mirror of https://github.com/ARMmbed/mbed-os.git
Merge commit '6dd01c679db4deb0a4a2c55832f3abe7b19bc51b' into mbedos511
* commit '6dd01c679db4deb0a4a2c55832f3abe7b19bc51b': Squashed 'features/nanostack/sal-stack-nanostack/' changes from 2535a6c..ccd30a3pull/8647/head
commit
ef39a19ba9
|
@ -69,7 +69,8 @@
|
||||||
typedef enum dhcp_instance_type
|
typedef enum dhcp_instance_type
|
||||||
{
|
{
|
||||||
DHCP_INSTANCE_CLIENT,
|
DHCP_INSTANCE_CLIENT,
|
||||||
DHCP_INSTANCE_SERVER
|
DHCP_INSTANCE_SERVER,
|
||||||
|
DHCP_INTANCE_RELAY_AGENT
|
||||||
} dhcp_instance_type_e;
|
} dhcp_instance_type_e;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -124,6 +125,16 @@ typedef int (dhcp_service_receive_resp_cb)(uint16_t instance_id, void *ptr, uint
|
||||||
|
|
||||||
uint16_t dhcp_service_init(int8_t interface_id, dhcp_instance_type_e instance_type, dhcp_service_receive_req_cb *receive_req_cb);
|
uint16_t dhcp_service_init(int8_t interface_id, dhcp_instance_type_e instance_type, dhcp_service_receive_req_cb *receive_req_cb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Enable DHCPv6 Relay Agent to server.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \param instance The instance ID of the registered server.
|
||||||
|
* \param server_address global server IPv6 address
|
||||||
|
*/
|
||||||
|
void dhcp_service_relay_instance_enable(uint16_t instance, uint8_t *server_address);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Deletes a server instance.
|
* \brief Deletes a server instance.
|
||||||
*
|
*
|
||||||
|
|
|
@ -132,8 +132,9 @@ typedef bool fhss_data_tx_fail(const fhss_api_t *api, uint8_t handle, int frame_
|
||||||
* @param api FHSS instance.
|
* @param api FHSS instance.
|
||||||
* @param fhss_state FHSS state (FHSS states are defined by FHSS api).
|
* @param fhss_state FHSS state (FHSS states are defined by FHSS api).
|
||||||
* @param pan_id PAN id of the network FHSS synchronizes with.
|
* @param pan_id PAN id of the network FHSS synchronizes with.
|
||||||
|
* @return -1 when failed, otherwise current MAC channel.
|
||||||
*/
|
*/
|
||||||
typedef void fhss_synch_state_set(const fhss_api_t *api, fhss_states fhss_state, uint16_t pan_id);
|
typedef int16_t fhss_synch_state_set(const fhss_api_t *api, fhss_states fhss_state, uint16_t pan_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read timestamp.
|
* @brief Read timestamp.
|
||||||
|
@ -215,6 +216,13 @@ typedef int mac_read_mac_address(const fhss_api_t *fhss_api, uint8_t *mac_addres
|
||||||
*/
|
*/
|
||||||
typedef uint32_t mac_read_datarate(const fhss_api_t *fhss_api);
|
typedef uint32_t mac_read_datarate(const fhss_api_t *fhss_api);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read 32-bit timestamp.
|
||||||
|
* @param fhss_api FHSS instance.
|
||||||
|
* @return Timestamp.
|
||||||
|
*/
|
||||||
|
typedef uint32_t mac_read_timestamp(const fhss_api_t *fhss_api);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Change channel.
|
* @brief Change channel.
|
||||||
* @param fhss_api FHSS instance.
|
* @param fhss_api FHSS instance.
|
||||||
|
@ -287,6 +295,7 @@ struct fhss_callback {
|
||||||
mac_read_tx_queue_size *read_tx_queue_size; /**< Read MAC TX queue size. */
|
mac_read_tx_queue_size *read_tx_queue_size; /**< Read MAC TX queue size. */
|
||||||
mac_read_mac_address *read_mac_address; /**< Read MAC address. */
|
mac_read_mac_address *read_mac_address; /**< Read MAC address. */
|
||||||
mac_read_datarate *read_datarate; /**< Read PHY datarate. */
|
mac_read_datarate *read_datarate; /**< Read PHY datarate. */
|
||||||
|
mac_read_timestamp *read_timestamp; /**< Read timestamp. */
|
||||||
mac_change_channel *change_channel; /**< Change channel. */
|
mac_change_channel *change_channel; /**< Change channel. */
|
||||||
mac_send_fhss_frame *send_fhss_frame; /**< Send FHSS frame. */
|
mac_send_fhss_frame *send_fhss_frame; /**< Send FHSS frame. */
|
||||||
mac_synch_lost_notification *synch_lost_notification; /**< Send notification when FHSS synchronization is lost. */
|
mac_synch_lost_notification *synch_lost_notification; /**< Send notification when FHSS synchronization is lost. */
|
||||||
|
|
|
@ -96,8 +96,11 @@ typedef int32_t fhss_vendor_defined_cf(const fhss_api_t *api, uint16_t slot, uin
|
||||||
*/
|
*/
|
||||||
typedef struct fhss_ws_configuration
|
typedef struct fhss_ws_configuration
|
||||||
{
|
{
|
||||||
/** WS channel function. */
|
/** WS unicast channel function. */
|
||||||
fhss_ws_channel_functions ws_channel_function;
|
fhss_ws_channel_functions ws_uc_channel_function;
|
||||||
|
|
||||||
|
/** WS broadcast channel function. */
|
||||||
|
fhss_ws_channel_functions ws_bc_channel_function;
|
||||||
|
|
||||||
/** Broadcast schedule identifier. */
|
/** Broadcast schedule identifier. */
|
||||||
uint16_t bsi;
|
uint16_t bsi;
|
||||||
|
@ -111,6 +114,12 @@ typedef struct fhss_ws_configuration
|
||||||
/** Broadcast dwell interval. Range: 15-250 milliseconds. */
|
/** Broadcast dwell interval. Range: 15-250 milliseconds. */
|
||||||
uint8_t fhss_bc_dwell_interval;
|
uint8_t fhss_bc_dwell_interval;
|
||||||
|
|
||||||
|
/** Unicast fixed channel */
|
||||||
|
uint8_t unicast_fixed_channel;
|
||||||
|
|
||||||
|
/** Broadcast fixed channel */
|
||||||
|
uint8_t broadcast_fixed_channel;
|
||||||
|
|
||||||
/** Channel mask. */
|
/** Channel mask. */
|
||||||
uint32_t channel_mask[8];
|
uint32_t channel_mask[8];
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ typedef struct unicast_timing_info {
|
||||||
unsigned unicast_channel_function:3; /**< Unicast schedule channel function */
|
unsigned unicast_channel_function:3; /**< Unicast schedule channel function */
|
||||||
uint8_t unicast_dwell_interval; /**< Unicast dwell interval */
|
uint8_t unicast_dwell_interval; /**< Unicast dwell interval */
|
||||||
uint16_t unicast_number_of_channels; /**< Unicast number of channels */
|
uint16_t unicast_number_of_channels; /**< Unicast number of channels */
|
||||||
|
uint16_t fixed_channel; /**< Unicast fixed channel*/
|
||||||
uint_fast24_t ufsi; /**< Unicast fractional sequence interval */
|
uint_fast24_t ufsi; /**< Unicast fractional sequence interval */
|
||||||
uint32_t utt_rx_timestamp; /**< UTT-IE reception timestamp */
|
uint32_t utt_rx_timestamp; /**< UTT-IE reception timestamp */
|
||||||
} unicast_timing_info_t;
|
} unicast_timing_info_t;
|
||||||
|
@ -47,6 +48,7 @@ typedef struct unicast_timing_info {
|
||||||
typedef struct broadcast_timing_info {
|
typedef struct broadcast_timing_info {
|
||||||
unsigned broadcast_channel_function:3; /**< Broadcast schedule channel function */
|
unsigned broadcast_channel_function:3; /**< Broadcast schedule channel function */
|
||||||
uint8_t broadcast_dwell_interval; /**< Broadcast dwell interval */
|
uint8_t broadcast_dwell_interval; /**< Broadcast dwell interval */
|
||||||
|
uint16_t fixed_channel; /**< Broadcast fixed channel*/
|
||||||
uint16_t broadcast_slot; /**< Broadcast slot number */
|
uint16_t broadcast_slot; /**< Broadcast slot number */
|
||||||
uint16_t broadcast_schedule_id; /**< Broadcast schedule identifier */
|
uint16_t broadcast_schedule_id; /**< Broadcast schedule identifier */
|
||||||
uint_fast24_t broadcast_interval_offset; /**< Broadcast interval offset */
|
uint_fast24_t broadcast_interval_offset; /**< Broadcast interval offset */
|
||||||
|
@ -78,9 +80,10 @@ typedef fhss_ws_neighbor_timing_info_t *fhss_get_neighbor_info(const fhss_api_t
|
||||||
* @param fhss_api FHSS instance.
|
* @param fhss_api FHSS instance.
|
||||||
* @param eui64 EUI-64 address of parent.
|
* @param eui64 EUI-64 address of parent.
|
||||||
* @param bc_timing_info Pointer to parent broadcast timing/hopping schedule info.
|
* @param bc_timing_info Pointer to parent broadcast timing/hopping schedule info.
|
||||||
|
* @param force_synch If false, synchronization is done only if minimum (internal) synchronization interval is exceed.
|
||||||
* @return 0 on success, -1 on fail.
|
* @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);
|
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, const bool force_synch);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Remove parent which was set by ns_fhss_ws_set_parent function.
|
* @brief Remove parent which was set by ns_fhss_ws_set_parent function.
|
||||||
|
|
|
@ -137,8 +137,9 @@ typedef void mcps_data_request_ext(const mac_api_t* api, const mcps_data_req_t *
|
||||||
* @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
|
||||||
* @param data MCPS-PURGE.request specific values
|
* @param data MCPS-PURGE.request specific values
|
||||||
|
* @return 0 in case of success, non-zero otherwise
|
||||||
*/
|
*/
|
||||||
typedef void mcps_purge_request(const mac_api_t* api, const mcps_purge_t *data);
|
typedef uint8_t mcps_purge_request(const mac_api_t* api, const mcps_purge_t *data);
|
||||||
|
|
||||||
//Upper layer specific callback functions (will also be set by Upper layer after mac_api_t has been created and given to it)
|
//Upper layer specific callback functions (will also be set by Upper layer after mac_api_t has been created and given to it)
|
||||||
|
|
||||||
|
|
|
@ -39,10 +39,9 @@ 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.
|
* @brief Creates FHSS WS API instance which will be registered to software MAC.
|
||||||
* @param fhss_configuration Basic FHSS configuration.
|
* @param fhss_configuration Basic FHSS configuration.
|
||||||
* @param fhss_timer FHSS platform timer interface and configuration.
|
* @param fhss_timer FHSS platform timer interface and configuration.
|
||||||
* @param fhss_statistics FHSS statistics storage.
|
|
||||||
* @return New FHSS instance if successful, NULL otherwise.
|
* @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);
|
extern fhss_api_t *ns_fhss_ws_create(const fhss_ws_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer);
|
||||||
|
|
|
@ -75,6 +75,7 @@ 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.
|
* Set prefix to be used as combining multiple thread networks on backbone.
|
||||||
*
|
*
|
||||||
|
@ -89,6 +90,20 @@ int thread_bbr_timeout_set(int8_t interface_id, uint32_t timeout_a, uint32_t tim
|
||||||
*/
|
*/
|
||||||
int thread_bbr_prefix_set(int8_t interface_id, uint8_t *prefix);
|
int thread_bbr_prefix_set(int8_t interface_id, uint8_t *prefix);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set sequence number to be used by bbr
|
||||||
|
*
|
||||||
|
* update sequence number value
|
||||||
|
*
|
||||||
|
* \param interface_id interface ID of the Thread network.
|
||||||
|
* \param sequence_number value that needs to be set on bbr
|
||||||
|
*
|
||||||
|
* \return 0 on success
|
||||||
|
* \return <0 in case of errors
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int thread_bbr_sequence_number_set(int8_t interface_id, uint8_t sequence_number);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the Thread validation interface destination address.
|
* Set the Thread validation interface destination address.
|
||||||
*
|
*
|
||||||
|
|
|
@ -189,8 +189,10 @@ void *thread_commission_device_get_next(void *ptr, int8_t interface_id, bool *sh
|
||||||
|
|
||||||
typedef struct thread_commissioning_link_configuration {
|
typedef struct thread_commissioning_link_configuration {
|
||||||
uint8_t name[16]; /**< Name of the Thread network. utf8 string nul terminated if shorter than 16. */
|
uint8_t name[16]; /**< Name of the Thread network. utf8 string nul terminated if shorter than 16. */
|
||||||
|
uint8_t destination_address[16]; /**<Border router destination address*/
|
||||||
uint8_t extented_pan_id[8]; /**< Extended PAN ID. */
|
uint8_t extented_pan_id[8]; /**< Extended PAN ID. */
|
||||||
uint16_t panId; /**< Network ID. */
|
uint16_t panId; /**< Network ID. */
|
||||||
|
uint16_t destination_port; /**<destination port for commissioning*/
|
||||||
uint8_t Protocol_id; /**< Current protocol ID. */
|
uint8_t Protocol_id; /**< Current protocol ID. */
|
||||||
uint8_t version; /**< Current protocol version. */
|
uint8_t version; /**< Current protocol version. */
|
||||||
uint8_t rfChannel; /**< Current RF channel. */
|
uint8_t rfChannel; /**< Current RF channel. */
|
||||||
|
@ -271,6 +273,18 @@ int thread_commissioning_native_commissioner_get_connection_info(int8_t interfac
|
||||||
*/
|
*/
|
||||||
int8_t thread_commissioning_get_management_id(int8_t interface_id);
|
int8_t thread_commissioning_get_management_id(int8_t interface_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Attach native commissioner to destination address and port.
|
||||||
|
*
|
||||||
|
* \param interface_id Network interface ID.
|
||||||
|
* \param destination_address Destination address pointer.
|
||||||
|
* \param destination_port Commissioning port.
|
||||||
|
*
|
||||||
|
* \return 0 attach OK.
|
||||||
|
* \return < 0 fail.
|
||||||
|
*/
|
||||||
|
int thread_commissioning_attach(int8_t interface_id, uint8_t *destination_address, uint16_t destination_port);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -55,7 +55,8 @@
|
||||||
#define DIAGCOP_TLV_SUPPLY_VOLTAGE 15 /**< Can not reset*/
|
#define DIAGCOP_TLV_SUPPLY_VOLTAGE 15 /**< Can not reset*/
|
||||||
#define DIAGCOP_TLV_CHILD_TABLE 16 /**< Can not reset*/
|
#define DIAGCOP_TLV_CHILD_TABLE 16 /**< Can not reset*/
|
||||||
#define DIAGCOP_TLV_CHANNEL_PAGES 17 /**< Can not reset*/
|
#define DIAGCOP_TLV_CHANNEL_PAGES 17 /**< Can not reset*/
|
||||||
#define DIAGCOP_TLV_TYPE_LIST 18 /**< List type*/
|
#define DIAGCOP_TLV_TYPE_LIST 18 /**< Cannot reset*/
|
||||||
|
#define DIAGCOP_TLV_MAX_CHILD_TIMEOUT 19 /**< Cannot reset*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Write array TLV.
|
* \brief Write array TLV.
|
||||||
|
|
|
@ -74,6 +74,7 @@
|
||||||
#include "6LoWPAN/Fragmentation/cipv6_fragmenter.h"
|
#include "6LoWPAN/Fragmentation/cipv6_fragmenter.h"
|
||||||
#include "Service_Libs/etx/etx.h"
|
#include "Service_Libs/etx/etx.h"
|
||||||
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
|
#include "6LoWPAN/ws/ws_bootstrap.h"
|
||||||
|
|
||||||
|
|
||||||
#define TRACE_GROUP_LOWPAN "6lo"
|
#define TRACE_GROUP_LOWPAN "6lo"
|
||||||
|
@ -473,7 +474,6 @@ void protocol_6lowpan_neighbor_priority_update(protocol_interface_info_entry_t *
|
||||||
}
|
}
|
||||||
|
|
||||||
#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)
|
||||||
{
|
{
|
||||||
|
@ -486,9 +486,12 @@ uint16_t protocol_6lowpan_neighbor_priority_set(int8_t interface_id, addrtype_t
|
||||||
mac_neighbor_table_entry_t * entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), 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 (entry) {
|
if (entry) {
|
||||||
|
|
||||||
|
bool new_primary = false;
|
||||||
etx_storage_t *etx_entry = etx_storage_entry_get(interface_id, entry->index);
|
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 (entry->link_role != PRIORITY_PARENT_NEIGHBOUR) {
|
if (entry->link_role != PRIORITY_PARENT_NEIGHBOUR) {
|
||||||
|
new_primary = true;
|
||||||
protocol_6lowpan_neighbor_priority_clear_all(interface_id, PRIORITY_1ST);
|
protocol_6lowpan_neighbor_priority_clear_all(interface_id, PRIORITY_1ST);
|
||||||
}
|
}
|
||||||
entry->link_role = PRIORITY_PARENT_NEIGHBOUR;
|
entry->link_role = PRIORITY_PARENT_NEIGHBOUR;
|
||||||
|
@ -501,6 +504,10 @@ uint16_t protocol_6lowpan_neighbor_priority_set(int8_t interface_id, addrtype_t
|
||||||
if (etx_entry) {
|
if (etx_entry) {
|
||||||
protocol_stats_update(STATS_ETX_1ST_PARENT, etx_entry->etx >> 4);
|
protocol_stats_update(STATS_ETX_1ST_PARENT, etx_entry->etx >> 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (new_primary) {
|
||||||
|
ws_primary_parent_update(cur, entry);
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -519,9 +526,11 @@ uint16_t protocol_6lowpan_neighbor_second_priority_set(int8_t interface_id, addr
|
||||||
mac_neighbor_table_entry_t * entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), 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 (entry) {
|
if (entry) {
|
||||||
|
bool new_secondary = false;
|
||||||
etx_storage_t *etx_entry = etx_storage_entry_get(interface_id, entry->index);
|
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 (entry->link_role != SECONDARY_PARENT_NEIGHBOUR) {
|
if (entry->link_role != SECONDARY_PARENT_NEIGHBOUR) {
|
||||||
|
new_secondary = true;
|
||||||
protocol_6lowpan_neighbor_priority_clear_all(interface_id, PRIORITY_2ND);
|
protocol_6lowpan_neighbor_priority_clear_all(interface_id, PRIORITY_2ND);
|
||||||
}
|
}
|
||||||
entry->link_role = SECONDARY_PARENT_NEIGHBOUR;
|
entry->link_role = SECONDARY_PARENT_NEIGHBOUR;
|
||||||
|
@ -529,6 +538,9 @@ uint16_t protocol_6lowpan_neighbor_second_priority_set(int8_t interface_id, addr
|
||||||
if (etx_entry) {
|
if (etx_entry) {
|
||||||
protocol_stats_update(STATS_ETX_2ND_PARENT, etx_entry->etx >> 4);
|
protocol_stats_update(STATS_ETX_2ND_PARENT, etx_entry->etx >> 4);
|
||||||
}
|
}
|
||||||
|
if (new_secondary) {
|
||||||
|
ws_secondary_parent_update(cur);
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -557,7 +569,6 @@ void protocol_6lowpan_neighbor_priority_clear_all(int8_t interface_id, neighbor_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1786,7 +1786,7 @@ int8_t arm_6lowpan_bootstarp_bootstrap_set(int8_t interface_id, net_6lowpan_mode
|
||||||
*/
|
*/
|
||||||
if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) {
|
if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) {
|
||||||
//rpl_control_set_domain_on_interface(cur, protocol_6lowpan_rpl_domain, true);
|
//rpl_control_set_domain_on_interface(cur, protocol_6lowpan_rpl_domain, true);
|
||||||
//rpl_control_set_callback(protocol_6lowpan_rpl_domain, protocol_6lowpan_bootstrap_rpl_callback, cur);
|
//rpl_control_set_callback(protocol_6lowpan_rpl_domain, protocol_6lowpan_bootstrap_rpl_callback, NULL, cur);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
cur->configure_flags |= INTERFACE_BOOTSTRAP_DEFINED;
|
cur->configure_flags |= INTERFACE_BOOTSTRAP_DEFINED;
|
||||||
|
@ -2073,6 +2073,8 @@ static void protocol_6lowpan_bootstrap_rpl_callback(rpl_event_t event, void *han
|
||||||
tr_error("RPL Local repair fail-->interface to idle");
|
tr_error("RPL Local repair fail-->interface to idle");
|
||||||
nwk_bootsrap_state_update(ARM_NWK_NWK_CONNECTION_DOWN, cur);
|
nwk_bootsrap_state_update(ARM_NWK_NWK_CONNECTION_DOWN, cur);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2179,7 +2181,7 @@ void nwk_6lowpan_nd_address_registartion_ready(protocol_interface_info_entry_t *
|
||||||
// arm_nwk_6lowpan_rpl_dodag_poison from a previous connection may have left force_leaf set
|
// arm_nwk_6lowpan_rpl_dodag_poison from a previous connection may have left force_leaf set
|
||||||
rpl_control_force_leaf(protocol_6lowpan_rpl_domain, false);
|
rpl_control_force_leaf(protocol_6lowpan_rpl_domain, false);
|
||||||
rpl_control_set_domain_on_interface(cur, protocol_6lowpan_rpl_domain, true);
|
rpl_control_set_domain_on_interface(cur, protocol_6lowpan_rpl_domain, true);
|
||||||
rpl_control_set_callback(protocol_6lowpan_rpl_domain, protocol_6lowpan_bootstrap_rpl_callback, cur);
|
rpl_control_set_callback(protocol_6lowpan_rpl_domain, protocol_6lowpan_bootstrap_rpl_callback, NULL, cur);
|
||||||
}
|
}
|
||||||
// Send unicast DIS to coordinator
|
// Send unicast DIS to coordinator
|
||||||
nwk_bootstrap_icmp_rpl_dis_coord_msg_tx(cur);
|
nwk_bootstrap_icmp_rpl_dis_coord_msg_tx(cur);
|
||||||
|
|
|
@ -39,9 +39,10 @@ typedef void mpx_data_request(const mpx_api_t *api, const struct mcps_data_req_s
|
||||||
* @param api API to handle the request
|
* @param api API to handle the request
|
||||||
* @param purge MCPS-purge request
|
* @param purge MCPS-purge request
|
||||||
* @param user_id MPX user ID
|
* @param user_id MPX user ID
|
||||||
|
* @return 0 if purge requst was OK, non-zero otherwise
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef void mpx_data_purge_request(const mpx_api_t *api, struct mcps_purge_s *purge, uint16_t user_id);
|
typedef uint8_t 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
|
* @brief mpx_data_confirm MPX-DATA confirm is called as a response to MPX-DATA request
|
||||||
|
|
|
@ -40,12 +40,16 @@
|
||||||
#include "common_functions.h"
|
#include "common_functions.h"
|
||||||
#include "thread_border_router_api.h"
|
#include "thread_border_router_api.h"
|
||||||
#include "thread_bbr_api.h"
|
#include "thread_bbr_api.h"
|
||||||
|
#include "net_ipv6_api.h"
|
||||||
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
#include "Common_Protocols/ipv6_constants.h"
|
#include "Common_Protocols/ipv6_constants.h"
|
||||||
#include "DHCPv6_Server/DHCPv6_server_service.h"
|
#include "DHCPv6_Server/DHCPv6_server_service.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_dhcpv6_server.h"
|
||||||
#include "thread_management_if.h"
|
#include "thread_management_if.h"
|
||||||
#include "6LoWPAN/Thread/thread_config.h"
|
#include "6LoWPAN/Thread/thread_config.h"
|
||||||
#include "6LoWPAN/Thread/thread_constants.h"
|
#include "6LoWPAN/Thread/thread_constants.h"
|
||||||
#include "6LoWPAN/Thread/thread_common.h"
|
#include "6LoWPAN/Thread/thread_common.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_bootstrap.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"
|
||||||
#include "6LoWPAN/Thread/thread_extension_bbr.h"
|
#include "6LoWPAN/Thread/thread_extension_bbr.h"
|
||||||
|
@ -96,7 +100,6 @@ typedef struct {
|
||||||
#define RFC6106_DNS_SEARCH_LIST_OPTION 31
|
#define RFC6106_DNS_SEARCH_LIST_OPTION 31
|
||||||
static NS_LIST_DEFINE(bbr_instance_list, thread_bbr_t, link);
|
static NS_LIST_DEFINE(bbr_instance_list, thread_bbr_t, link);
|
||||||
|
|
||||||
|
|
||||||
static thread_bbr_t *thread_bbr_find_by_interface(int8_t interface_id)
|
static thread_bbr_t *thread_bbr_find_by_interface(int8_t interface_id)
|
||||||
{
|
{
|
||||||
thread_bbr_t *this = NULL;
|
thread_bbr_t *this = NULL;
|
||||||
|
@ -579,7 +582,7 @@ static void thread_bbr_network_data_send(thread_bbr_t *this, uint8_t prefix[8],
|
||||||
// delete old prefix
|
// delete old prefix
|
||||||
memset(this->bbr_prefix,0,8);
|
memset(this->bbr_prefix,0,8);
|
||||||
// create new prefix
|
// create new prefix
|
||||||
if (DHCPv6_server_service_init(this->interface_id, prefix, eui64, DHCPV6_DUID_HARDWARE_EUI64_TYPE) != 0) {
|
if (thread_dhcp6_server_init(this->interface_id, prefix, eui64, THREAD_MIN_PREFIX_LIFETIME) != 0) {
|
||||||
tr_warn("DHCP server alloc fail");
|
tr_warn("DHCP server alloc fail");
|
||||||
// set 20 seconds delay before next process
|
// set 20 seconds delay before next process
|
||||||
this->br_delay_timer = 20;
|
this->br_delay_timer = 20;
|
||||||
|
@ -587,8 +590,6 @@ static void thread_bbr_network_data_send(thread_bbr_t *this, uint8_t prefix[8],
|
||||||
}
|
}
|
||||||
memcpy(this->bbr_prefix,prefix,8);
|
memcpy(this->bbr_prefix,prefix,8);
|
||||||
|
|
||||||
DHCPv6_server_service_set_address_validlifetime(this->interface_id, this->bbr_prefix, THREAD_MIN_PREFIX_LIFETIME);
|
|
||||||
|
|
||||||
br_info.P_default_route = true;
|
br_info.P_default_route = true;
|
||||||
br_info.P_dhcp = true;
|
br_info.P_dhcp = true;
|
||||||
br_info.P_on_mesh = true;
|
br_info.P_on_mesh = true;
|
||||||
|
@ -724,7 +725,7 @@ static bool thread_bbr_activated(thread_bbr_t *this, uint32_t seconds)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur->thread_info->routerIdReqCoapID) {
|
if (cur->thread_info->routerIdRequested) {
|
||||||
// Router id reguest pending we need to wait for response
|
// Router id reguest pending we need to wait for response
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -978,25 +979,31 @@ int thread_bbr_nd_entry_add (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)
|
int thread_bbr_dua_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, const uint8_t *mleid_ptr)
|
||||||
{
|
{
|
||||||
thread_bbr_t *this = thread_bbr_find_by_interface(interface_id);
|
thread_bbr_t *this = thread_bbr_find_by_interface(interface_id);
|
||||||
|
thread_pbbr_dua_info_t *map;
|
||||||
if (!this || this->backbone_interface_id < 0) {
|
if (!this || this->backbone_interface_id < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
thread_pbbr_dua_info_t *map = ns_dyn_mem_alloc(sizeof(thread_pbbr_dua_info_t));
|
ipv6_route_t *route = ipv6_route_lookup_with_info(addr_data_ptr, 128, interface_id, NULL, ROUTE_THREAD_PROXIED_DUA_HOST, NULL, 0);
|
||||||
if (!map) {
|
if (!route){
|
||||||
goto error;
|
map = ns_dyn_mem_alloc(sizeof(thread_pbbr_dua_info_t));
|
||||||
|
if (!map) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
// We are using route info field to store BBR MLEID map
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
map = route->info.info;
|
||||||
memcpy(map->mleid_ptr, mleid_ptr, 8);
|
memcpy(map->mleid_ptr, mleid_ptr, 8);
|
||||||
map->last_contact_time = protocol_core_monotonic_time;
|
map->last_contact_time = protocol_core_monotonic_time;
|
||||||
|
route->info.info = map;
|
||||||
|
|
||||||
// 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
|
// send NA
|
||||||
thread_bbr_na_send(this->backbone_interface_id, addr_data_ptr);
|
thread_bbr_na_send(this->backbone_interface_id, addr_data_ptr);
|
||||||
|
|
||||||
|
@ -1006,15 +1013,6 @@ error:
|
||||||
return -2;
|
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)
|
||||||
{
|
{
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(handler_interface_id);
|
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(handler_interface_id);
|
||||||
|
@ -1099,7 +1097,11 @@ int thread_bbr_start(int8_t interface_id, int8_t backbone_interface_id)
|
||||||
// By default multicast forwarding is not enabled as it causes multicast loops
|
// By default multicast forwarding is not enabled as it causes multicast loops
|
||||||
multicast_fwd_set_forwarding(this->interface_id, false);
|
multicast_fwd_set_forwarding(this->interface_id, false);
|
||||||
|
|
||||||
|
// Adjust BBR neighbor and destination cache size
|
||||||
|
arm_nwk_ipv6_max_cache_entries(THREAD_BBR_IPV6_DESTINATION_CACHE_SIZE);
|
||||||
|
|
||||||
thread_extension_bbr_init(interface_id,backbone_interface_id);
|
thread_extension_bbr_init(interface_id,backbone_interface_id);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1131,6 +1133,17 @@ int thread_bbr_prefix_set(int8_t interface_id, uint8_t *prefix)
|
||||||
#endif // HAVE_THREAD_BORDER_ROUTER
|
#endif // HAVE_THREAD_BORDER_ROUTER
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int thread_bbr_sequence_number_set(int8_t interface_id, uint8_t sequence_number)
|
||||||
|
{
|
||||||
|
(void) interface_id;
|
||||||
|
(void) sequence_number;
|
||||||
|
#ifdef HAVE_THREAD_BORDER_ROUTER
|
||||||
|
return thread_extension_bbr_sequence_number_set(interface_id, sequence_number);
|
||||||
|
#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;
|
||||||
|
|
|
@ -67,7 +67,6 @@ void thread_bbr_seconds_timer(int8_t interface_id, uint32_t tics);
|
||||||
*/
|
*/
|
||||||
int thread_bbr_commissioner_proxy_service_update(int8_t interface_id);
|
int thread_bbr_commissioner_proxy_service_update(int8_t interface_id);
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define thread_bbr_init(interface_id, external_commisssioner_port)
|
#define thread_bbr_init(interface_id, external_commisssioner_port)
|
||||||
#define thread_bbr_delete(interface_id)
|
#define thread_bbr_delete(interface_id)
|
||||||
|
@ -118,12 +117,6 @@ int thread_bbr_dua_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr,
|
||||||
*/
|
*/
|
||||||
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]);
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Find if bbr has dua entry
|
|
||||||
*
|
|
||||||
* \param interface_id 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)
|
||||||
|
@ -131,7 +124,6 @@ struct ipv6_route *thread_bbr_dua_entry_find(int8_t interface_id, const uint8_t
|
||||||
#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) (0)
|
#define thread_bbr_nd_entry_add(interface_id, addr_data_ptr, lifetime, info) (0)
|
||||||
#define thread_bbr_dua_entry_add(interface_id, addr_data_ptr, lifetime, mleid_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)
|
#define thread_bbr_na_send(interface_id, target) (0)
|
||||||
#endif //HAVE_THREAD_BORDER_ROUTER
|
#endif //HAVE_THREAD_BORDER_ROUTER
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@
|
||||||
#include "MPL/mpl.h"
|
#include "MPL/mpl.h"
|
||||||
#include "MLE/mle.h"
|
#include "MLE/mle.h"
|
||||||
#include "MLE/mle_tlv.h"
|
#include "MLE/mle_tlv.h"
|
||||||
#include "thread_dhcpv6_client.h"
|
#include "DHCPv6_client/dhcpv6_client_api.h"
|
||||||
#include "thread_config.h"
|
#include "thread_config.h"
|
||||||
#include "thread_meshcop_lib.h"
|
#include "thread_meshcop_lib.h"
|
||||||
#include "multicast_api.h"
|
#include "multicast_api.h"
|
||||||
|
@ -136,8 +136,6 @@ static void thread_neighbor_remove(mac_neighbor_table_entry_t *entry_ptr, void *
|
||||||
|
|
||||||
static bool thread_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data)
|
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;
|
protocol_interface_info_entry_t *cur_interface = user_data;
|
||||||
|
|
||||||
if (thread_am_router(cur_interface)) {
|
if (thread_am_router(cur_interface)) {
|
||||||
|
@ -676,8 +674,6 @@ static void thread_bootstrap_ml_address_update(protocol_interface_info_entry_t *
|
||||||
|
|
||||||
// Generate new ML64 address
|
// Generate new ML64 address
|
||||||
thread_generate_ml64_address(cur);
|
thread_generate_ml64_address(cur);
|
||||||
// Generate new domain address
|
|
||||||
thread_extension_address_generate(cur);
|
|
||||||
|
|
||||||
// Register multicast addresses
|
// Register multicast addresses
|
||||||
thread_bootstrap_all_nodes_multicast_register(cur);
|
thread_bootstrap_all_nodes_multicast_register(cur);
|
||||||
|
@ -698,8 +694,6 @@ int thread_configuration_thread_activate(protocol_interface_info_entry_t *cur, l
|
||||||
//Define Default Contexts
|
//Define Default Contexts
|
||||||
lowpan_context_update(&cur->lowpan_contexts, LOWPAN_CONTEXT_C, 0xFFFF, linkConfiguration->mesh_local_ula_prefix, 64, true);
|
lowpan_context_update(&cur->lowpan_contexts, LOWPAN_CONTEXT_C, 0xFFFF, linkConfiguration->mesh_local_ula_prefix, 64, true);
|
||||||
|
|
||||||
thread_extension_activate(cur);
|
|
||||||
|
|
||||||
thread_extension_bbr_route_update(cur);
|
thread_extension_bbr_route_update(cur);
|
||||||
|
|
||||||
blacklist_clear();
|
blacklist_clear();
|
||||||
|
@ -896,7 +890,7 @@ void thread_interface_init(protocol_interface_info_entry_t *cur)
|
||||||
{
|
{
|
||||||
thread_discovery_reset(cur->id);
|
thread_discovery_reset(cur->id);
|
||||||
thread_routing_set_mesh_callbacks(cur);
|
thread_routing_set_mesh_callbacks(cur);
|
||||||
thread_dhcp_client_init(cur->id);
|
dhcp_client_init(cur->id);
|
||||||
thread_management_client_init(cur->id);
|
thread_management_client_init(cur->id);
|
||||||
thread_address_registration_init();
|
thread_address_registration_init();
|
||||||
cur->mpl_seed_id_mode = MULTICAST_MPL_SEED_ID_MAC_SHORT;
|
cur->mpl_seed_id_mode = MULTICAST_MPL_SEED_ID_MAC_SHORT;
|
||||||
|
@ -1069,9 +1063,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) {
|
thread_host_bootstrap_child_update(cur, 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: {
|
||||||
tr_debug_extra("Thread SM THREAD_ANNOUNCE_ACTIVE");
|
tr_debug_extra("Thread SM THREAD_ANNOUNCE_ACTIVE");
|
||||||
|
@ -1178,6 +1170,10 @@ void thread_bootstrap_ready(protocol_interface_info_entry_t *cur)
|
||||||
thread_leader_service_generate_network_data(cur);
|
thread_leader_service_generate_network_data(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (thread_addresses_needs_to_be_registered(cur)) {
|
||||||
|
thread_info(cur)->childUpdateReqTimer = 1;
|
||||||
|
}
|
||||||
|
|
||||||
cur->bootsrap_state_machine_cnt = 0;
|
cur->bootsrap_state_machine_cnt = 0;
|
||||||
mac_data_poll_protocol_poll_mode_decrement(cur);
|
mac_data_poll_protocol_poll_mode_decrement(cur);
|
||||||
}
|
}
|
||||||
|
@ -1194,6 +1190,31 @@ void thread_neighbor_list_clean(struct protocol_interface_info_entry *cur)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void thread_reed_fed_neighbour_links_clean(struct protocol_interface_info_entry *cur)
|
||||||
|
{
|
||||||
|
mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
|
||||||
|
|
||||||
|
if (thread_i_am_router(cur)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thread_info(cur)->thread_device_mode == THREAD_DEVICE_MODE_END_DEVICE ||
|
||||||
|
thread_info(cur)->thread_device_mode == THREAD_DEVICE_MODE_SLEEPY_END_DEVICE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!thread_info(cur)->thread_endnode_parent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ns_list_foreach_safe(mac_neighbor_table_entry_t, cur_entry, mac_table_list) {
|
||||||
|
// do not remove parent entry
|
||||||
|
if (memcmp(cur_entry->mac64, thread_info(cur)->thread_endnode_parent->mac64, 8) != 0) {
|
||||||
|
tr_debug("Free short addr: %x", cur_entry->mac16);
|
||||||
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), cur_entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void thread_clean_old_16_bit_address_based_addresses(protocol_interface_info_entry_t *cur)
|
void thread_clean_old_16_bit_address_based_addresses(protocol_interface_info_entry_t *cur)
|
||||||
{
|
{
|
||||||
uint8_t static_address[16];
|
uint8_t static_address[16];
|
||||||
|
@ -1612,7 +1633,6 @@ void thread_bootstrap_routing_activate(protocol_interface_info_entry_t *cur)
|
||||||
if (cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_FULL_END_DEVICE ||
|
if (cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_FULL_END_DEVICE ||
|
||||||
cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_ROUTER) {
|
cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_ROUTER) {
|
||||||
thread_meshlocal_route_set(cur);
|
thread_meshlocal_route_set(cur);
|
||||||
thread_extension_route_set(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 {
|
||||||
|
@ -1627,7 +1647,7 @@ void thread_bootstrap_attached_finish(protocol_interface_info_entry_t *cur)
|
||||||
cur->lowpan_info |= INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY;
|
cur->lowpan_info |= INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY;
|
||||||
cur->lowpan_info &= ~INTERFACE_NWK_ROUTER_DEVICE;
|
cur->lowpan_info &= ~INTERFACE_NWK_ROUTER_DEVICE;
|
||||||
cur->bootsrap_state_machine_cnt = 10;
|
cur->bootsrap_state_machine_cnt = 10;
|
||||||
cur->thread_info->routerIdReqCoapID = 0;
|
cur->thread_info->routerIdRequested = false;
|
||||||
cur->thread_info->networkDataRequested = false;
|
cur->thread_info->networkDataRequested = false;
|
||||||
clear_power_state(ICMP_ACTIVE);
|
clear_power_state(ICMP_ACTIVE);
|
||||||
|
|
||||||
|
@ -1644,8 +1664,6 @@ void thread_bootstrap_attached_finish(protocol_interface_info_entry_t *cur)
|
||||||
thread_generate_ml16_address(cur);
|
thread_generate_ml16_address(cur);
|
||||||
//GENERATE ML-EID64
|
//GENERATE ML-EID64
|
||||||
thread_generate_ml64_address(cur);
|
thread_generate_ml64_address(cur);
|
||||||
// Generate new domain address
|
|
||||||
thread_extension_address_generate(cur);
|
|
||||||
thread_bootstrap_routing_activate(cur);
|
thread_bootstrap_routing_activate(cur);
|
||||||
thread_bootstrap_network_data_update(cur);
|
thread_bootstrap_network_data_update(cur);
|
||||||
// After successful attach if there is announcement info present, send announcement back to previous channel
|
// After successful attach if there is announcement info present, send announcement back to previous channel
|
||||||
|
@ -1823,8 +1841,7 @@ static void thread_dhcp_client_gua_error_cb(int8_t interface, uint8_t dhcp_addr[
|
||||||
tr_warn("Address Get fail: %s from: %s", trace_ipv6(prefix), trace_ipv6(dhcp_addr));
|
tr_warn("Address Get fail: %s from: %s", trace_ipv6(prefix), trace_ipv6(dhcp_addr));
|
||||||
if (prefix && dhcp_addr) {
|
if (prefix && dhcp_addr) {
|
||||||
tr_debug("Delete Current Server data");
|
tr_debug("Delete Current Server data");
|
||||||
thread_dhcp_client_global_address_delete(interface, dhcp_addr, prefix);
|
dhcp_client_global_address_delete(interface, dhcp_addr, prefix);
|
||||||
//TODO shuold we try again or select new Server
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1964,6 +1981,10 @@ void thread_discover_native_commissioner_response(protocol_interface_info_entry_
|
||||||
config_ptr[n].rfChannel = cur_class->channel;
|
config_ptr[n].rfChannel = cur_class->channel;
|
||||||
memcpy(config_ptr[n].name, cur_class->network_name, 16);
|
memcpy(config_ptr[n].name, cur_class->network_name, 16);
|
||||||
memcpy(config_ptr[n].extented_pan_id, cur_class->extented_pan_id, 8);
|
memcpy(config_ptr[n].extented_pan_id, cur_class->extented_pan_id, 8);
|
||||||
|
memcpy(config_ptr[n].destination_address, ADDR_LINK_LOCAL_PREFIX, 8);
|
||||||
|
memcpy(&config_ptr[n].destination_address[8], cur_class->extented_mac, 8);
|
||||||
|
config_ptr[n].destination_address[8] ^= 2;
|
||||||
|
config_ptr[n].destination_port = cur_class->commissioner_port;
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2023,7 +2044,7 @@ void thread_discover_native_commissioner_response(protocol_interface_info_entry_
|
||||||
interface->lowpan_info |= INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY;
|
interface->lowpan_info |= INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY;
|
||||||
interface->lowpan_info &= ~INTERFACE_NWK_ROUTER_DEVICE;
|
interface->lowpan_info &= ~INTERFACE_NWK_ROUTER_DEVICE;
|
||||||
|
|
||||||
interface->thread_info->routerIdReqCoapID = 0;
|
interface->thread_info->routerIdRequested = false;
|
||||||
interface->thread_info->networkDataRequested = false;
|
interface->thread_info->networkDataRequested = false;
|
||||||
|
|
||||||
interface->bootsrap_state_machine_cnt = 10;
|
interface->bootsrap_state_machine_cnt = 10;
|
||||||
|
@ -2128,6 +2149,12 @@ static bool thread_bootstrap_sync_after_reset_start(protocol_interface_info_entr
|
||||||
uint16_t my_short_address;
|
uint16_t my_short_address;
|
||||||
uint8_t parent_mac64[8];
|
uint8_t parent_mac64[8];
|
||||||
|
|
||||||
|
// link sync is allowed only once in bootstrap start and we might get here in other cases also
|
||||||
|
if (!cur->thread_info->link_sync_allowed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cur->thread_info->link_sync_allowed = false;
|
||||||
|
|
||||||
int link_info_err = thread_nvm_store_link_info_get(parent_mac64, &my_short_address);
|
int link_info_err = thread_nvm_store_link_info_get(parent_mac64, &my_short_address);
|
||||||
if ( link_info_err!= THREAD_NVM_FILE_SUCCESS) {
|
if ( link_info_err!= THREAD_NVM_FILE_SUCCESS) {
|
||||||
tr_warning("thread_nvm_store_link_info_get returned %d", link_info_err);
|
tr_warning("thread_nvm_store_link_info_get returned %d", link_info_err);
|
||||||
|
@ -2136,7 +2163,7 @@ static bool thread_bootstrap_sync_after_reset_start(protocol_interface_info_entr
|
||||||
link_info_err = thread_nvm_store_link_info_clear();
|
link_info_err = thread_nvm_store_link_info_clear();
|
||||||
if ( link_info_err!= THREAD_NVM_FILE_SUCCESS) {
|
if ( link_info_err!= THREAD_NVM_FILE_SUCCESS) {
|
||||||
tr_warning("thread_nvm_store_link_info_clear returned %d", link_info_err);
|
tr_warning("thread_nvm_store_link_info_clear returned %d", link_info_err);
|
||||||
}
|
}
|
||||||
if (thread_is_router_addr(my_short_address)) {
|
if (thread_is_router_addr(my_short_address)) {
|
||||||
thread_info(cur)->routerShortAddress = my_short_address;
|
thread_info(cur)->routerShortAddress = my_short_address;
|
||||||
thread_dynamic_storage_build_mle_table(cur->id);
|
thread_dynamic_storage_build_mle_table(cur->id);
|
||||||
|
@ -2278,7 +2305,7 @@ void thread_bootstrap_stop(protocol_interface_info_entry_t *cur)
|
||||||
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);
|
||||||
thread_dhcp_client_delete(cur->id);
|
dhcp_client_delete(cur->id);
|
||||||
thread_nd_service_delete(cur->id);
|
thread_nd_service_delete(cur->id);
|
||||||
thread_child_id_request_entry_clean(cur);
|
thread_child_id_request_entry_clean(cur);
|
||||||
thread_registered_mcast_addr_entry_clean(cur);
|
thread_registered_mcast_addr_entry_clean(cur);
|
||||||
|
@ -2356,6 +2383,7 @@ static int thread_nd_prefix_context_allocate(protocol_interface_info_entry_t *cu
|
||||||
if (cid == 16) {
|
if (cid == 16) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
context.cid = cid;
|
context.cid = cid;
|
||||||
context.compression = true;
|
context.compression = true;
|
||||||
context.stableData = stableData;
|
context.stableData = stableData;
|
||||||
|
@ -2499,6 +2527,7 @@ int thread_bootstrap_network_data_process(protocol_interface_info_entry_t *cur,
|
||||||
genericService.P_slaac = ((flags >> THREAD_P_SLAAC_BIT_MOVE) & 1);
|
genericService.P_slaac = ((flags >> THREAD_P_SLAAC_BIT_MOVE) & 1);
|
||||||
genericService.P_on_mesh = ((flags >> THREAD_P_ON_MESH_BIT_MOVE) & 1);
|
genericService.P_on_mesh = ((flags >> THREAD_P_ON_MESH_BIT_MOVE) & 1);
|
||||||
genericService.P_nd_dns = ((flags >> THREAD_P_ND_DNS_BIT_MOVE) & 1);
|
genericService.P_nd_dns = ((flags >> THREAD_P_ND_DNS_BIT_MOVE) & 1);
|
||||||
|
genericService.P_res1 = ((flags >> THREAD_P_ND_RES_BIT_MOVE) & 1);
|
||||||
if (thread_nd_local_list_add_on_mesh_prefix(networkDataStorage, &prefixTlv, &genericService) == 0) {
|
if (thread_nd_local_list_add_on_mesh_prefix(networkDataStorage, &prefixTlv, &genericService) == 0) {
|
||||||
if (networkDataStorage->stableUpdatePushed || networkDataStorage->temporaryUpdatePushed) {
|
if (networkDataStorage->stableUpdatePushed || networkDataStorage->temporaryUpdatePushed) {
|
||||||
if (!genericService.P_slaac) {
|
if (!genericService.P_slaac) {
|
||||||
|
@ -2525,7 +2554,7 @@ int thread_bootstrap_network_data_process(protocol_interface_info_entry_t *cur,
|
||||||
memcpy(&addr[8], ADDR_SHORT_ADR_SUFFIC, 6);
|
memcpy(&addr[8], ADDR_SHORT_ADR_SUFFIC, 6);
|
||||||
common_write_16_bit(genericService.routerID, &addr[14]);
|
common_write_16_bit(genericService.routerID, &addr[14]);
|
||||||
tr_debug("Delete DHCPv6 given address");
|
tr_debug("Delete DHCPv6 given address");
|
||||||
thread_dhcp_client_global_address_delete(cur->id, addr, prefixTlv.Prefix);
|
dhcp_client_global_address_delete(cur->id, addr, prefixTlv.Prefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2702,6 +2731,8 @@ int thread_bootstrap_network_data_activate(protocol_interface_info_entry_t *cur)
|
||||||
thread_border_router_network_data_update_notify(cur);
|
thread_border_router_network_data_update_notify(cur);
|
||||||
thread_bbr_network_data_update_notify(cur);
|
thread_bbr_network_data_update_notify(cur);
|
||||||
|
|
||||||
|
thread_maintenance_timer_set(cur, THREAD_MAINTENANCE_TIMER_INTERVAL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2744,7 +2775,6 @@ int thread_bootstrap_network_data_save(protocol_interface_info_entry_t *cur, thr
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void thread_bootstrap_network_prefixes_process(protocol_interface_info_entry_t *cur)
|
void thread_bootstrap_network_prefixes_process(protocol_interface_info_entry_t *cur)
|
||||||
{
|
{
|
||||||
// Route prefix is variable-length, so need to zero pad for ip6tos
|
// Route prefix is variable-length, so need to zero pad for ip6tos
|
||||||
|
@ -2794,6 +2824,8 @@ void thread_bootstrap_network_prefixes_process(protocol_interface_info_entry_t *
|
||||||
if (curBorderRouter->P_dhcp && weHostService && nd_proxy_enabled_for_upstream(cur->id) && nd_proxy_upstream_route_onlink(cur->id,curPrefix->servicesPrefix)) {
|
if (curBorderRouter->P_dhcp && weHostService && nd_proxy_enabled_for_upstream(cur->id) && nd_proxy_upstream_route_onlink(cur->id,curPrefix->servicesPrefix)) {
|
||||||
// don't add
|
// don't add
|
||||||
tr_debug("Suppressing onlink %s for proxy", trace_ipv6_prefix(curPrefix->servicesPrefix, curPrefix->servicesPrefixLen));
|
tr_debug("Suppressing onlink %s for proxy", trace_ipv6_prefix(curPrefix->servicesPrefix, curPrefix->servicesPrefixLen));
|
||||||
|
} else if (curBorderRouter->P_res1) {
|
||||||
|
ipv6_route_add(curPrefix->servicesPrefix, curPrefix->servicesPrefixLen, cur->id, NULL, ROUTE_THREAD_PROXIED_DUA_HOST, 0xffffffff, 0);
|
||||||
} else {
|
} else {
|
||||||
//add
|
//add
|
||||||
tr_debug("Adding onlink %s", trace_ipv6_prefix(curPrefix->servicesPrefix, curPrefix->servicesPrefixLen));
|
tr_debug("Adding onlink %s", trace_ipv6_prefix(curPrefix->servicesPrefix, curPrefix->servicesPrefixLen));
|
||||||
|
@ -2818,8 +2850,8 @@ void thread_bootstrap_network_prefixes_process(protocol_interface_info_entry_t *
|
||||||
if (!thread_dhcpv6_address_entry_available(curPrefix->servicesPrefix, &cur->ip_addresses)) {
|
if (!thread_dhcpv6_address_entry_available(curPrefix->servicesPrefix, &cur->ip_addresses)) {
|
||||||
thread_addr_write_mesh_local_16(addr, curBorderRouter->routerID, cur->thread_info);
|
thread_addr_write_mesh_local_16(addr, curBorderRouter->routerID, cur->thread_info);
|
||||||
/* Do not allow multiple DHCP solicits from one prefix => delete previous */
|
/* Do not allow multiple DHCP solicits from one prefix => delete previous */
|
||||||
thread_dhcp_client_global_address_delete(cur->id, NULL, curPrefix->servicesPrefix);
|
dhcp_client_global_address_delete(cur->id, NULL, curPrefix->servicesPrefix);
|
||||||
if (thread_dhcp_client_get_global_address(cur->id, addr, curPrefix->servicesPrefix, cur->mac, thread_dhcp_client_gua_error_cb) == 0) {
|
if (dhcp_client_get_global_address(cur->id, addr, curPrefix->servicesPrefix, cur->mac, thread_dhcp_client_gua_error_cb) == 0) {
|
||||||
tr_debug("GP Address Requested");
|
tr_debug("GP Address Requested");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2839,6 +2871,10 @@ void thread_bootstrap_network_prefixes_process(protocol_interface_info_entry_t *
|
||||||
icmpv6_slaac_address_add(cur, curPrefix->servicesPrefix, curPrefix->servicesPrefixLen, 0xffffffff, 0xffffffff, true, SLAAC_IID_DEFAULT);
|
icmpv6_slaac_address_add(cur, curPrefix->servicesPrefix, curPrefix->servicesPrefixLen, 0xffffffff, 0xffffffff, true, SLAAC_IID_DEFAULT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// generate address based on res1 bit
|
||||||
|
if (curBorderRouter->P_res1) {
|
||||||
|
thread_extension_dua_address_generate(cur,curPrefix->servicesPrefix,64);
|
||||||
|
}
|
||||||
|
|
||||||
} // for each borderRouterList
|
} // for each borderRouterList
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,9 @@ void thread_general_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg,
|
||||||
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);
|
||||||
|
|
||||||
|
/* Function to remove linked neighbours for REEDs and FEDs */
|
||||||
|
void thread_reed_fed_neighbour_links_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 mac_neighbor_table_entry *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);
|
||||||
|
@ -191,7 +194,6 @@ int thread_bootstrap_announce_send(protocol_interface_info_entry_t *cur, uint8_t
|
||||||
void thread_bootstrap_announcement_start(protocol_interface_info_entry_t *cur, uint8_t channel_page, uint16_t channel, uint8_t count, uint16_t period);
|
void thread_bootstrap_announcement_start(protocol_interface_info_entry_t *cur, uint8_t channel_page, uint16_t channel, uint8_t count, uint16_t period);
|
||||||
void thread_bootstrap_temporary_attach(protocol_interface_info_entry_t *cur, uint8_t channel_page, uint16_t channel, uint16_t panid, uint64_t timestamp);
|
void thread_bootstrap_temporary_attach(protocol_interface_info_entry_t *cur, uint8_t channel_page, uint16_t channel, uint16_t panid, uint64_t timestamp);
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define thread_interface_up(cur) ((void) 0)
|
#define thread_interface_up(cur) ((void) 0)
|
||||||
#define thread_bootstrap_state_machine(cur) ((void)0)
|
#define thread_bootstrap_state_machine(cur) ((void)0)
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "NWK_INTERFACE/Include/protocol.h"
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
#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_extension_bbr.h"
|
||||||
#include "6LoWPAN/Thread/thread_network_data_lib.h"
|
#include "6LoWPAN/Thread/thread_network_data_lib.h"
|
||||||
#include "6LoWPAN/Thread/thread_network_data_storage.h"
|
#include "6LoWPAN/Thread/thread_network_data_storage.h"
|
||||||
#include "6LoWPAN/Thread/thread_management_client.h"
|
#include "6LoWPAN/Thread/thread_management_client.h"
|
||||||
|
@ -591,6 +592,15 @@ void thread_border_router_network_data_update_notify(protocol_interface_info_ent
|
||||||
|
|
||||||
thread_border_router_network_data_appl_callback(cur);
|
thread_border_router_network_data_appl_callback(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void thread_border_router_old_partition_data_clean(int8_t interface_id)
|
||||||
|
{
|
||||||
|
thread_border_router_t *this = thread_border_router_find_by_interface(interface_id);
|
||||||
|
if (this) {
|
||||||
|
coap_service_request_delete_by_service_id(this->coap_service_id);
|
||||||
|
}
|
||||||
|
thread_extension_bbr_old_partition_data_clean(interface_id);
|
||||||
|
}
|
||||||
#endif // HAVE_THREAD_ROUTER
|
#endif // HAVE_THREAD_ROUTER
|
||||||
|
|
||||||
/*External APIs*/
|
/*External APIs*/
|
||||||
|
@ -837,7 +847,6 @@ int thread_border_router_dns_search_list_option_set(int8_t interface_id, uint8_t
|
||||||
static void thread_tmf_client_network_data_set_cb(int8_t interface_id, int8_t status, uint8_t *data_ptr, uint16_t data_len)
|
static void thread_tmf_client_network_data_set_cb(int8_t interface_id, int8_t status, uint8_t *data_ptr, uint16_t data_len)
|
||||||
{
|
{
|
||||||
protocol_interface_info_entry_t *cur;
|
protocol_interface_info_entry_t *cur;
|
||||||
(void) status;
|
|
||||||
(void) data_len;
|
(void) data_len;
|
||||||
(void) data_ptr;
|
(void) data_ptr;
|
||||||
|
|
||||||
|
@ -846,7 +855,7 @@ static void thread_tmf_client_network_data_set_cb(int8_t interface_id, int8_t st
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur->thread_info->localServerDataBase.publish_active = false;
|
cur->thread_info->localServerDataBase.publish_coap_req_id = 0;
|
||||||
|
|
||||||
tr_debug("BR a/sd response status: %s, addr: %x",status?"Fail":"OK", cur->thread_info->localServerDataBase.registered_rloc16);
|
tr_debug("BR a/sd response status: %s, addr: %x",status?"Fail":"OK", cur->thread_info->localServerDataBase.registered_rloc16);
|
||||||
|
|
||||||
|
@ -855,9 +864,11 @@ static void thread_tmf_client_network_data_set_cb(int8_t interface_id, int8_t st
|
||||||
thread_border_router_publish(cur->id);
|
thread_border_router_publish(cur->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// always update RLOC to new one. If COAP response fails then resubmit timer will trigger new a/sd
|
if (status == 0) {
|
||||||
cur->thread_info->localServerDataBase.registered_rloc16 = mac_helper_mac16_address_get(cur);
|
// If request was successful, then update RLOC to new one.
|
||||||
cur->thread_info->localServerDataBase.release_old_address = false;
|
cur->thread_info->localServerDataBase.registered_rloc16 = mac_helper_mac16_address_get(cur);
|
||||||
|
cur->thread_info->localServerDataBase.release_old_address = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -884,21 +895,20 @@ int thread_border_router_publish(int8_t interface_id)
|
||||||
rloc16 = mac_helper_mac16_address_get(cur);
|
rloc16 = mac_helper_mac16_address_get(cur);
|
||||||
tr_debug("Border router old: %x, new: %x", cur->thread_info->localServerDataBase.registered_rloc16, rloc16);
|
tr_debug("Border router old: %x, new: %x", cur->thread_info->localServerDataBase.registered_rloc16, rloc16);
|
||||||
|
|
||||||
if (cur->thread_info->localServerDataBase.publish_active) {
|
if (cur->thread_info->localServerDataBase.publish_coap_req_id) {
|
||||||
if (rloc16 != cur->thread_info->localServerDataBase.registered_rloc16) {
|
if (rloc16 != cur->thread_info->localServerDataBase.registered_rloc16) {
|
||||||
/*
|
/*
|
||||||
* Device short address has changed, cancel previous a/sd and a/as requests
|
* Device short address has changed, cancel previous a/sd requests
|
||||||
* and start resubmit timer
|
* and start resubmit timer
|
||||||
* */
|
* */
|
||||||
tr_debug("address changed, kill pending reuqests");
|
tr_debug("RLOC changed, kill pending a/sd request");
|
||||||
thread_management_client_pending_coap_request_kill(cur->id);
|
thread_management_client_coap_message_delete(cur->id, cur->thread_info->localServerDataBase.publish_coap_req_id);
|
||||||
thread_border_router_resubmit_timer_set(interface_id, 5);
|
thread_border_router_resubmit_timer_set(interface_id, 5);
|
||||||
return 0;
|
|
||||||
} else {
|
} else {
|
||||||
cur->thread_info->localServerDataBase.publish_pending = true;
|
cur->thread_info->localServerDataBase.publish_pending = true;
|
||||||
tr_debug("Activate pending status for publish");
|
tr_debug("Activate pending status for publish");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Allocate Memory for Data
|
//Allocate Memory for Data
|
||||||
|
@ -926,8 +936,10 @@ int thread_border_router_publish(int8_t interface_id)
|
||||||
if (payload_ptr) {
|
if (payload_ptr) {
|
||||||
ns_dyn_mem_free(payload_ptr);
|
ns_dyn_mem_free(payload_ptr);
|
||||||
}
|
}
|
||||||
if (ret_val == 0) {
|
if (ret_val > 0) {
|
||||||
cur->thread_info->localServerDataBase.publish_active = true;
|
// a/sd request successful, save coap request id
|
||||||
|
cur->thread_info->localServerDataBase.publish_coap_req_id = (uint16_t)ret_val;
|
||||||
|
ret_val = 0 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_border_router_resubmit_timer_set(interface_id, -1);
|
thread_border_router_resubmit_timer_set(interface_id, -1);
|
||||||
|
|
|
@ -85,6 +85,14 @@ void thread_border_router_network_data_appl_callback(protocol_interface_info_ent
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void thread_border_router_network_data_update_notify(protocol_interface_info_entry_t *cur);
|
void thread_border_router_network_data_update_notify(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Clear data related to old partition.
|
||||||
|
*
|
||||||
|
* \param interface_id Network interface ID.
|
||||||
|
*/
|
||||||
|
void thread_border_router_old_partition_data_clean(int8_t interface_id);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define thread_border_router_init(interface_id)
|
#define thread_border_router_init(interface_id)
|
||||||
#define thread_border_router_delete(interface_id)
|
#define thread_border_router_delete(interface_id)
|
||||||
|
@ -92,6 +100,7 @@ void thread_border_router_network_data_update_notify(protocol_interface_info_ent
|
||||||
#define thread_border_router_resubmit_timer_set(interface_id, seconds)
|
#define thread_border_router_resubmit_timer_set(interface_id, seconds)
|
||||||
#define thread_border_router_network_data_appl_callback(cur)
|
#define thread_border_router_network_data_appl_callback(cur)
|
||||||
#define thread_border_router_network_data_update_notify(cur)
|
#define thread_border_router_network_data_update_notify(cur)
|
||||||
|
#define thread_border_router_old_partition_data_clean(interface_id)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif /* THREAD_BORDER_ROUTER_API_INTERNAL_H_ */
|
#endif /* THREAD_BORDER_ROUTER_API_INTERNAL_H_ */
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "ns_list.h"
|
#include "ns_list.h"
|
||||||
#include "ns_trace.h"
|
#include "ns_trace.h"
|
||||||
#include "nsdynmemLIB.h"
|
#include "nsdynmemLIB.h"
|
||||||
|
#include "randLIB.h"
|
||||||
#include "common_functions.h"
|
#include "common_functions.h"
|
||||||
#include "ns_sha256.h"
|
#include "ns_sha256.h"
|
||||||
|
|
||||||
|
@ -74,6 +75,8 @@ typedef NS_LIST_HEAD(device_t, link) device_list_t;
|
||||||
typedef struct commissioner_entry {
|
typedef struct commissioner_entry {
|
||||||
device_list_t device_list;
|
device_list_t device_list;
|
||||||
uint8_t destination_address[16];
|
uint8_t destination_address[16];
|
||||||
|
uint8_t final_dest_address[16]; // Relay message final destination
|
||||||
|
uint8_t leader_address[16]; // leader ALOC for contacting the leader
|
||||||
uint8_t PSKc_ptr[16];
|
uint8_t PSKc_ptr[16];
|
||||||
thread_commissioning_status_cb *status_cb_ptr;
|
thread_commissioning_status_cb *status_cb_ptr;
|
||||||
uint16_t destination_port;
|
uint16_t destination_port;
|
||||||
|
@ -82,7 +85,8 @@ typedef struct commissioner_entry {
|
||||||
int8_t interface_id;
|
int8_t interface_id;
|
||||||
int8_t coap_service_id;
|
int8_t coap_service_id;
|
||||||
int8_t coap_secure_service_id;
|
int8_t coap_secure_service_id;
|
||||||
int8_t coap_virtual_service_id;
|
int8_t coap_secure_virtual_service_id;
|
||||||
|
int8_t coap_udp_proxy_service_id;
|
||||||
bool registered: 1;
|
bool registered: 1;
|
||||||
bool native_commissioner: 1;
|
bool native_commissioner: 1;
|
||||||
|
|
||||||
|
@ -167,7 +171,7 @@ static commissioner_t *commissioner_find_by_service(int8_t service_id)
|
||||||
{
|
{
|
||||||
commissioner_t *this = NULL;
|
commissioner_t *this = NULL;
|
||||||
ns_list_foreach(commissioner_t, cur_ptr, &instance_list) {
|
ns_list_foreach(commissioner_t, cur_ptr, &instance_list) {
|
||||||
if (cur_ptr->coap_service_id == service_id || cur_ptr->coap_virtual_service_id == service_id || cur_ptr->coap_secure_service_id == service_id) {
|
if (cur_ptr->coap_service_id == service_id || cur_ptr->coap_secure_virtual_service_id == service_id || cur_ptr->coap_secure_service_id == service_id || cur_ptr->coap_udp_proxy_service_id == service_id) {
|
||||||
this = cur_ptr;
|
this = cur_ptr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -237,12 +241,46 @@ static int commission_finalisation_resp_send(int8_t coap_service_id, device_t *d
|
||||||
* Callback functions
|
* Callback functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static int thread_commissioning_active_get_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *response_ptr)
|
||||||
|
{
|
||||||
|
commissioner_t *this = commissioner_find_by_service(service_id);
|
||||||
|
commissioning_state_e state = COMMISSIONING_STATE_REJECT;// Default is accept if we get error it is rejected
|
||||||
|
uint8_t *ptr;
|
||||||
|
uint16_t len;
|
||||||
|
(void) source_address;
|
||||||
|
(void) source_port;
|
||||||
|
|
||||||
|
/* Transaction failed */
|
||||||
|
if (!response_ptr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr_debug("management get response from comm module");
|
||||||
|
if (!this) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((len = thread_meshcop_tlv_find(response_ptr->payload_ptr, response_ptr->payload_len, MESHCOP_TLV_NETWORK_MESH_LOCAL_ULA, &ptr)) > 0) {
|
||||||
|
state = COMMISSIONING_STATE_ACCEPT;
|
||||||
|
tr_debug(" TLV ml prefix=%s\r\n", trace_array(ptr, len));
|
||||||
|
memcpy(this->leader_address, ptr, 8);
|
||||||
|
memcpy(this->leader_address + 8, ADDR_SHORT_ADR_SUFFIC, 6);
|
||||||
|
common_write_16_bit(0xfc00, this->leader_address + 14);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->status_cb_ptr) {
|
||||||
|
this->status_cb_ptr(this->interface_id, this->session_id, state);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int commissioning_leader_petition_recv_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *response_ptr)
|
static int commissioning_leader_petition_recv_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *response_ptr)
|
||||||
{
|
{
|
||||||
commissioner_t *this = commissioner_find_by_service(service_id);
|
commissioner_t *this = commissioner_find_by_service(service_id);
|
||||||
commissioning_state_e state = COMMISSIONING_STATE_REJECT;
|
commissioning_state_e state = COMMISSIONING_STATE_REJECT;
|
||||||
uint16_t session_id = 0;
|
uint16_t session_id = 0;
|
||||||
uint8_t *ptr;
|
uint8_t *ptr = NULL;
|
||||||
|
char *uri_ptr = THREAD_URI_ACTIVE_GET;
|
||||||
(void) source_address;
|
(void) source_address;
|
||||||
(void) source_port;
|
(void) source_port;
|
||||||
|
|
||||||
|
@ -267,6 +305,16 @@ static int commissioning_leader_petition_recv_cb(int8_t service_id, uint8_t sour
|
||||||
}
|
}
|
||||||
tr_debug("petition response session_id: %d state:%d",session_id, state);
|
tr_debug("petition response session_id: %d state:%d",session_id, state);
|
||||||
|
|
||||||
|
// if registered and native commissioner send ACTIVE_GET to BBR to get mesh parameters
|
||||||
|
// if not native set leader ALOC from stack
|
||||||
|
if (this->native_commissioner) {
|
||||||
|
coap_service_request_send(service_id, COAP_REQUEST_OPTIONS_NONE, this->destination_address, this->destination_port,
|
||||||
|
COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, uri_ptr, COAP_CT_OCTET_STREAM, NULL, 0, thread_commissioning_active_get_cb);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
thread_management_get_leader_aloc(this->interface_id, this->leader_address);
|
||||||
|
}
|
||||||
|
|
||||||
user_response:
|
user_response:
|
||||||
if (state == COMMISSIONING_STATE_REJECT) {
|
if (state == COMMISSIONING_STATE_REJECT) {
|
||||||
thci_trace("commissionerPetitionRejected");
|
thci_trace("commissionerPetitionRejected");
|
||||||
|
@ -376,10 +424,54 @@ static int commission_dataset_changed_notify_recv_cb(int8_t service_id, uint8_t
|
||||||
(void)source_port;
|
(void)source_port;
|
||||||
|
|
||||||
tr_debug("Dataset changed - notification received from: %s", trace_ipv6(source_address));
|
tr_debug("Dataset changed - notification received from: %s", trace_ipv6(source_address));
|
||||||
|
commissioner_t *this = commissioner_find_by_service(service_id);
|
||||||
|
|
||||||
|
if (!this) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
coap_service_request_send(service_id, COAP_REQUEST_OPTIONS_NONE, this->destination_address, this->destination_port,
|
||||||
|
COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_ACTIVE_GET, COAP_CT_OCTET_STREAM, NULL, 0, thread_commissioning_active_get_cb);
|
||||||
|
|
||||||
coap_service_response_send(service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_NONE, NULL, 0);
|
coap_service_response_send(service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, COAP_MSG_CODE_RESPONSE_CHANGED, COAP_CT_NONE, NULL, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
static int thread_commission_udp_proxy_receive_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
|
||||||
|
{
|
||||||
|
tr_debug("Recv UDP_RX.ntf");
|
||||||
|
|
||||||
|
commissioner_t *this = commissioner_find_by_service(service_id);
|
||||||
|
uint8_t *udp_encapsulation_ptr, *udp_tmf_ptr;
|
||||||
|
uint16_t udp_encapsulation_len, udp_tmf_len;
|
||||||
|
uint8_t *ipv6_addr_ptr;
|
||||||
|
uint16_t ipv6_addr_len;
|
||||||
|
uint16_t dest_port;
|
||||||
|
|
||||||
|
(void) source_port;
|
||||||
|
|
||||||
|
if (!this || !source_address || !request_ptr) {
|
||||||
|
return -1; // goto error response
|
||||||
|
}
|
||||||
|
|
||||||
|
udp_encapsulation_len = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_UDP_ENCAPSULATION, &udp_encapsulation_ptr);
|
||||||
|
ipv6_addr_len = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_IPV6_ADDRESS, &ipv6_addr_ptr);
|
||||||
|
|
||||||
|
if (udp_encapsulation_len == 0 || ipv6_addr_len < 16) {
|
||||||
|
tr_warn("Corrupted UDP_RX.ntf received (%d, %d)", udp_encapsulation_len, ipv6_addr_len);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest_port = common_read_16_bit(udp_encapsulation_ptr + 2);
|
||||||
|
udp_tmf_len = udp_encapsulation_len - 4;
|
||||||
|
udp_tmf_ptr = udp_encapsulation_ptr + 4;
|
||||||
|
|
||||||
|
tr_debug("UDP_RX tmf: %s", trace_array(udp_tmf_ptr, udp_tmf_len));
|
||||||
|
|
||||||
|
coap_service_virtual_socket_recv(this->coap_udp_proxy_service_id, ipv6_addr_ptr, dest_port, udp_tmf_ptr, udp_tmf_len);
|
||||||
|
|
||||||
|
return -1; // no response sent
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t *bloom_filter_calculate(uint8_t *bloom_filter_ptr,device_list_t device_list, int *steering_tlv_max_length)
|
static uint8_t *bloom_filter_calculate(uint8_t *bloom_filter_ptr,device_list_t device_list, int *steering_tlv_max_length)
|
||||||
{
|
{
|
||||||
|
@ -403,6 +495,35 @@ static uint8_t *bloom_filter_calculate(uint8_t *bloom_filter_ptr,device_list_t d
|
||||||
|
|
||||||
return bloom_filter_ptr;
|
return bloom_filter_ptr;
|
||||||
}
|
}
|
||||||
|
static int thread_commissioner_set_steering_data(commissioner_t *this, uint16_t session_id, uint8_t *steering_data_ptr, uint8_t steering_data_len)
|
||||||
|
{
|
||||||
|
uint8_t payload[24];/* 4 + 16 + 4*/
|
||||||
|
uint8_t *ptr;
|
||||||
|
int8_t coap_service_id;
|
||||||
|
if (!this || steering_data_len > 16) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = payload;
|
||||||
|
ptr = thread_meshcop_tlv_data_write(ptr, MESHCOP_TLV_STEERING_DATA, steering_data_len, steering_data_ptr);
|
||||||
|
ptr = thread_meshcop_tlv_data_write_uint16(ptr, MESHCOP_TLV_COMMISSIONER_SESSION_ID, session_id);
|
||||||
|
|
||||||
|
tr_debug("thread commissioner set steering data %s", trace_array(steering_data_ptr, steering_data_len));
|
||||||
|
memcpy(this->final_dest_address, this->leader_address,16);
|
||||||
|
//default uri for thread version 1.1
|
||||||
|
char *uri = THREAD_URI_COMMISSIONER_SET;
|
||||||
|
|
||||||
|
if (this->native_commissioner) {
|
||||||
|
coap_service_id = this->coap_udp_proxy_service_id;
|
||||||
|
} else {
|
||||||
|
coap_service_id = this->coap_service_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
coap_service_request_send(coap_service_id, COAP_REQUEST_OPTIONS_NONE, this->destination_address, this->destination_port,
|
||||||
|
COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, uri, COAP_CT_OCTET_STREAM, payload, ptr - payload, NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int commission_steering_data_update(commissioner_t *this)
|
static int commission_steering_data_update(commissioner_t *this)
|
||||||
{
|
{
|
||||||
|
@ -414,7 +535,7 @@ static int commission_steering_data_update(commissioner_t *this)
|
||||||
//bloom filter calculation function call
|
//bloom filter calculation function call
|
||||||
bloom_filter_calculate(bloom_filter_ptr, this->device_list, &steering_tlv_length);
|
bloom_filter_calculate(bloom_filter_ptr, this->device_list, &steering_tlv_length);
|
||||||
tr_debug("Steering bloom set :%s", trace_array(bloom_filter_ptr, 16));
|
tr_debug("Steering bloom set :%s", trace_array(bloom_filter_ptr, 16));
|
||||||
ret = thread_management_set_steering_data(this->management_instance, this->session_id,bloom_filter_ptr, steering_tlv_length, NULL);
|
ret = thread_commissioner_set_steering_data(this, this->session_id,bloom_filter_ptr, steering_tlv_length);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
tr_warn("Steering data set failed %d", ret);
|
tr_warn("Steering data set failed %d", ret);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -475,7 +596,7 @@ static int commission_relay_rx_recv_cb(int8_t service_id, uint8_t source_address
|
||||||
tr_warn("catching device for iid:%s", trace_array(&joiner_address[8], 8));
|
tr_warn("catching device for iid:%s", trace_array(&joiner_address[8], 8));
|
||||||
}
|
}
|
||||||
device_ptr->joiner_router_rloc = joiner_router_rloc;
|
device_ptr->joiner_router_rloc = joiner_router_rloc;
|
||||||
coap_service_virtual_socket_recv(this->coap_virtual_service_id, joiner_address, joiner_port, udp_ptr, udp_len);
|
coap_service_virtual_socket_recv(this->coap_secure_virtual_service_id, joiner_address, joiner_port, udp_ptr, udp_len);
|
||||||
return -1; // no response sent
|
return -1; // no response sent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,20 +737,55 @@ static int commissioner_br_security_done_cb(int8_t service_id, uint8_t address[1
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int thread_commissioning_remote_addr_set(commissioner_t *this)
|
static int thread_commission_udp_proxy_virtual_socket_send_cb(int8_t service_id, uint8_t destination_addr_ptr[static 16], uint16_t port, const uint8_t *data_ptr, uint16_t data_len)
|
||||||
{
|
{
|
||||||
if (0 == thread_management_get_leader_address(this->interface_id, this->destination_address)) {
|
(void) port;
|
||||||
tr_debug("on-mesh commissioner");
|
uint8_t *payload_ptr;
|
||||||
this->destination_port = THREAD_MANAGEMENT_PORT;
|
uint8_t *ptr;
|
||||||
this->native_commissioner = false;
|
uint16_t payload_len;
|
||||||
} else if (0 == thread_commissioning_native_commissioner_get_connection_info(this->interface_id,
|
uint16_t source_port;
|
||||||
this->destination_address, &this->destination_port)) {
|
|
||||||
tr_debug("native commissioner");
|
commissioner_t *this = commissioner_find_by_service(service_id);
|
||||||
this->native_commissioner = true;
|
if (!this) {
|
||||||
} else {
|
|
||||||
tr_error("No remote address");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tr_debug("UDP_TX.ntf tmf: %s", trace_array(data_ptr, data_len));
|
||||||
|
if (!this || !destination_addr_ptr || !data_ptr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
payload_len = 2 + THREAD_IPV6_ADDRESS_TLV_LENGTH + 4 + 4 + data_len; // MESHCOP_TLV_IPV6_ADDRESS + MESHCOP_TLV_UDP_ENCAPSULATION
|
||||||
|
|
||||||
|
payload_ptr = ns_dyn_mem_alloc(payload_len);
|
||||||
|
if (!payload_ptr) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = payload_ptr;
|
||||||
|
|
||||||
|
tr_debug("br_address %s final dest_address %s and port %d", trace_ipv6(this->destination_address),
|
||||||
|
trace_ipv6(this->final_dest_address), this->destination_port);
|
||||||
|
|
||||||
|
/* MESHCOP_TLV_IPV6_ADDRESS */
|
||||||
|
ptr = thread_meshcop_tlv_data_write(ptr, MESHCOP_TLV_IPV6_ADDRESS, THREAD_IPV6_ADDRESS_TLV_LENGTH, this->final_dest_address);
|
||||||
|
|
||||||
|
/* MESHCOP_TLV_UDP_ENCAPSULATION */
|
||||||
|
*ptr++ = MESHCOP_TLV_UDP_ENCAPSULATION;
|
||||||
|
*ptr++ = 0xff;
|
||||||
|
ptr = common_write_16_bit(2 + 2 + data_len, ptr); // length (Port x 2 + TMF message)
|
||||||
|
source_port = randLIB_get_16bit(); // ephemeral port, 16-bit number
|
||||||
|
ptr = common_write_16_bit(source_port, ptr); // source port,
|
||||||
|
ptr = common_write_16_bit(THREAD_MANAGEMENT_PORT, ptr); // destination port
|
||||||
|
memcpy(ptr, data_ptr, data_len);
|
||||||
|
ptr += data_len;
|
||||||
|
|
||||||
|
/* Send UDP_TX.ntf */
|
||||||
|
coap_service_request_send(this->coap_secure_service_id, COAP_REQUEST_OPTIONS_NONE, this->destination_address, this->destination_port,
|
||||||
|
COAP_MSG_TYPE_NON_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_UDP_TRANSMIT_NOTIFICATION, COAP_CT_OCTET_STREAM, payload_ptr, ptr - payload_ptr, NULL);
|
||||||
|
|
||||||
|
ns_dyn_mem_free(payload_ptr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -638,16 +794,17 @@ Public api functions
|
||||||
*/
|
*/
|
||||||
int thread_commissioning_register(int8_t interface_id, uint8_t PSKc[static 16])
|
int thread_commissioning_register(int8_t interface_id, uint8_t PSKc[static 16])
|
||||||
{
|
{
|
||||||
if (commissioner_find(interface_id)) {
|
commissioner_t *this = commissioner_find(interface_id);
|
||||||
return -1;
|
if (!this) {
|
||||||
|
this = commissioner_create(interface_id);
|
||||||
}
|
}
|
||||||
commissioner_t *this = commissioner_create(interface_id);
|
|
||||||
if (!this) {
|
if (!this) {
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
memcpy(this->PSKc_ptr,PSKc,16);
|
memcpy(this->PSKc_ptr,PSKc,16);
|
||||||
|
if (this->registered) {
|
||||||
this->management_instance = thread_management_register(interface_id);
|
return 0;
|
||||||
|
}
|
||||||
this->coap_service_id = coap_service_initialize(this->interface_id, THREAD_MANAGEMENT_PORT, COAP_SERVICE_OPTIONS_NONE, NULL, NULL);
|
this->coap_service_id = coap_service_initialize(this->interface_id, THREAD_MANAGEMENT_PORT, COAP_SERVICE_OPTIONS_NONE, NULL, NULL);
|
||||||
coap_service_register_uri(this->coap_service_id, THREAD_URI_RELAY_RECEIVE, COAP_SERVICE_ACCESS_POST_ALLOWED, commission_relay_rx_recv_cb);
|
coap_service_register_uri(this->coap_service_id, THREAD_URI_RELAY_RECEIVE, COAP_SERVICE_ACCESS_POST_ALLOWED, commission_relay_rx_recv_cb);
|
||||||
coap_service_register_uri(this->coap_service_id, THREAD_URI_JOINER_APPLICATION_REQUEST, COAP_SERVICE_ACCESS_POST_ALLOWED, commission_application_provision_req_recv_cb);
|
coap_service_register_uri(this->coap_service_id, THREAD_URI_JOINER_APPLICATION_REQUEST, COAP_SERVICE_ACCESS_POST_ALLOWED, commission_application_provision_req_recv_cb);
|
||||||
|
@ -655,10 +812,15 @@ int thread_commissioning_register(int8_t interface_id, uint8_t PSKc[static 16])
|
||||||
|
|
||||||
this->coap_secure_service_id = coap_service_initialize(this->interface_id, THREAD_COMMISSIONING_PORT, COAP_SERVICE_OPTIONS_SECURE | COAP_SERVICE_OPTIONS_SECURE_BYPASS, commissioner_br_security_start_cb, commissioner_br_security_done_cb);
|
this->coap_secure_service_id = coap_service_initialize(this->interface_id, THREAD_COMMISSIONING_PORT, COAP_SERVICE_OPTIONS_SECURE | COAP_SERVICE_OPTIONS_SECURE_BYPASS, commissioner_br_security_start_cb, commissioner_br_security_done_cb);
|
||||||
coap_service_register_uri(this->coap_secure_service_id, THREAD_URI_RELAY_RECEIVE, COAP_SERVICE_ACCESS_POST_ALLOWED, commission_relay_rx_recv_cb);
|
coap_service_register_uri(this->coap_secure_service_id, THREAD_URI_RELAY_RECEIVE, COAP_SERVICE_ACCESS_POST_ALLOWED, commission_relay_rx_recv_cb);
|
||||||
|
coap_service_register_uri(this->coap_secure_service_id, THREAD_URI_UDP_RECVEIVE_NOTIFICATION, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_commission_udp_proxy_receive_cb);
|
||||||
|
|
||||||
|
this->coap_secure_virtual_service_id = coap_service_initialize(this->interface_id, THREAD_MANAGEMENT_PORT, COAP_SERVICE_OPTIONS_SECURE | COAP_SERVICE_OPTIONS_VIRTUAL_SOCKET, joiner_commissioner_security_start_cb, commissioning_security_done_cb);
|
||||||
|
coap_service_register_uri(this->coap_secure_virtual_service_id, THREAD_URI_JOINER_FINALIZATION, COAP_SERVICE_ACCESS_POST_ALLOWED, commission_finalisation_req_recv_cb);
|
||||||
|
coap_service_virtual_socket_set_cb(this->coap_secure_virtual_service_id, commission_virtual_socket_send_cb);
|
||||||
|
|
||||||
|
this->coap_udp_proxy_service_id = coap_service_initialize(this->interface_id, THREAD_MANAGEMENT_PORT, COAP_SERVICE_OPTIONS_VIRTUAL_SOCKET, NULL, NULL);
|
||||||
|
coap_service_virtual_socket_set_cb(this->coap_udp_proxy_service_id, thread_commission_udp_proxy_virtual_socket_send_cb);
|
||||||
|
|
||||||
this->coap_virtual_service_id = coap_service_initialize(this->interface_id, THREAD_MANAGEMENT_PORT, COAP_SERVICE_OPTIONS_SECURE | COAP_SERVICE_OPTIONS_VIRTUAL_SOCKET, joiner_commissioner_security_start_cb, commissioning_security_done_cb);
|
|
||||||
coap_service_register_uri(this->coap_virtual_service_id, THREAD_URI_JOINER_FINALIZATION, COAP_SERVICE_ACCESS_POST_ALLOWED, commission_finalisation_req_recv_cb);
|
|
||||||
coap_service_virtual_socket_set_cb(this->coap_virtual_service_id, commission_virtual_socket_send_cb);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -672,11 +834,11 @@ int thread_commissioning_unregister(int8_t interface_id)
|
||||||
// Unregister the commissioner
|
// Unregister the commissioner
|
||||||
thread_commissioning_petition_keep_alive(this->interface_id, COMMISSIONING_STATE_REJECT);
|
thread_commissioning_petition_keep_alive(this->interface_id, COMMISSIONING_STATE_REJECT);
|
||||||
}
|
}
|
||||||
thread_management_unregister(this->management_instance);
|
|
||||||
|
|
||||||
coap_service_delete(this->coap_service_id);
|
coap_service_delete(this->coap_service_id);
|
||||||
coap_service_delete(this->coap_secure_service_id);
|
coap_service_delete(this->coap_secure_service_id);
|
||||||
coap_service_delete(this->coap_virtual_service_id);
|
coap_service_delete(this->coap_secure_virtual_service_id);
|
||||||
|
coap_service_delete(this->coap_udp_proxy_service_id);
|
||||||
|
|
||||||
commissioner_delete(this);
|
commissioner_delete(this);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -690,7 +852,6 @@ int thread_commissioning_petition_start(int8_t interface_id, char *commissioner_
|
||||||
uint8_t service_id;
|
uint8_t service_id;
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
char *uri_ptr;
|
char *uri_ptr;
|
||||||
|
|
||||||
this = commissioner_find(interface_id);
|
this = commissioner_find(interface_id);
|
||||||
|
|
||||||
if (!this) {
|
if (!this) {
|
||||||
|
@ -705,16 +866,14 @@ int thread_commissioning_petition_start(int8_t interface_id, char *commissioner_
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread_commissioning_remote_addr_set(this)) {
|
|
||||||
return -4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->native_commissioner) {
|
if (this->native_commissioner) {
|
||||||
uri_ptr = THREAD_URI_COMMISSIONER_PETITION;
|
uri_ptr = THREAD_URI_COMMISSIONER_PETITION;
|
||||||
service_id = this->coap_secure_service_id;
|
service_id = this->coap_secure_service_id;
|
||||||
} else {
|
} else {
|
||||||
uri_ptr = THREAD_URI_LEADER_PETITION;
|
uri_ptr = THREAD_URI_LEADER_PETITION;
|
||||||
service_id = this->coap_service_id;
|
service_id = this->coap_service_id;
|
||||||
|
thread_management_get_leader_aloc(this->interface_id, this->destination_address);
|
||||||
|
this->destination_port = THREAD_MANAGEMENT_PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->status_cb_ptr = status_cb_ptr;
|
this->status_cb_ptr = status_cb_ptr;
|
||||||
|
@ -747,16 +906,13 @@ int thread_commissioning_petition_keep_alive(int8_t interface_id, commissioning_
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread_commissioning_remote_addr_set(this)) {
|
|
||||||
return -4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->native_commissioner) {
|
if (this->native_commissioner) {
|
||||||
uri_ptr = THREAD_URI_COMMISSIONER_KEEP_ALIVE;
|
uri_ptr = THREAD_URI_COMMISSIONER_KEEP_ALIVE;
|
||||||
service_id = this->coap_secure_service_id;
|
service_id = this->coap_secure_service_id;
|
||||||
} else {
|
} else {
|
||||||
uri_ptr = THREAD_URI_LEADER_KEEP_ALIVE;
|
uri_ptr = THREAD_URI_LEADER_KEEP_ALIVE;
|
||||||
service_id = this->coap_service_id;
|
service_id = this->coap_service_id;
|
||||||
|
thread_management_get_leader_aloc(this->interface_id, this->destination_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = payload;
|
ptr = payload;
|
||||||
|
@ -867,6 +1023,20 @@ void *thread_commission_device_get_next(void *ptr, int8_t interface_id, bool *sh
|
||||||
return cur_ptr;
|
return cur_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int thread_commissioning_attach(int8_t interface_id, uint8_t *destination_address, uint16_t destination_port)
|
||||||
|
{
|
||||||
|
tr_debug("start ethernet commissioner attach");
|
||||||
|
commissioner_t *this = commissioner_find(interface_id);
|
||||||
|
if (!this) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy(this->destination_address, destination_address,16);
|
||||||
|
this->destination_port = destination_port;
|
||||||
|
this->native_commissioner = true;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int thread_commissioning_native_commissioner_start(int8_t interface_id, thread_commissioning_native_select_cb *cb_ptr)
|
int thread_commissioning_native_commissioner_start(int8_t interface_id, thread_commissioning_native_select_cb *cb_ptr)
|
||||||
{
|
{
|
||||||
protocol_interface_info_entry_t *cur;
|
protocol_interface_info_entry_t *cur;
|
||||||
|
@ -909,6 +1079,18 @@ int thread_commissioning_native_commissioner_connect(int8_t interface_id, thread
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
*cur->thread_info->native_commissioner_link = *link_ptr;
|
*cur->thread_info->native_commissioner_link = *link_ptr;
|
||||||
|
|
||||||
|
commissioner_t *this = commissioner_find(interface_id);
|
||||||
|
if (!this) {
|
||||||
|
this = commissioner_create(interface_id);
|
||||||
|
}
|
||||||
|
if (!this) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->native_commissioner = true;
|
||||||
|
memcpy(this->destination_address, link_ptr->destination_address,16);
|
||||||
|
this->destination_port = link_ptr->destination_port;
|
||||||
//TODO check that we are scanning for networks and reset backup timers
|
//TODO check that we are scanning for networks and reset backup timers
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -916,22 +1098,15 @@ int thread_commissioning_native_commissioner_connect(int8_t interface_id, thread
|
||||||
|
|
||||||
int thread_commissioning_native_commissioner_get_connection_info(int8_t interface_id, uint8_t *address_ptr, uint16_t *port)
|
int thread_commissioning_native_commissioner_get_connection_info(int8_t interface_id, uint8_t *address_ptr, uint16_t *port)
|
||||||
{
|
{
|
||||||
protocol_interface_info_entry_t *cur;
|
commissioner_t *this = commissioner_find(interface_id);
|
||||||
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
|
||||||
tr_debug("get native connection info");
|
tr_debug("get native connection info");
|
||||||
if(!cur || !cur->thread_info) {
|
if (!this) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread_attach_ready(cur) != 0) {
|
memcpy(address_ptr,this->destination_address,16);
|
||||||
return -2;
|
|
||||||
}
|
*port = this->destination_port;
|
||||||
if (protocol_6lowpan_interface_get_link_local_cordinator_address(cur, address_ptr) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (port) {
|
|
||||||
*port = cur->thread_info->native_commissioner_port;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1031,4 +1206,11 @@ int thread_commissioning_native_commissioner_connect(int8_t interface_id, thread
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int thread_commissioning_attach(int8_t interface_id, uint8_t *destination_address, uint16_t destination_port) {
|
||||||
|
(void)interface_id;
|
||||||
|
(void)destination_address;
|
||||||
|
(void)destination_port;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -44,9 +44,11 @@
|
||||||
#include "6LoWPAN/Bootstraps/protocol_6lowpan_interface.h"
|
#include "6LoWPAN/Bootstraps/protocol_6lowpan_interface.h"
|
||||||
#include "6LoWPAN/Thread/thread_common.h"
|
#include "6LoWPAN/Thread/thread_common.h"
|
||||||
#include "6LoWPAN/Thread/thread_beacon.h"
|
#include "6LoWPAN/Thread/thread_beacon.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_diagnostic.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_extension_bbr.h"
|
||||||
#include "6LoWPAN/Thread/thread_leader_service.h"
|
#include "6LoWPAN/Thread/thread_leader_service.h"
|
||||||
#include "6LoWPAN/Thread/thread_routing.h"
|
#include "6LoWPAN/Thread/thread_routing.h"
|
||||||
#include "6LoWPAN/Thread/thread_dhcpv6_client.h"
|
#include "DHCPv6_client/dhcpv6_client_api.h"
|
||||||
#include "6LoWPAN/Thread/thread_discovery.h"
|
#include "6LoWPAN/Thread/thread_discovery.h"
|
||||||
#include "6LoWPAN/Thread/thread_bootstrap.h"
|
#include "6LoWPAN/Thread/thread_bootstrap.h"
|
||||||
#include "6LoWPAN/Thread/thread_router_bootstrap.h"
|
#include "6LoWPAN/Thread/thread_router_bootstrap.h"
|
||||||
|
@ -60,6 +62,7 @@
|
||||||
#include "6LoWPAN/Thread/thread_management_internal.h"
|
#include "6LoWPAN/Thread/thread_management_internal.h"
|
||||||
#include "6LoWPAN/Thread/thread_management_client.h"
|
#include "6LoWPAN/Thread/thread_management_client.h"
|
||||||
#include "6LoWPAN/Thread/thread_management_server.h"
|
#include "6LoWPAN/Thread/thread_management_server.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_resolution_server.h"
|
||||||
#include "6LoWPAN/Thread/thread_resolution_client.h"
|
#include "6LoWPAN/Thread/thread_resolution_client.h"
|
||||||
#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"
|
||||||
|
@ -226,6 +229,7 @@ int8_t thread_bootstrap_up(protocol_interface_info_entry_t *cur)
|
||||||
ret_val = nwk_6lowpan_up(cur);
|
ret_val = nwk_6lowpan_up(cur);
|
||||||
|
|
||||||
cur->nwk_nd_re_scan_count = 0;
|
cur->nwk_nd_re_scan_count = 0;
|
||||||
|
cur->thread_info->link_sync_allowed = true;
|
||||||
|
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
@ -258,9 +262,11 @@ int8_t thread_bootstrap_down(protocol_interface_info_entry_t *cur)
|
||||||
thread_leader_mleid_rloc_map_to_nvm_write(cur);
|
thread_leader_mleid_rloc_map_to_nvm_write(cur);
|
||||||
thread_bootstrap_stop(cur);
|
thread_bootstrap_stop(cur);
|
||||||
mle_service_interface_unregister(cur->id);
|
mle_service_interface_unregister(cur->id);
|
||||||
|
thread_diagnostic_delete(cur->id); // delete before thread_management_server_delete as they share same coap_service id
|
||||||
|
thread_management_client_delete(cur->id); // delete before thread_management_server_delete as they share same coap_service id
|
||||||
|
thread_nd_service_disable(cur->id); // delete before thread_management_server_delete as they share same coap_service id
|
||||||
thread_management_server_delete(cur->id);
|
thread_management_server_delete(cur->id);
|
||||||
thread_joiner_application_deinit(cur->id);
|
thread_joiner_application_deinit(cur->id);
|
||||||
thread_management_client_delete(cur->id);
|
|
||||||
//free network Data
|
//free network Data
|
||||||
thread_network_data_free_and_clean(&cur->thread_info->networkDataStorage);
|
thread_network_data_free_and_clean(&cur->thread_info->networkDataStorage);
|
||||||
//free local also here
|
//free local also here
|
||||||
|
@ -451,7 +457,7 @@ void thread_data_base_init(thread_info_t *thread_info, int8_t interfaceId)
|
||||||
thread_leader_commissioner_create(thread_info);
|
thread_leader_commissioner_create(thread_info);
|
||||||
thread_info->rfc6775 = false;
|
thread_info->rfc6775 = false;
|
||||||
thread_info->threadPrivatePrefixInfo.ulaValid = false;
|
thread_info->threadPrivatePrefixInfo.ulaValid = false;
|
||||||
thread_info->routerIdReqCoapID = 0;
|
thread_info->routerIdRequested = false;
|
||||||
thread_info->networkDataRequested = false;
|
thread_info->networkDataRequested = false;
|
||||||
thread_info->proactive_an_timer = 0;
|
thread_info->proactive_an_timer = 0;
|
||||||
|
|
||||||
|
@ -905,6 +911,7 @@ static void thread_child_update_req_timer(protocol_interface_info_entry_t *cur,
|
||||||
if (cur->thread_info->childUpdateReqTimer == -1) {
|
if (cur->thread_info->childUpdateReqTimer == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur->thread_info->childUpdateReqTimer > seconds) {
|
if (cur->thread_info->childUpdateReqTimer > seconds) {
|
||||||
cur->thread_info->childUpdateReqTimer -= seconds;
|
cur->thread_info->childUpdateReqTimer -= seconds;
|
||||||
} else {
|
} else {
|
||||||
|
@ -945,6 +952,20 @@ static void thread_key_switch_timer(protocol_interface_info_entry_t *cur, uint16
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void thread_maintenance_timer(protocol_interface_info_entry_t *cur, uint32_t seconds)
|
||||||
|
{
|
||||||
|
if (thread_info(cur)->thread_maintenance_timer) {
|
||||||
|
if (thread_info(cur)->thread_maintenance_timer > seconds) {
|
||||||
|
thread_info(cur)->thread_maintenance_timer -= seconds;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_info(cur)->thread_maintenance_timer = THREAD_MAINTENANCE_TIMER_INTERVAL ;
|
||||||
|
|
||||||
|
thread_bootstrap_network_data_activate(cur);
|
||||||
|
}
|
||||||
|
|
||||||
void thread_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t ticks)
|
void thread_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t ticks)
|
||||||
{
|
{
|
||||||
uint8_t leader_address[16];
|
uint8_t leader_address[16];
|
||||||
|
@ -1003,6 +1024,7 @@ void thread_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t ticks)
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_router_bootstrap_timer(cur, ticks);
|
thread_router_bootstrap_timer(cur, ticks);
|
||||||
|
thread_maintenance_timer(cur, ticks);
|
||||||
thread_border_router_seconds_timer(cur->id, ticks);
|
thread_border_router_seconds_timer(cur->id, ticks);
|
||||||
thread_bbr_seconds_timer(cur->id, ticks);
|
thread_bbr_seconds_timer(cur->id, ticks);
|
||||||
thread_lowpower_timer(cur, ticks);
|
thread_lowpower_timer(cur, ticks);
|
||||||
|
@ -1720,9 +1742,105 @@ uint8_t *thread_leader_data_tlv_write(uint8_t *ptr, protocol_interface_info_entr
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool thread_addresses_needs_to_be_registered(protocol_interface_info_entry_t *cur)
|
||||||
|
{
|
||||||
|
lowpan_context_t *ctx;
|
||||||
|
uint8_t thread_realm_local_mcast_addr[16];
|
||||||
|
uint8_t thread_ll_unicast_prefix_based_mcast_addr[16];
|
||||||
|
if (thread_info(cur)->thread_device_mode != THREAD_DEVICE_MODE_SLEEPY_END_DEVICE &&
|
||||||
|
thread_info(cur)->thread_device_mode != THREAD_DEVICE_MODE_END_DEVICE) {
|
||||||
|
// No address registration for others than MED or SED
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for addresses
|
||||||
|
ns_list_foreach(if_address_entry_t, e, &cur->ip_addresses) {
|
||||||
|
if (addr_ipv6_scope(e->address, cur) == IPV6_SCOPE_GLOBAL || (addr_ipv6_scope(e->address, cur) == IPV6_SCOPE_REALM_LOCAL
|
||||||
|
&& !thread_addr_is_mesh_local_16(e->address, cur))) {
|
||||||
|
ctx = lowpan_context_get_by_address(&cur->lowpan_contexts, e->address);
|
||||||
|
if (!ctx) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ctx->cid != 0) {
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for multicast groups
|
||||||
|
thread_bootstrap_all_nodes_address_generate(thread_realm_local_mcast_addr, cur->thread_info->threadPrivatePrefixInfo.ulaPrefix, IPV6_SCOPE_REALM_LOCAL);
|
||||||
|
thread_bootstrap_all_nodes_address_generate(thread_ll_unicast_prefix_based_mcast_addr, cur->thread_info->threadPrivatePrefixInfo.ulaPrefix, IPV6_SCOPE_LINK_LOCAL);
|
||||||
|
ns_list_foreach(if_group_entry_t, entry, &cur->ip_groups)
|
||||||
|
{
|
||||||
|
if (!memcmp((entry->group), ADDR_MULTICAST_SOLICITED, 13)) {
|
||||||
|
/* Skip solicited node multicast address */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (addr_ipv6_equal(entry->group, thread_realm_local_mcast_addr)) {
|
||||||
|
/* Skip well-known realm-local all Thread nodes multicast address */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (addr_ipv6_equal(entry->group, thread_ll_unicast_prefix_based_mcast_addr)) {
|
||||||
|
/* Skip well-known link-local all Thread nodes multicast address */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (addr_ipv6_equal(entry->group, ADDR_ALL_MPL_FORWARDERS)) {
|
||||||
|
/* Skip All MPL Forwarders address */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (addr_ipv6_equal(entry->group, ADDR_REALM_LOCAL_ALL_NODES)) {
|
||||||
|
/* Skip Mesh local all nodes */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (addr_ipv6_equal(entry->group, ADDR_REALM_LOCAL_ALL_ROUTERS)) {
|
||||||
|
/* Skip Mesh local all routers */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *thread_ml_address_tlv_write(uint8_t *ptr, protocol_interface_info_entry_t *cur)
|
||||||
|
{
|
||||||
|
lowpan_context_t *ctx;
|
||||||
|
uint8_t *address_len_ptr;
|
||||||
|
|
||||||
|
if (thread_info(cur)->thread_device_mode != THREAD_DEVICE_MODE_SLEEPY_END_DEVICE &&
|
||||||
|
thread_info(cur)->thread_device_mode != THREAD_DEVICE_MODE_END_DEVICE) {
|
||||||
|
// No address registration for others than MED or SED
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
*ptr++ = MLE_TYPE_ADDRESS_REGISTRATION;
|
||||||
|
address_len_ptr = ptr++;
|
||||||
|
|
||||||
|
*address_len_ptr = 0;
|
||||||
|
|
||||||
|
ns_list_foreach(if_address_entry_t, e, &cur->ip_addresses) {
|
||||||
|
|
||||||
|
if (*address_len_ptr > 148 ) {
|
||||||
|
// Maximum length of address registrations
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!thread_addr_is_mesh_local_16(e->address, cur)) {
|
||||||
|
ctx = lowpan_context_get_by_address(&cur->lowpan_contexts, e->address);
|
||||||
|
if (ctx && ctx->cid == 0) {
|
||||||
|
//Write TLV to list
|
||||||
|
*ptr++ = (ctx->cid | 0x80);
|
||||||
|
memcpy(ptr, e->address + 8, 8);
|
||||||
|
ptr += 8;
|
||||||
|
*address_len_ptr += 9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t *thread_address_registration_tlv_write(uint8_t *ptr, protocol_interface_info_entry_t *cur)
|
uint8_t *thread_address_registration_tlv_write(uint8_t *ptr, protocol_interface_info_entry_t *cur)
|
||||||
{
|
{
|
||||||
uint8_t thread_realm_local_mcast_addr[16];
|
uint8_t thread_realm_local_mcast_addr[16];
|
||||||
|
uint8_t thread_ll_unicast_prefix_based_mcast_addr[16];
|
||||||
lowpan_context_t *ctx;
|
lowpan_context_t *ctx;
|
||||||
uint8_t *address_len_ptr;
|
uint8_t *address_len_ptr;
|
||||||
|
|
||||||
|
@ -1738,7 +1856,6 @@ uint8_t *thread_address_registration_tlv_write(uint8_t *ptr, protocol_interface_
|
||||||
|
|
||||||
// Register all global addressess
|
// Register all global addressess
|
||||||
ns_list_foreach(if_address_entry_t, e, &cur->ip_addresses) {
|
ns_list_foreach(if_address_entry_t, e, &cur->ip_addresses) {
|
||||||
|
|
||||||
if (*address_len_ptr > 148 ) {
|
if (*address_len_ptr > 148 ) {
|
||||||
// Maximum length of address registrations
|
// Maximum length of address registrations
|
||||||
continue;
|
continue;
|
||||||
|
@ -1762,23 +1879,27 @@ uint8_t *thread_address_registration_tlv_write(uint8_t *ptr, protocol_interface_
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Registers multicast addresses to the parent */
|
/* Registers multicast addresses to the parent */
|
||||||
thread_bootstrap_all_nodes_address_generate(thread_realm_local_mcast_addr, cur->thread_info->threadPrivatePrefixInfo.ulaPrefix, 3);
|
thread_bootstrap_all_nodes_address_generate(thread_realm_local_mcast_addr, cur->thread_info->threadPrivatePrefixInfo.ulaPrefix, IPV6_SCOPE_REALM_LOCAL);
|
||||||
|
thread_bootstrap_all_nodes_address_generate(thread_ll_unicast_prefix_based_mcast_addr, cur->thread_info->threadPrivatePrefixInfo.ulaPrefix, IPV6_SCOPE_LINK_LOCAL);
|
||||||
ns_list_foreach(if_group_entry_t, entry, &cur->ip_groups)
|
ns_list_foreach(if_group_entry_t, entry, &cur->ip_groups)
|
||||||
{
|
{
|
||||||
if (*address_len_ptr > 148) {
|
if (*address_len_ptr > 148) {
|
||||||
// Maximum length of address registrations
|
// Maximum length of address registrations
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (addr_ipv6_multicast_scope(entry->group) < IPV6_SCOPE_REALM_LOCAL) {
|
|
||||||
/* Skip Link Local multicast address */
|
if (!memcmp((entry->group), ADDR_MULTICAST_SOLICITED, 13)) {
|
||||||
|
/* Skip solicited node multicast address */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr_ipv6_equal(entry->group, thread_realm_local_mcast_addr)) {
|
if (addr_ipv6_equal(entry->group, thread_realm_local_mcast_addr)) {
|
||||||
/* Skip well-known realm-local all Thread nodes multicast address */
|
/* Skip well-known realm-local all Thread nodes multicast address */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (addr_ipv6_equal(entry->group, thread_ll_unicast_prefix_based_mcast_addr)) {
|
||||||
|
/* Skip well-known link-local all Thread nodes multicast address */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (addr_ipv6_equal(entry->group, ADDR_ALL_MPL_FORWARDERS)) {
|
if (addr_ipv6_equal(entry->group, ADDR_ALL_MPL_FORWARDERS)) {
|
||||||
/* Skip All MPL Forwarders address */
|
/* Skip All MPL Forwarders address */
|
||||||
continue;
|
continue;
|
||||||
|
@ -1935,9 +2056,34 @@ static void thread_address_notification_cb(struct protocol_interface_info_entry
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool thread_mcast_should_register_address(struct protocol_interface_info_entry *cur, uint8_t *addr)
|
||||||
|
{
|
||||||
|
uint8_t thread_realm_local_mcast_addr[16];
|
||||||
|
uint8_t thread_ll_unicast_prefix_based_mcast_addr[16];
|
||||||
|
thread_bootstrap_all_nodes_address_generate(thread_realm_local_mcast_addr, cur->thread_info->threadPrivatePrefixInfo.ulaPrefix, IPV6_SCOPE_REALM_LOCAL);
|
||||||
|
thread_bootstrap_all_nodes_address_generate(thread_ll_unicast_prefix_based_mcast_addr, cur->thread_info->threadPrivatePrefixInfo.ulaPrefix, IPV6_SCOPE_LINK_LOCAL);
|
||||||
|
if (addr_ipv6_multicast_scope(addr) >= IPV6_SCOPE_LINK_LOCAL) {
|
||||||
|
if (memcmp(addr, ADDR_MULTICAST_SOLICITED, 13) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (memcmp(addr, thread_realm_local_mcast_addr, 16) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (memcmp(addr, thread_ll_unicast_prefix_based_mcast_addr, 16) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (memcmp(addr, ADDR_LINK_LOCAL_ALL_NODES, 16) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (memcmp(addr, ADDR_LINK_LOCAL_ALL_ROUTERS, 16) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (thread_attach_ready(interface) != 0) {
|
if (thread_attach_ready(interface) != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1946,7 +2092,7 @@ void thread_mcast_group_change(struct protocol_interface_info_entry *interface,
|
||||||
|
|
||||||
if (thread_bootstrap_should_register_address(interface)) {
|
if (thread_bootstrap_should_register_address(interface)) {
|
||||||
/* Trigger Child Update Request only if MTD child's multicast address change */
|
/* Trigger Child Update Request only if MTD child's multicast address change */
|
||||||
if (addr_ipv6_multicast_scope(group->group) > IPV6_SCOPE_LINK_LOCAL) {
|
if (thread_mcast_should_register_address(interface, group->group)) {
|
||||||
interface->thread_info->childUpdateReqTimer = 1;
|
interface->thread_info->childUpdateReqTimer = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1956,10 +2102,16 @@ void thread_mcast_group_change(struct protocol_interface_info_entry *interface,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void thread_old_partition_data_clean(int8_t interface_id)
|
||||||
|
{
|
||||||
|
thread_management_client_old_partition_data_clean(interface_id);
|
||||||
|
thread_border_router_old_partition_data_clean(interface_id);
|
||||||
|
}
|
||||||
|
|
||||||
void thread_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_old_partition_data_clean(cur->id);
|
||||||
|
|
||||||
/* Reset previous routing information */
|
/* Reset previous routing information */
|
||||||
thread_routing_reset(&cur->thread_info->routing);
|
thread_routing_reset(&cur->thread_info->routing);
|
||||||
|
@ -1967,6 +2119,9 @@ void thread_partition_data_purge(protocol_interface_info_entry_t *cur)
|
||||||
/* Flush address cache */
|
/* Flush address cache */
|
||||||
ipv6_neighbour_cache_flush(&cur->ipv6_neighbour_cache);
|
ipv6_neighbour_cache_flush(&cur->ipv6_neighbour_cache);
|
||||||
|
|
||||||
|
/* Remove linked neighbours for REEDs and FEDs */
|
||||||
|
thread_reed_fed_neighbour_links_clean(cur);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool thread_partition_match(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData)
|
bool thread_partition_match(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData)
|
||||||
|
@ -1997,5 +2152,10 @@ void thread_neighbor_communication_update(protocol_interface_info_entry_t *cur,
|
||||||
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, neighbor_attribute_index);
|
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, neighbor_attribute_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void thread_maintenance_timer_set(protocol_interface_info_entry_t *cur, uint16_t delay)
|
||||||
|
{
|
||||||
|
thread_info(cur)->thread_maintenance_timer = delay;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -309,10 +309,10 @@ typedef struct thread_info_s {
|
||||||
uint16_t routerShortAddress;
|
uint16_t routerShortAddress;
|
||||||
uint16_t reedJitterTimer;
|
uint16_t reedJitterTimer;
|
||||||
uint16_t reedMergeAdvTimer;
|
uint16_t reedMergeAdvTimer;
|
||||||
uint16_t routerIdReqCoapID; // COAP msg id of RouterID request
|
|
||||||
int16_t childUpdateReqTimer;
|
int16_t childUpdateReqTimer;
|
||||||
uint16_t childUpdateReqMsgId;
|
uint16_t childUpdateReqMsgId;
|
||||||
uint16_t proactive_an_timer;
|
uint16_t proactive_an_timer;
|
||||||
|
uint16_t thread_maintenance_timer;
|
||||||
//uint8_t lastValidRouteMask[8];
|
//uint8_t lastValidRouteMask[8];
|
||||||
int8_t interface_id; //Thread Interface ID
|
int8_t interface_id; //Thread Interface ID
|
||||||
uint8_t version;
|
uint8_t version;
|
||||||
|
@ -322,11 +322,13 @@ typedef struct thread_info_s {
|
||||||
bool rfc6775: 1;
|
bool rfc6775: 1;
|
||||||
bool requestFullNetworkData: 1;
|
bool requestFullNetworkData: 1;
|
||||||
bool leaderCab: 1;
|
bool leaderCab: 1;
|
||||||
|
bool routerIdRequested: 1;
|
||||||
bool releaseRouterId: 1;
|
bool releaseRouterId: 1;
|
||||||
bool networkSynch: 1;
|
bool networkSynch: 1;
|
||||||
bool networkDataRequested: 1;
|
bool networkDataRequested: 1;
|
||||||
bool end_device_link_synch: 1;
|
bool end_device_link_synch: 1;
|
||||||
bool router_mc_addrs_registered: 1;
|
bool router_mc_addrs_registered: 1;
|
||||||
|
bool link_sync_allowed:1;
|
||||||
bool leader_synced:1; // flag used by leader after restart
|
bool leader_synced:1; // flag used by leader after restart
|
||||||
} thread_info_t;
|
} thread_info_t;
|
||||||
|
|
||||||
|
@ -397,6 +399,11 @@ void thread_child_mcast_entries_remove(protocol_interface_info_entry_t *cur, con
|
||||||
uint8_t thread_leader_data_tlv_size(protocol_interface_info_entry_t *cur);
|
uint8_t thread_leader_data_tlv_size(protocol_interface_info_entry_t *cur);
|
||||||
uint8_t *thread_leader_data_tlv_write(uint8_t *ptr, protocol_interface_info_entry_t *cur);
|
uint8_t *thread_leader_data_tlv_write(uint8_t *ptr, protocol_interface_info_entry_t *cur);
|
||||||
uint8_t *thread_address_registration_tlv_write(uint8_t *ptr, protocol_interface_info_entry_t *cur);
|
uint8_t *thread_address_registration_tlv_write(uint8_t *ptr, protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
|
// returns true if SED/MED needs to register additional address to parent
|
||||||
|
bool thread_addresses_needs_to_be_registered(protocol_interface_info_entry_t *cur);
|
||||||
|
// write mesh local address tlv
|
||||||
|
uint8_t *thread_ml_address_tlv_write(uint8_t *ptr, protocol_interface_info_entry_t *cur);
|
||||||
int thread_link_reject_send(protocol_interface_info_entry_t *interface, const uint8_t *ll64);
|
int thread_link_reject_send(protocol_interface_info_entry_t *interface, const uint8_t *ll64);
|
||||||
thread_leader_info_t *thread_allocate_and_init_leader_private_data(void);
|
thread_leader_info_t *thread_allocate_and_init_leader_private_data(void);
|
||||||
thread_route_cost_t thread_link_quality_to_cost(thread_link_quality_e quality);
|
thread_route_cost_t thread_link_quality_to_cost(thread_link_quality_e quality);
|
||||||
|
@ -441,6 +448,7 @@ bool thread_partition_match(protocol_interface_info_entry_t *cur, thread_leader_
|
||||||
void thread_partition_info_update(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);
|
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);
|
bool thread_stable_context_check(protocol_interface_info_entry_t *cur, buffer_t *buf);
|
||||||
|
void thread_maintenance_timer_set(protocol_interface_info_entry_t *cur, uint16_t delay);
|
||||||
#else // HAVE_THREAD
|
#else // HAVE_THREAD
|
||||||
|
|
||||||
NS_DUMMY_DEFINITIONS_OK
|
NS_DUMMY_DEFINITIONS_OK
|
||||||
|
|
|
@ -326,6 +326,17 @@
|
||||||
*/
|
*/
|
||||||
#define THREAD_BBR_ROUTER_ID_REQUEST_STATUS THREAD_COAP_STATUS_TLV_HAVE_CHILD_ID_REQUEST
|
#define THREAD_BBR_ROUTER_ID_REQUEST_STATUS THREAD_COAP_STATUS_TLV_HAVE_CHILD_ID_REQUEST
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Number of destination and neighbor cache entries assuming 250 thread devices (worst case) connecting to cloud service.
|
||||||
|
* Six entries reserved for backbone devices.
|
||||||
|
*/
|
||||||
|
#define THREAD_BBR_IPV6_DESTINATION_CACHE_SIZE 256
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timeout to solicit address from DHCP if previous request fails.
|
||||||
|
*/
|
||||||
|
#define THREAD_MAINTENANCE_TIMER_INTERVAL 300
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build time flag to enable THCI special traces for test harness purposes
|
* Build time flag to enable THCI special traces for test harness purposes
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -145,6 +145,7 @@
|
||||||
#define THREAD_DEFAULT_KEY_SWITCH_GUARD_TIME 624 // Hours
|
#define THREAD_DEFAULT_KEY_SWITCH_GUARD_TIME 624 // Hours
|
||||||
#define THREAD_DEFAULT_KEY_ROTATION 672 // Hours
|
#define THREAD_DEFAULT_KEY_ROTATION 672 // Hours
|
||||||
#define THREAD_COMMISSIONER_KEEP_ALIVE_INTERVAL 50000 // Default thread commissioner keep-alive message interval (milliseconds)
|
#define THREAD_COMMISSIONER_KEEP_ALIVE_INTERVAL 50000 // Default thread commissioner keep-alive message interval (milliseconds)
|
||||||
|
#define THREAD_DELAY_JOIN_ENT 50 // Minimum delay for Joiner router before sending joiner entrust (milliseconds)
|
||||||
|
|
||||||
#define THREAD_FAILED_CHILD_TRANSMISSIONS 4
|
#define THREAD_FAILED_CHILD_TRANSMISSIONS 4
|
||||||
#define THREAD_FAILED_ROUTER_TRANSMISSIONS 4
|
#define THREAD_FAILED_ROUTER_TRANSMISSIONS 4
|
||||||
|
|
|
@ -1,98 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2014-2015, 2017, 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 SOURCE_6LOWPAN_THREAD_THREAD_DHCPV6_CLIENT_H_
|
|
||||||
#define SOURCE_6LOWPAN_THREAD_THREAD_DHCPV6_CLIENT_H_
|
|
||||||
|
|
||||||
#include <ns_types.h>
|
|
||||||
|
|
||||||
/* Thread DHCP client implementation.
|
|
||||||
*
|
|
||||||
* Responsibilities of this module are:
|
|
||||||
* - send router id address request and receive new router address and inform it to thread bootstrap.
|
|
||||||
* - handle Global address queries and refresh inside thread network.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Initialize dhcp thread dhcp client.
|
|
||||||
*
|
|
||||||
* This instance needs to bee initialized once for each thread network interface.
|
|
||||||
* if only one thread instance is supported this is needed to call only once.
|
|
||||||
*
|
|
||||||
* /param interface interface id of this thread instance.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void thread_dhcp_client_init(int8_t interface);
|
|
||||||
|
|
||||||
/* Delete dhcp thread dhcp client.
|
|
||||||
*
|
|
||||||
* When this is called all addressed assigned by this module are removed from stack.
|
|
||||||
*/
|
|
||||||
void thread_dhcp_client_delete(int8_t interface);
|
|
||||||
|
|
||||||
/* Global address handler.
|
|
||||||
*
|
|
||||||
* This module updates the addresses from dhcp server and sets them in stack.
|
|
||||||
* this module makes refresh of address when needed.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* give dhcp server and prefix for global address assignment
|
|
||||||
*
|
|
||||||
* /param interface interface where address is got
|
|
||||||
* /param dhcp_addr dhcp server ML16 address where address is registered.
|
|
||||||
* /param prefix dhcp server ML16 address where address is registered.
|
|
||||||
* /param mac64 64 bit mac address for identifieng client.
|
|
||||||
* /param error_cb error callback that is called if address cannot be created or becomes invalid.
|
|
||||||
* /param register_status true if address registered.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
typedef void (thread_dhcp_client_global_adress_cb)(int8_t interface, uint8_t dhcp_addr[static 16], uint8_t prefix[static 16], bool register_status);
|
|
||||||
|
|
||||||
int thread_dhcp_client_get_global_address(int8_t interface, uint8_t dhcp_addr[static 16], uint8_t prefix[static 16], uint8_t mac64[static 8], thread_dhcp_client_global_adress_cb *error_cb);
|
|
||||||
|
|
||||||
/* Renew all leased adddresses might be used when short address changes
|
|
||||||
*
|
|
||||||
* /param interface interface where address is got
|
|
||||||
*/
|
|
||||||
void thread_dhcp_client_global_address_renew(int8_t interface);
|
|
||||||
|
|
||||||
/* Delete address from device
|
|
||||||
* if prefix is NULL all are deleted
|
|
||||||
*
|
|
||||||
* /param interface interface where address is got
|
|
||||||
* /param prefix dhcp server ML16 address where address is registered.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void thread_dhcp_client_global_address_delete(int8_t interface, uint8_t dhcp_addr[static 16], uint8_t prefix[static 16]);
|
|
||||||
|
|
||||||
#endif /* SOURCE_6LOWPAN_THREAD_THREAD_DHCPV6_CLIENT_H_ */
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
#if defined(HAVE_THREAD) && defined(HAVE_DHCPV6_SERVER)
|
||||||
|
#include <string.h>
|
||||||
|
#include <ns_types.h>
|
||||||
|
#include "eventOS_event.h"
|
||||||
|
#include "eventOS_event_timer.h"
|
||||||
|
#include "common_functions.h"
|
||||||
|
#include "ns_trace.h"
|
||||||
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
|
#include "ipv6_stack/protocol_ipv6.h"
|
||||||
|
#include "Common_Protocols/ipv6_constants.h"
|
||||||
|
#include "Common_Protocols/ipv6.h"
|
||||||
|
#include "DHCPv6_Server/DHCPv6_server_service.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_bbr_api_internal.h"
|
||||||
|
|
||||||
|
#define TRACE_GROUP "thds"
|
||||||
|
|
||||||
|
static void thread_service_remove_GUA_from_neighcache(protocol_interface_info_entry_t *cur, uint8_t *targetAddress)
|
||||||
|
{
|
||||||
|
ipv6_neighbour_t *neighbour_entry;
|
||||||
|
|
||||||
|
neighbour_entry = ipv6_neighbour_lookup(&cur->ipv6_neighbour_cache, targetAddress);
|
||||||
|
if (neighbour_entry) {
|
||||||
|
tr_debug("Remove from neigh Cache: %s", tr_ipv6(targetAddress));
|
||||||
|
ipv6_neighbour_entry_remove(&cur->ipv6_neighbour_cache, neighbour_entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void thread_dhcp_address_prefer_remove_cb(int8_t interfaceId, uint8_t *targetAddress, void *prefix_info)
|
||||||
|
{
|
||||||
|
protocol_interface_info_entry_t *curPtr = protocol_stack_interface_info_get_by_id(interfaceId);
|
||||||
|
if (!curPtr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!targetAddress) {
|
||||||
|
//Clear All targets routes
|
||||||
|
ipv6_route_table_remove_info(interfaceId, ROUTE_THREAD_PROXIED_HOST,prefix_info);
|
||||||
|
} else {
|
||||||
|
tr_debug("Address Preferred Timeout");
|
||||||
|
ipv6_route_delete(targetAddress, 128, interfaceId, NULL, ROUTE_THREAD_PROXIED_HOST);
|
||||||
|
thread_service_remove_GUA_from_neighcache(curPtr, targetAddress);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool thread_dhcp_address_add_cb(int8_t interfaceId, dhcp_address_cache_update_t *address_info, void *route_src)
|
||||||
|
{
|
||||||
|
protocol_interface_info_entry_t *curPtr = protocol_stack_interface_info_get_by_id(interfaceId);
|
||||||
|
if (!curPtr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is solicit from existing address, flush ND cache.
|
||||||
|
if (address_info->allocatedNewAddress) {
|
||||||
|
// coverity[returned_null] for ignoring protocol_stack_interface_info_get_by_id NULL return
|
||||||
|
thread_service_remove_GUA_from_neighcache(curPtr, address_info->allocatedAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thread_bbr_nd_entry_add(interfaceId,address_info->allocatedAddress, address_info->validLifeTime, route_src) == -1) {
|
||||||
|
// No nanostack BBR present we will put entry for application implemented BBR
|
||||||
|
ipv6_route_t *route = ipv6_route_add_with_info(address_info->allocatedAddress, 128, interfaceId, NULL, ROUTE_THREAD_PROXIED_HOST,route_src,0, address_info->validLifeTime, 0);
|
||||||
|
if (!route) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int thread_dhcp6_server_init(int8_t interface_id, uint8_t prefix[8], uint8_t eui64[8], uint32_t validLifeTimne)
|
||||||
|
{
|
||||||
|
if (DHCPv6_server_service_init(interface_id, prefix, eui64, DHCPV6_DUID_HARDWARE_EUI64_TYPE) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//Register Callbacks
|
||||||
|
DHCPv6_server_service_callback_set(interface_id, prefix, thread_dhcp_address_prefer_remove_cb, thread_dhcp_address_add_cb);
|
||||||
|
//SET Timeout
|
||||||
|
DHCPv6_server_service_set_address_validlifetime(interface_id, prefix, validLifeTimne);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* 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_DHCPV6_SERVER_H_
|
||||||
|
#define THREAD_DHCPV6_SERVER_H_
|
||||||
|
#if defined(HAVE_THREAD) && defined(HAVE_DHCPV6_SERVER)
|
||||||
|
int thread_dhcp6_server_init(int8_t interface_id, uint8_t prefix[8], uint8_t eui64[8], uint32_t validLifeTimne);
|
||||||
|
#else
|
||||||
|
#define thread_dhcp6_server_init(interface_id, prefix, eui64, validLifeTimne) (-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* THREAD_DHCPV6_SERVER_H_ */
|
|
@ -35,6 +35,7 @@
|
||||||
#include "nsdynmemLIB.h"
|
#include "nsdynmemLIB.h"
|
||||||
#include "net_interface.h"
|
#include "net_interface.h"
|
||||||
#include "thread_management_if.h"
|
#include "thread_management_if.h"
|
||||||
|
#include "thread_management_server.h"
|
||||||
#include "thread_common.h"
|
#include "thread_common.h"
|
||||||
#include "thread_joiner_application.h"
|
#include "thread_joiner_application.h"
|
||||||
#include "thread_leader_service.h"
|
#include "thread_leader_service.h"
|
||||||
|
@ -229,6 +230,10 @@ static int thread_diagnostic_configuration_calc(protocol_interface_info_entry_t
|
||||||
payload_len += 2+1;
|
payload_len += 2+1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DIAGCOP_TLV_MAX_CHILD_TIMEOUT:
|
||||||
|
payload_len += 2 + 4;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// todo: Other TLV's not supported atm
|
// todo: Other TLV's not supported atm
|
||||||
break;
|
break;
|
||||||
|
@ -254,6 +259,7 @@ static uint8_t *thread_diagnostic_get_build(protocol_interface_info_entry_t *cur
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
int written_address_count = 0;
|
int written_address_count = 0;
|
||||||
uint16_t ipv6_address_count = 0;
|
uint16_t ipv6_address_count = 0;
|
||||||
|
uint32_t max_child_timeout = 0;
|
||||||
uint8_t extended_address[8] = {0};
|
uint8_t extended_address[8] = {0};
|
||||||
|
|
||||||
arm_net_interface_address_list_size(cur->id, &ipv6_address_count);
|
arm_net_interface_address_list_size(cur->id, &ipv6_address_count);
|
||||||
|
@ -352,6 +358,12 @@ static uint8_t *thread_diagnostic_get_build(protocol_interface_info_entry_t *cur
|
||||||
response_ptr = thread_diagcop_tlv_data_write_uint8(response_ptr, DIAGCOP_TLV_CHANNEL_PAGES, 0);
|
response_ptr = thread_diagcop_tlv_data_write_uint8(response_ptr, DIAGCOP_TLV_CHANNEL_PAGES, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DIAGCOP_TLV_MAX_CHILD_TIMEOUT:
|
||||||
|
if (thread_router_bootstrap_child_max_timeout_get(cur, &max_child_timeout) == 0) {
|
||||||
|
response_ptr = thread_diagcop_tlv_data_write_uint32(response_ptr, DIAGCOP_TLV_MAX_CHILD_TIMEOUT, max_child_timeout);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -532,7 +544,7 @@ int thread_diagnostic_init(int8_t interface_id)
|
||||||
|
|
||||||
this->interface_id = interface_id;
|
this->interface_id = interface_id;
|
||||||
|
|
||||||
this->coap_service_id = coap_service_initialize(this->interface_id, THREAD_MANAGEMENT_PORT, COAP_SERVICE_OPTIONS_NONE, NULL, NULL);
|
this->coap_service_id = thread_management_server_service_id_get(interface_id);
|
||||||
if (this->coap_service_id < 0) {
|
if (this->coap_service_id < 0) {
|
||||||
tr_error("Thread diagnostic init failed");
|
tr_error("Thread diagnostic init failed");
|
||||||
ns_dyn_mem_free(this);
|
ns_dyn_mem_free(this);
|
||||||
|
@ -556,8 +568,9 @@ int thread_diagnostic_delete(int8_t interface_id)
|
||||||
if (!this) {
|
if (!this) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
coap_service_unregister_uri(this->coap_service_id, THREAD_URI_DIAGNOSTIC_REQUEST);
|
||||||
coap_service_delete(this->coap_service_id);
|
coap_service_unregister_uri(this->coap_service_id, THREAD_URI_DIAGNOSTIC_RESET);
|
||||||
|
coap_service_unregister_uri(this->coap_service_id, THREAD_URI_DIAGNOSTIC_QUERY);
|
||||||
ns_list_remove(&instance_list, this);
|
ns_list_remove(&instance_list, this);
|
||||||
ns_dyn_mem_free(this);
|
ns_dyn_mem_free(this);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -46,19 +46,15 @@ void thread_extension_allocate(protocol_interface_info_entry_t *cur);
|
||||||
void thread_extension_free(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_init(int8_t interface_id, int8_t coap_service_id);
|
||||||
void thread_extension_mtd_service_register(protocol_interface_info_entry_t *cur);
|
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);
|
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);
|
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_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_dua_address_generate(protocol_interface_info_entry_t *cur, const uint8_t *domain_prefix, uint8_t domain_prefix_len);
|
||||||
void thread_extension_aloc_generate(struct protocol_interface_info_entry *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);
|
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_mcast_subscrition_change(protocol_interface_info_entry_t *interface);
|
||||||
void thread_extension_address_registration_trigger(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_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);
|
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_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);
|
void thread_extension_discover_response_tlv_write(uint16_t *data, uint8_t version, uint16_t securityPolicy);
|
||||||
|
@ -70,35 +66,31 @@ uint8_t thread_extension_discover_response_len(protocol_interface_info_entry_t *
|
||||||
uint8_t *thread_extension_discover_response_write(protocol_interface_info_entry_t *cur, uint8_t *ptr);
|
uint8_t *thread_extension_discover_response_write(protocol_interface_info_entry_t *cur, uint8_t *ptr);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#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)
|
||||||
#endif //HAVE_THREAD_ROUTER
|
#endif //HAVE_THREAD_ROUTER
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define thread_extension_allocate(cur)
|
#define thread_extension_allocate(cur) ((void) 0)
|
||||||
#define thread_extension_free(cur)
|
#define thread_extension_free(cur) ((void) 0)
|
||||||
#define thread_extension_init(interface_id,coap_service_id)
|
#define thread_extension_init(interface_id,coap_service_id) ((void) 0)
|
||||||
#define thread_extension_network_prefix_get(interface_id,options_ptr,prefix_ptr,prefix_len) (-1)
|
#define thread_extension_network_data_process(cur) ((void) 0)
|
||||||
#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,refresh_child_entry,duplicate_child_detected)
|
#define thread_extension_address_registration(interface,addr,child_mac64,refresh_child_entry,duplicate_child_detected) ((void) 0)
|
||||||
#define thread_extension_address_generate(cur)
|
#define thread_extension_aloc_generate(cur) ((void) 0)
|
||||||
#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) ((void) 0)
|
||||||
#define thread_extension_mcast_subscrition_change(interface)
|
|
||||||
#define thread_extension_route_set(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) ((void) 0)
|
||||||
#define thread_extension_discover_response_tlv_write(data, version, extension_bit) (data)
|
#define thread_extension_discover_response_tlv_write(data, version, securityPolicy) ((void) 0)
|
||||||
#define thread_extension_service_init(cur) 0
|
#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_addr_ntf_send(cur,destination_address,addr_data_ptr,bbr_status) ((void) 0)
|
||||||
#define thread_extension_context_can_delete(id, servicesPrefix, context_prefix_length) false
|
#define thread_extension_dua_address_generate(cur, domain_prefix, domain_prefix_len) ((void) 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -52,10 +52,12 @@ int8_t thread_extension_bbr_init(int8_t interface_id, int8_t backbone_interface_
|
||||||
void thread_extension_bbr_delete(int8_t interface_id);
|
void thread_extension_bbr_delete(int8_t interface_id);
|
||||||
bool thread_extension_bbr_nd_query_process(protocol_interface_info_entry_t *cur, const uint8_t *target_addr, uint16_t rloc);
|
bool thread_extension_bbr_nd_query_process(protocol_interface_info_entry_t *cur, const uint8_t *target_addr, uint16_t rloc);
|
||||||
void thread_extension_bbr_seconds_timer(int8_t interface_id, uint32_t seconds);
|
void thread_extension_bbr_seconds_timer(int8_t interface_id, uint32_t seconds);
|
||||||
|
int thread_extension_bbr_sequence_number_set(int8_t interface_id, uint8_t seq_number);
|
||||||
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);
|
int thread_extension_bbr_prefix_set(int8_t interface_id, uint8_t *prefix);
|
||||||
|
void thread_extension_bbr_old_partition_data_clean(int8_t interface_id);
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -67,7 +69,9 @@ int thread_extension_bbr_prefix_set(int8_t interface_id, uint8_t *prefix);
|
||||||
#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_sequence_number_set(interface_id, seq_number) (-1)
|
||||||
#define thread_extension_bbr_prefix_set(interface_id, prefix) 0
|
#define thread_extension_bbr_prefix_set(interface_id, prefix) 0
|
||||||
|
#define thread_extension_bbr_old_partition_data_clean(interface_id)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -45,6 +45,8 @@ extern "C" {
|
||||||
#define thread_extension_bootstrap_thread_name_length_get(cur) (0)
|
#define thread_extension_bootstrap_thread_name_length_get(cur) (0)
|
||||||
#define thread_extension_bootstrap_thread_name_ptr_get(cur) (NULL)
|
#define thread_extension_bootstrap_thread_name_ptr_get(cur) (NULL)
|
||||||
#define thread_extension_bootstrap_network_certificate_enable(cur, coap_service_id) (NULL)
|
#define thread_extension_bootstrap_network_certificate_enable(cur, coap_service_id) (NULL)
|
||||||
|
#define thread_extension_bootstrap_reenrollment_start(cur, service_id, pbbr_addr) (-1)
|
||||||
|
#define thread_extension_bootstrap_network_reattach(interface_id, timeout) (-1)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,11 +121,11 @@ static void thread_network_data_clean(protocol_interface_info_entry_t *cur)
|
||||||
|
|
||||||
static void thread_merge_prepare(protocol_interface_info_entry_t *cur)
|
static void thread_merge_prepare(protocol_interface_info_entry_t *cur)
|
||||||
{
|
{
|
||||||
|
thread_partition_data_purge(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);
|
||||||
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_DUA_HOST, NULL);
|
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;
|
||||||
}
|
}
|
||||||
|
@ -305,6 +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_tlv_info_t addressRegisteredTlv;
|
||||||
mac_neighbor_table_entry_t *entry_temp;
|
mac_neighbor_table_entry_t *entry_temp;
|
||||||
bool new_entry_created;
|
bool new_entry_created;
|
||||||
|
|
||||||
|
@ -320,6 +321,7 @@ static int thread_end_device_synch_response_validate(protocol_interface_info_ent
|
||||||
// Address
|
// Address
|
||||||
// MLE_TYPE_SRC_ADDRESS
|
// MLE_TYPE_SRC_ADDRESS
|
||||||
// MLE_TYPE_LEADER_DATA
|
// MLE_TYPE_LEADER_DATA
|
||||||
|
// MLE_TYPE_ADDRESS_REGISTRATION
|
||||||
if (!mle_tlv_read_8_bit_tlv(MLE_TYPE_MODE, ptr, data_length, &mode) ||
|
if (!mle_tlv_read_8_bit_tlv(MLE_TYPE_MODE, ptr, data_length, &mode) ||
|
||||||
!mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, ptr, data_length, &srcAddress) ||
|
!mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, ptr, data_length, &srcAddress) ||
|
||||||
!mle_tlv_read_16_bit_tlv(MLE_TYPE_ADDRESS16, ptr, data_length, &address16) ||
|
!mle_tlv_read_16_bit_tlv(MLE_TYPE_ADDRESS16, ptr, data_length, &address16) ||
|
||||||
|
@ -329,6 +331,25 @@ static int thread_end_device_synch_response_validate(protocol_interface_info_ent
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(mode & THREAD_DEVICE_FED)) {
|
||||||
|
// check for presence of Address registration TLV for MTDs
|
||||||
|
if (!mle_tlv_read_tlv(MLE_TYPE_ADDRESS_REGISTRATION, ptr, data_length, &addressRegisteredTlv) ||
|
||||||
|
(addressRegisteredTlv.tlvLen == 0)) {
|
||||||
|
tr_debug("MTD missed address registration TLV - reattach");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the source address is a router address
|
||||||
|
if (!thread_is_router_addr(srcAddress)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the address16 is a valid child address
|
||||||
|
if (!thread_addr_is_child(srcAddress, address16)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
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
|
// if learning key sequence from link sync actual guard timer value is not known
|
||||||
|
@ -1103,7 +1124,7 @@ static int thread_attach_child_id_request_build(protocol_interface_info_entry_t
|
||||||
|
|
||||||
//Add ML-EID
|
//Add ML-EID
|
||||||
if ((mode & MLE_FFD_DEV) == 0) {
|
if ((mode & MLE_FFD_DEV) == 0) {
|
||||||
ptr = thread_address_registration_tlv_write(ptr, cur);
|
ptr = thread_ml_address_tlv_write(ptr,cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
reqTlvCnt = 2;
|
reqTlvCnt = 2;
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#include "thread_management_if.h"
|
#include "thread_management_if.h"
|
||||||
#include "thread_common.h"
|
#include "thread_common.h"
|
||||||
#include "thread_bootstrap.h"
|
#include "thread_bootstrap.h"
|
||||||
|
#include "thread_router_bootstrap.h"
|
||||||
#include "thread_network_synch.h"
|
#include "thread_network_synch.h"
|
||||||
#include "thread_network_data_lib.h"
|
#include "thread_network_data_lib.h"
|
||||||
#include "thread_joiner_application.h"
|
#include "thread_joiner_application.h"
|
||||||
|
@ -1140,7 +1141,7 @@ void thread_joiner_pending_config_activate(int8_t interface_id)
|
||||||
this->active_configuration_ptr->timestamp = pending_active_timestamp;
|
this->active_configuration_ptr->timestamp = pending_active_timestamp;
|
||||||
// All information is copied from old configuration so if configuration is corrupt we dont change anything.
|
// All information is copied from old configuration so if configuration is corrupt we dont change anything.
|
||||||
this->pending_configuration_ptr = NULL;
|
this->pending_configuration_ptr = NULL;
|
||||||
(void)thread_nvm_store_pending_configuration_remove();
|
thread_nvm_store_pending_configuration_remove();
|
||||||
configuration_set_copy_mandatory(this->active_configuration_ptr, this->old_active_configuration_ptr);
|
configuration_set_copy_mandatory(this->active_configuration_ptr, this->old_active_configuration_ptr);
|
||||||
link_configuration_update(this->configuration_ptr,this->active_configuration_ptr->data, this->active_configuration_ptr->length);
|
link_configuration_update(this->configuration_ptr,this->active_configuration_ptr->data, this->active_configuration_ptr->length);
|
||||||
link_configuration_trace(this->configuration_ptr);
|
link_configuration_trace(this->configuration_ptr);
|
||||||
|
@ -1922,6 +1923,8 @@ int thread_joiner_application_update_configuration(uint8_t interface_id, uint8_t
|
||||||
}
|
}
|
||||||
thread_meshcop_tlv_data_get_uint64(msg_ptr, msg_len, MESHCOP_TLV_ACTIVE_TIME_STAMP, &this->active_configuration_ptr->timestamp);
|
thread_meshcop_tlv_data_get_uint64(msg_ptr, msg_len, MESHCOP_TLV_ACTIVE_TIME_STAMP, &this->active_configuration_ptr->timestamp);
|
||||||
link_configuration_update(this->configuration_ptr,msg_ptr,msg_len);
|
link_configuration_update(this->configuration_ptr,msg_ptr,msg_len);
|
||||||
|
// allow 5 seconds delay before state change for data response propagation
|
||||||
|
thread_router_bootstrap_delay_reed_jitter(interface_id, 5);
|
||||||
ns_dyn_mem_free(configuration_ptr);
|
ns_dyn_mem_free(configuration_ptr);
|
||||||
thread_joiner_application_configuration_nvm_save(interface_id);
|
thread_joiner_application_configuration_nvm_save(interface_id);
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,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_bootstrap.h"
|
#include "6LoWPAN/Thread/thread_bootstrap.h"
|
||||||
#include "6LoWPAN/Thread/thread_dhcpv6_client.h"
|
#include "DHCPv6_client/dhcpv6_client_api.h"
|
||||||
#include "6LoWPAN/Thread/thread_discovery.h"
|
#include "6LoWPAN/Thread/thread_discovery.h"
|
||||||
#include "6LoWPAN/Thread/thread_joiner_application.h"
|
#include "6LoWPAN/Thread/thread_joiner_application.h"
|
||||||
#include "6LoWPAN/Thread/thread_network_data_lib.h"
|
#include "6LoWPAN/Thread/thread_network_data_lib.h"
|
||||||
|
@ -305,7 +305,6 @@ static int thread_leader_service_commissioner_register(int8_t interface_id, uint
|
||||||
protocol_interface_info_entry_t *cur;
|
protocol_interface_info_entry_t *cur;
|
||||||
link_configuration_s *linkConfiguration;
|
link_configuration_s *linkConfiguration;
|
||||||
|
|
||||||
tr_debug("Register interface %d commissioner: %s", interface_id, trace_ipv6(border_router_address));
|
|
||||||
|
|
||||||
linkConfiguration = thread_joiner_application_get_config(interface_id);
|
linkConfiguration = thread_joiner_application_get_config(interface_id);
|
||||||
if (!linkConfiguration) {
|
if (!linkConfiguration) {
|
||||||
|
@ -341,6 +340,13 @@ static int thread_leader_service_commissioner_register(int8_t interface_id, uint
|
||||||
*session_id = cur->thread_info->registered_commissioner.session_id;
|
*session_id = cur->thread_info->registered_commissioner.session_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (memcmp(border_router_address, linkConfiguration->mesh_local_ula_prefix, 8) == 0 &&
|
||||||
|
memcmp(border_router_address + 8, ADDR_SHORT_ADR_SUFFIC, 6) == 0 &&
|
||||||
|
border_router_address[14] == 0xfc) {
|
||||||
|
// source address is ALOC
|
||||||
|
common_write_16_bit(cur->thread_info->routerShortAddress, &border_router_address[14]);
|
||||||
|
}
|
||||||
|
tr_debug("Register interface %d commissioner: %s", interface_id, trace_ipv6(border_router_address));
|
||||||
//SET Border Router Locator
|
//SET Border Router Locator
|
||||||
memcpy(cur->thread_info->registered_commissioner.border_router_address, border_router_address, 16);
|
memcpy(cur->thread_info->registered_commissioner.border_router_address, border_router_address, 16);
|
||||||
cur->thread_info->registered_commissioner.commissioner_valid = true;
|
cur->thread_info->registered_commissioner.commissioner_valid = true;
|
||||||
|
@ -1295,7 +1301,7 @@ static int thread_leader_service_leader_init(protocol_interface_info_entry_t *cu
|
||||||
thread_routing_free(&thread_info->routing);
|
thread_routing_free(&thread_info->routing);
|
||||||
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);
|
||||||
thread_dhcp_client_delete(cur->id);
|
dhcp_client_delete(cur->id);
|
||||||
thread_nd_service_delete(cur->id);
|
thread_nd_service_delete(cur->id);
|
||||||
mpl_clear_realm_scope_seeds(cur);
|
mpl_clear_realm_scope_seeds(cur);
|
||||||
ipv6_neighbour_cache_flush(&cur->ipv6_neighbour_cache);
|
ipv6_neighbour_cache_flush(&cur->ipv6_neighbour_cache);
|
||||||
|
@ -1352,7 +1358,6 @@ static void thread_leader_service_interface_setup_activate(protocol_interface_in
|
||||||
cur->lowpan_address_mode = NET_6LOWPAN_GP16_ADDRESS;
|
cur->lowpan_address_mode = NET_6LOWPAN_GP16_ADDRESS;
|
||||||
thread_bootstrap_update_ml16_address(cur, cur->thread_info->routerShortAddress);
|
thread_bootstrap_update_ml16_address(cur, cur->thread_info->routerShortAddress);
|
||||||
thread_generate_ml64_address(cur);
|
thread_generate_ml64_address(cur);
|
||||||
thread_extension_address_generate(cur);
|
|
||||||
thread_bootstrap_routing_activate(cur);
|
thread_bootstrap_routing_activate(cur);
|
||||||
thread_routing_update_id_set(cur, private->maskSeq, private->master_router_id_mask);
|
thread_routing_update_id_set(cur, private->maskSeq, private->master_router_id_mask);
|
||||||
thread_routing_activate(&cur->thread_info->routing);
|
thread_routing_activate(&cur->thread_info->routing);
|
||||||
|
|
|
@ -287,7 +287,6 @@ int thread_management_register(int8_t interface_id)
|
||||||
this->get_response_cb_ptr = NULL;
|
this->get_response_cb_ptr = NULL;
|
||||||
|
|
||||||
if (thread_management_get_remote_addr(this)) {
|
if (thread_management_get_remote_addr(this)) {
|
||||||
ns_dyn_mem_free(this);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "6LoWPAN/Thread/thread_constants.h"
|
#include "6LoWPAN/Thread/thread_constants.h"
|
||||||
#include "6LoWPAN/Thread/thread_tmfcop_lib.h"
|
#include "6LoWPAN/Thread/thread_tmfcop_lib.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_joiner_application.h"
|
#include "6LoWPAN/Thread/thread_joiner_application.h"
|
||||||
#include "6LoWPAN/Thread/thread_network_data_lib.h"
|
#include "6LoWPAN/Thread/thread_network_data_lib.h"
|
||||||
#include "6LoWPAN/Thread/thread_bootstrap.h"
|
#include "6LoWPAN/Thread/thread_bootstrap.h"
|
||||||
|
@ -58,9 +59,8 @@ typedef struct thread_management {
|
||||||
thread_management_client_router_id_cb *router_id_release_cb_ptr;
|
thread_management_client_router_id_cb *router_id_release_cb_ptr;
|
||||||
thread_management_client_network_data_set_cb *network_data_set_cb_ptr;
|
thread_management_client_network_data_set_cb *network_data_set_cb_ptr;
|
||||||
thread_management_client_network_data_set_cb *neighbor_discovery_cb_ptr;
|
thread_management_client_network_data_set_cb *neighbor_discovery_cb_ptr;
|
||||||
uint16_t coap_asd_msg_id; // COAP msg id for a/sd
|
|
||||||
int8_t interface_id;
|
int8_t interface_id;
|
||||||
int8_t coap_service_id;
|
int8_t coap_service_id; // COAP service ID from Management server
|
||||||
ns_list_link_t link;
|
ns_list_link_t link;
|
||||||
} thread_management_t;
|
} thread_management_t;
|
||||||
|
|
||||||
|
@ -150,9 +150,12 @@ void thread_management_client_init(int8_t interface_id)
|
||||||
this->neighbor_discovery_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;
|
|
||||||
//TODO: Check if to use ephemeral port here
|
//TODO: Check if to use ephemeral port here
|
||||||
this->coap_service_id = coap_service_initialize(this->interface_id, THREAD_MANAGEMENT_PORT, COAP_SERVICE_OPTIONS_NONE, NULL, NULL);
|
|
||||||
|
this->coap_service_id = thread_management_server_service_id_get(interface_id);
|
||||||
|
if (this->coap_service_id < 0) {
|
||||||
|
tr_error("Failed to init COAP service");
|
||||||
|
}
|
||||||
ns_list_add_to_start(&instance_list, this);
|
ns_list_add_to_start(&instance_list, this);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -165,19 +168,10 @@ void thread_management_client_delete(int8_t interface_id)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
coap_service_delete(this->coap_service_id);
|
|
||||||
ns_list_remove(&instance_list, this);
|
ns_list_remove(&instance_list, this);
|
||||||
ns_dyn_mem_free(this);
|
ns_dyn_mem_free(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int8_t thread_management_client_service_id_get(int8_t interface_id)
|
|
||||||
{
|
|
||||||
thread_management_t *this = thread_management_find(interface_id);
|
|
||||||
if (!this) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return this->coap_service_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
int thread_management_client_router_id_get(int8_t interface_id, uint8_t mac[8], uint16_t router_id, thread_management_client_router_id_cb *id_cb, uint8_t status)
|
int thread_management_client_router_id_get(int8_t interface_id, uint8_t mac[8], uint16_t router_id, thread_management_client_router_id_cb *id_cb, uint8_t status)
|
||||||
{
|
{
|
||||||
|
@ -251,8 +245,6 @@ static int thread_management_client_register_cb(int8_t service_id, uint8_t sourc
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->coap_asd_msg_id = 0; //clear the coap message id
|
|
||||||
|
|
||||||
if (this->network_data_set_cb_ptr) {
|
if (this->network_data_set_cb_ptr) {
|
||||||
if (response_ptr) {
|
if (response_ptr) {
|
||||||
// If we get response status is OK
|
// If we get response status is OK
|
||||||
|
@ -281,10 +273,8 @@ int thread_management_client_network_data_register(int8_t interface_id, uint8_t
|
||||||
this->network_data_set_cb_ptr = set_cb;
|
this->network_data_set_cb_ptr = set_cb;
|
||||||
tr_debug("thread network data send to %s", trace_ipv6(destination));
|
tr_debug("thread network data send to %s", trace_ipv6(destination));
|
||||||
|
|
||||||
this->coap_asd_msg_id = coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, destination, THREAD_MANAGEMENT_PORT,
|
return coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, destination, THREAD_MANAGEMENT_PORT,
|
||||||
COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_NETWORK_DATA, COAP_CT_OCTET_STREAM, data_ptr, data_len, thread_management_client_register_cb);
|
COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_NETWORK_DATA, COAP_CT_OCTET_STREAM, data_ptr, data_len, thread_management_client_register_cb);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_management_client_network_data_unregister(int8_t interface_id, uint16_t rloc16)
|
int thread_management_client_network_data_unregister(int8_t interface_id, uint16_t rloc16)
|
||||||
|
@ -306,8 +296,8 @@ int thread_management_client_network_data_unregister(int8_t interface_id, uint16
|
||||||
|
|
||||||
tr_debug("thread network data unregister");
|
tr_debug("thread network data unregister");
|
||||||
|
|
||||||
this->coap_asd_msg_id = coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, destination, THREAD_MANAGEMENT_PORT,
|
coap_service_request_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, destination, THREAD_MANAGEMENT_PORT,
|
||||||
COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_NETWORK_DATA, COAP_CT_OCTET_STREAM, payload, ptr - payload, thread_management_client_register_cb);
|
COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_NETWORK_DATA, COAP_CT_OCTET_STREAM, payload, ptr - payload, thread_management_client_register_cb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,7 +606,18 @@ void thread_management_client_proactive_an(int8_t interface_id, const uint8_t ad
|
||||||
payload, ptr - payload, thread_management_client_proactive_an_cb);
|
payload, ptr - payload, thread_management_client_proactive_an_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_management_client_pending_coap_request_kill(int8_t interface_id)
|
void thread_management_client_coap_message_delete(int8_t interface_id, uint16_t coap_message_id)
|
||||||
|
{
|
||||||
|
thread_management_t *this = thread_management_find(interface_id);
|
||||||
|
|
||||||
|
if (!this) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
coap_service_request_delete(this->coap_service_id, coap_message_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_management_client_old_partition_data_clean(int8_t interface_id)
|
||||||
{
|
{
|
||||||
thread_management_t *this = thread_management_find(interface_id);
|
thread_management_t *this = thread_management_find(interface_id);
|
||||||
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);
|
||||||
|
@ -625,17 +626,9 @@ void thread_management_client_pending_coap_request_kill(int8_t interface_id)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur->thread_info->localServerDataBase.publish_active = false;
|
cur->thread_info->localServerDataBase.publish_coap_req_id = 0;
|
||||||
|
cur->thread_info->routerIdRequested = false;
|
||||||
if (this->coap_asd_msg_id != 0) {
|
coap_service_request_delete_by_service_id(this->coap_service_id);
|
||||||
coap_service_request_delete(this->coap_service_id, this->coap_asd_msg_id);
|
|
||||||
this->coap_asd_msg_id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cur->thread_info->routerIdReqCoapID != 0) {
|
|
||||||
coap_service_request_delete(this->coap_service_id, cur->thread_info->routerIdReqCoapID);
|
|
||||||
cur->thread_info->routerIdReqCoapID = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -65,12 +65,6 @@ void thread_management_client_init(int8_t interface_id);
|
||||||
*/
|
*/
|
||||||
void thread_management_client_delete(int8_t interface_id);
|
void thread_management_client_delete(int8_t interface_id);
|
||||||
|
|
||||||
/** Get service id of management service.
|
|
||||||
*
|
|
||||||
* When using Coap Management port service this service is the only instance used to make client transactions.
|
|
||||||
*/
|
|
||||||
int8_t thread_management_client_service_id_get(int8_t interface_id);
|
|
||||||
|
|
||||||
/** Router id handler callback.
|
/** Router id handler callback.
|
||||||
*
|
*
|
||||||
* callback to inform when new router id is received from leader.
|
* callback to inform when new router id is received from leader.
|
||||||
|
@ -213,9 +207,20 @@ int thread_management_client_provision_request(int8_t interface_id, uint8_t *dst
|
||||||
*/
|
*/
|
||||||
void thread_management_client_proactive_an(int8_t interface_id, const uint8_t address[16], const uint16_t rloc, const uint8_t ml_eid[8], const uint8_t dst_addr[16]);
|
void thread_management_client_proactive_an(int8_t interface_id, const uint8_t address[16], const uint16_t rloc, const uint8_t ml_eid[8], const uint8_t dst_addr[16]);
|
||||||
|
|
||||||
/** Kill pending COAP requests.
|
/** Delete COAP message .
|
||||||
|
*
|
||||||
|
* Delete COAP message that is sent to COAP service.
|
||||||
|
*
|
||||||
|
* \param interface_id interface id of this Thread instance.
|
||||||
|
* \param coap_message_id COAP message to be deleted.
|
||||||
|
*/
|
||||||
|
void thread_management_client_coap_message_delete(int8_t interface_id, uint16_t coap_message_id);
|
||||||
|
|
||||||
|
/** Clear old partition data.
|
||||||
|
*
|
||||||
|
* Clear data related to old partition, like pending COAP transactions.
|
||||||
*
|
*
|
||||||
* \param interface_id interface id of this Thread instance.
|
* \param interface_id interface id of this Thread instance.
|
||||||
*/
|
*/
|
||||||
void thread_management_client_pending_coap_request_kill(int8_t interface_id);
|
void thread_management_client_old_partition_data_clean(int8_t interface_id);
|
||||||
#endif /* THREAD_MANAGEMENT_CLIENT_H_ */
|
#endif /* THREAD_MANAGEMENT_CLIENT_H_ */
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
#include "6LoWPAN/Thread/thread_leader_service.h"
|
#include "6LoWPAN/Thread/thread_leader_service.h"
|
||||||
#include "6LoWPAN/Thread/thread_nd.h"
|
#include "6LoWPAN/Thread/thread_nd.h"
|
||||||
#include "thread_diagnostic.h"
|
#include "thread_diagnostic.h"
|
||||||
#include "6LoWPAN/Thread/thread_dhcpv6_client.h"
|
#include "DHCPv6_client/dhcpv6_client_api.h"
|
||||||
#include "6LoWPAN/Thread/thread_discovery.h"
|
#include "6LoWPAN/Thread/thread_discovery.h"
|
||||||
#include "6LoWPAN/Thread/thread_network_synch.h"
|
#include "6LoWPAN/Thread/thread_network_synch.h"
|
||||||
#include "6LoWPAN/Thread/thread_management_internal.h"
|
#include "6LoWPAN/Thread/thread_management_internal.h"
|
||||||
|
@ -63,6 +63,7 @@
|
||||||
#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/Thread/thread_extension.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_bbr_api_internal.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"
|
||||||
|
@ -71,9 +72,8 @@
|
||||||
#include "thread_commissioning_if.h"
|
#include "thread_commissioning_if.h"
|
||||||
#include "shalib.h"
|
#include "shalib.h"
|
||||||
#include "Common_Protocols/icmpv6.h"
|
#include "Common_Protocols/icmpv6.h"
|
||||||
#include "libDHCPv6/libDHCPv6.h"
|
|
||||||
#include "libDHCPv6/libDHCPv6_server.h"
|
|
||||||
#include "DHCPv6_Server/DHCPv6_server_service.h"
|
#include "DHCPv6_Server/DHCPv6_server_service.h"
|
||||||
|
#include "6LoWPAN/Thread/thread_dhcpv6_server.h"
|
||||||
#include "Service_Libs/mle_service/mle_service_api.h"
|
#include "Service_Libs/mle_service/mle_service_api.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"
|
||||||
|
@ -606,7 +606,7 @@ int thread_management_get_ml_prefix_112(int8_t interface_id, uint8_t *prefix_ptr
|
||||||
*/
|
*/
|
||||||
int thread_dhcpv6_server_add(int8_t interface_id, uint8_t *prefix_ptr, uint32_t max_client_cnt, bool stableData)
|
int thread_dhcpv6_server_add(int8_t interface_id, uint8_t *prefix_ptr, uint32_t max_client_cnt, bool stableData)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_DHCPV6_SERVER
|
#if defined(HAVE_THREAD) && defined(HAVE_DHCPV6_SERVER)
|
||||||
protocol_interface_info_entry_t *cur;
|
protocol_interface_info_entry_t *cur;
|
||||||
thread_prefix_tlv_t prefixTlv;
|
thread_prefix_tlv_t prefixTlv;
|
||||||
thread_border_router_tlv_entry_t service;
|
thread_border_router_tlv_entry_t service;
|
||||||
|
@ -622,7 +622,7 @@ int thread_dhcpv6_server_add(int8_t interface_id, uint8_t *prefix_ptr, uint32_t
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DHCPv6_server_service_init(interface_id, prefix_ptr, cur->mac, DHCPV6_DUID_HARDWARE_EUI64_TYPE) != 0) {
|
if (thread_dhcp6_server_init(interface_id, prefix_ptr, cur->mac, THREAD_MIN_PREFIX_LIFETIME) != 0) {
|
||||||
tr_warn("SerVER alloc fail");
|
tr_warn("SerVER alloc fail");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -637,14 +637,9 @@ int thread_dhcpv6_server_add(int8_t interface_id, uint8_t *prefix_ptr, uint32_t
|
||||||
service.P_on_mesh = true;
|
service.P_on_mesh = true;
|
||||||
service.stableData = stableData;
|
service.stableData = stableData;
|
||||||
|
|
||||||
//SET Timeout
|
|
||||||
DHCPv6_server_service_set_address_validlifetime(interface_id, prefix_ptr, THREAD_MIN_PREFIX_LIFETIME);
|
|
||||||
|
|
||||||
// SET maximum number of accepted clients
|
// SET maximum number of accepted clients
|
||||||
DHCPv6_server_service_set_max_clients_accepts_count(interface_id, prefix_ptr, max_client_cnt);
|
DHCPv6_server_service_set_max_clients_accepts_count(interface_id, prefix_ptr, max_client_cnt);
|
||||||
|
|
||||||
//Enable Mapping
|
|
||||||
//DHCPv6_server_service_set_gua_address_mapping(interface_id,prefix_ptr, true, cur->thread_info->threadPrivatePrefixInfo.ulaPrefix);
|
|
||||||
tr_debug("GUA server Generate OK");
|
tr_debug("GUA server Generate OK");
|
||||||
memcpy(ptr, prefix_ptr, 8);
|
memcpy(ptr, prefix_ptr, 8);
|
||||||
memset(ptr + 8, 0, 8);
|
memset(ptr + 8, 0, 8);
|
||||||
|
@ -665,7 +660,7 @@ int thread_dhcpv6_server_add(int8_t interface_id, uint8_t *prefix_ptr, uint32_t
|
||||||
|
|
||||||
int thread_dhcpv6_server_set_lifetime(int8_t interface_id, uint8_t *prefix_ptr, uint32_t valid_lifetime)
|
int thread_dhcpv6_server_set_lifetime(int8_t interface_id, uint8_t *prefix_ptr, uint32_t valid_lifetime)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_DHCPV6_SERVER
|
#if defined(HAVE_THREAD) && defined(HAVE_DHCPV6_SERVER)
|
||||||
if (!prefix_ptr) {
|
if (!prefix_ptr) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -681,7 +676,7 @@ int thread_dhcpv6_server_set_lifetime(int8_t interface_id, uint8_t *prefix_ptr,
|
||||||
|
|
||||||
int thread_dhcpv6_server_set_max_client(int8_t interface_id, uint8_t *prefix_ptr, uint32_t max_client_count)
|
int thread_dhcpv6_server_set_max_client(int8_t interface_id, uint8_t *prefix_ptr, uint32_t max_client_count)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_DHCPV6_SERVER
|
#if defined(HAVE_THREAD) && defined(HAVE_DHCPV6_SERVER)
|
||||||
if (!prefix_ptr) {
|
if (!prefix_ptr) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -697,7 +692,7 @@ int thread_dhcpv6_server_set_max_client(int8_t interface_id, uint8_t *prefix_ptr
|
||||||
|
|
||||||
int thread_dhcpv6_server_set_anonymous_addressing(int8_t interface_id, uint8_t *prefix_ptr, bool anonymous)
|
int thread_dhcpv6_server_set_anonymous_addressing(int8_t interface_id, uint8_t *prefix_ptr, bool anonymous)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_DHCPV6_SERVER
|
#if defined(HAVE_THREAD) && defined(HAVE_DHCPV6_SERVER)
|
||||||
if (!prefix_ptr) {
|
if (!prefix_ptr) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -715,7 +710,7 @@ int thread_dhcpv6_server_set_anonymous_addressing(int8_t interface_id, uint8_t *
|
||||||
|
|
||||||
int thread_dhcpv6_server_delete(int8_t interface_id, uint8_t *prefix_ptr)
|
int thread_dhcpv6_server_delete(int8_t interface_id, uint8_t *prefix_ptr)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_DHCPV6_SERVER
|
#if defined(HAVE_THREAD) && defined(HAVE_DHCPV6_SERVER)
|
||||||
uint8_t temp[16];
|
uint8_t temp[16];
|
||||||
protocol_interface_info_entry_t *cur;
|
protocol_interface_info_entry_t *cur;
|
||||||
thread_prefix_tlv_t prefixTlv;
|
thread_prefix_tlv_t prefixTlv;
|
||||||
|
|
|
@ -100,6 +100,9 @@ typedef struct announce {
|
||||||
typedef struct thread_management_server {
|
typedef struct thread_management_server {
|
||||||
scan_query_t *scan_ptr;
|
scan_query_t *scan_ptr;
|
||||||
announce_t *announce_ptr;
|
announce_t *announce_ptr;
|
||||||
|
timeout_t *join_ent_timer;
|
||||||
|
uint8_t destination_address[16];
|
||||||
|
uint8_t one_time_key[16];
|
||||||
uint16_t relay_port_joiner;
|
uint16_t relay_port_joiner;
|
||||||
uint16_t external_commissioner_port;
|
uint16_t external_commissioner_port;
|
||||||
int8_t interface_id;
|
int8_t interface_id;
|
||||||
|
@ -994,7 +997,6 @@ error_exit:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void thread_announce_timeout_cb(void* arg)
|
static void thread_announce_timeout_cb(void* arg)
|
||||||
{
|
{
|
||||||
link_configuration_s *linkConfiguration;
|
link_configuration_s *linkConfiguration;
|
||||||
|
@ -1132,6 +1134,9 @@ int thread_management_server_init(int8_t interface_id)
|
||||||
this->relay_port_joiner = 0;
|
this->relay_port_joiner = 0;
|
||||||
this->scan_ptr = NULL;
|
this->scan_ptr = NULL;
|
||||||
this->announce_ptr = NULL;
|
this->announce_ptr = NULL;
|
||||||
|
this->join_ent_timer = NULL;
|
||||||
|
memset(this->destination_address,0,16);
|
||||||
|
memset(this->one_time_key,0,16);
|
||||||
this->external_commissioner_port = THREAD_COMMISSIONING_PORT;
|
this->external_commissioner_port = THREAD_COMMISSIONING_PORT;
|
||||||
|
|
||||||
#ifdef HAVE_THREAD_ROUTER
|
#ifdef HAVE_THREAD_ROUTER
|
||||||
|
@ -1147,13 +1152,13 @@ int thread_management_server_init(int8_t interface_id)
|
||||||
#endif
|
#endif
|
||||||
this->coap_service_id = coap_service_initialize(this->interface_id, THREAD_MANAGEMENT_PORT, COAP_SERVICE_OPTIONS_NONE, NULL, NULL);
|
this->coap_service_id = coap_service_initialize(this->interface_id, THREAD_MANAGEMENT_PORT, COAP_SERVICE_OPTIONS_NONE, NULL, NULL);
|
||||||
if (this->coap_service_id < 0) {
|
if (this->coap_service_id < 0) {
|
||||||
tr_warn("Thread management init failed");
|
tr_error("Thread management init failed");
|
||||||
ns_dyn_mem_free(this);
|
ns_dyn_mem_free(this);
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_THREAD_ROUTER
|
#ifdef HAVE_THREAD_ROUTER
|
||||||
if (thread_leader_service_init(interface_id, this->coap_service_id) != 0) {
|
if (thread_leader_service_init(interface_id, this->coap_service_id) != 0) {
|
||||||
tr_warn("Thread leader service init failed");
|
tr_error("Thread leader service init failed");
|
||||||
ns_dyn_mem_free(this);
|
ns_dyn_mem_free(this);
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
@ -1191,6 +1196,7 @@ void thread_management_server_delete(int8_t interface_id)
|
||||||
coap_service_unregister_uri(this->coap_service_id, THREAD_URI_MANAGEMENT_GET);
|
coap_service_unregister_uri(this->coap_service_id, THREAD_URI_MANAGEMENT_GET);
|
||||||
coap_service_unregister_uri(this->coap_service_id, THREAD_URI_MANAGEMENT_SET);
|
coap_service_unregister_uri(this->coap_service_id, THREAD_URI_MANAGEMENT_SET);
|
||||||
coap_service_delete(this->coap_service_id);
|
coap_service_delete(this->coap_service_id);
|
||||||
|
|
||||||
ns_list_remove(&instance_list, this);
|
ns_list_remove(&instance_list, this);
|
||||||
if (this->announce_ptr) {
|
if (this->announce_ptr) {
|
||||||
if (this->announce_ptr->timer) {
|
if (this->announce_ptr->timer) {
|
||||||
|
@ -1215,6 +1221,15 @@ void thread_management_server_delete(int8_t interface_id)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int8_t thread_management_server_service_id_get(int8_t interface_id)
|
||||||
|
{
|
||||||
|
thread_management_server_t *this = thread_management_server_find(interface_id);
|
||||||
|
if (!this) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return this->coap_service_id;
|
||||||
|
}
|
||||||
|
|
||||||
int8_t thread_management_server_interface_id_get(int8_t coap_service_id)
|
int8_t thread_management_server_interface_id_get(int8_t coap_service_id)
|
||||||
{
|
{
|
||||||
thread_management_server_t *this = thread_management_find_by_service(coap_service_id);
|
thread_management_server_t *this = thread_management_find_by_service(coap_service_id);
|
||||||
|
@ -1312,6 +1327,19 @@ static int thread_management_server_entrust_send(thread_management_server_t *thi
|
||||||
ns_dyn_mem_free(response_ptr);
|
ns_dyn_mem_free(response_ptr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void thread_join_ent_timeout_cb(void *arg)
|
||||||
|
{
|
||||||
|
thread_management_server_t *this = arg;
|
||||||
|
if(!this || !this->join_ent_timer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->join_ent_timer = NULL;
|
||||||
|
thread_management_server_entrust_send(this, this->destination_address, this->one_time_key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void joiner_router_recv_commission_msg(void *cb_res)
|
void joiner_router_recv_commission_msg(void *cb_res)
|
||||||
{
|
{
|
||||||
socket_callback_t *sckt_data = 0;
|
socket_callback_t *sckt_data = 0;
|
||||||
|
@ -1412,7 +1440,13 @@ static int thread_management_server_relay_tx_cb(int8_t service_id, uint8_t sourc
|
||||||
if (0 < thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_JOINER_ROUTER_KEK, &kek_ptr)) {
|
if (0 < thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_JOINER_ROUTER_KEK, &kek_ptr)) {
|
||||||
// KEK present in relay set pairwise key and send entrust
|
// KEK present in relay set pairwise key and send entrust
|
||||||
tr_debug("Kek received");
|
tr_debug("Kek received");
|
||||||
thread_management_server_entrust_send(this, destination_address.address, kek_ptr);
|
if (this->join_ent_timer) {
|
||||||
|
eventOS_timeout_cancel(this->join_ent_timer);
|
||||||
|
thread_management_server_entrust_send(this, this->destination_address, this->one_time_key);
|
||||||
|
}
|
||||||
|
memcpy(this->destination_address, destination_address.address, 16);
|
||||||
|
memcpy(this->one_time_key, kek_ptr, 16);
|
||||||
|
this->join_ent_timer = eventOS_timeout_ms(thread_join_ent_timeout_cb, THREAD_DELAY_JOIN_ENT, this);
|
||||||
}
|
}
|
||||||
tr_debug("Relay TX sendto addr:%s port:%d, length:%d", trace_ipv6(destination_address.address), port, udp_data_len);
|
tr_debug("Relay TX sendto addr:%s port:%d, length:%d", trace_ipv6(destination_address.address), port, udp_data_len);
|
||||||
thci_trace("joinerrouterJoinerDataRelayedOutbound");
|
thci_trace("joinerrouterJoinerDataRelayedOutbound");
|
||||||
|
|
|
@ -99,6 +99,13 @@ int thread_management_server_joiner_router_init(int8_t interface_id);
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void thread_management_server_joiner_router_deinit(int8_t interface_id);
|
void thread_management_server_joiner_router_deinit(int8_t interface_id);
|
||||||
|
|
||||||
|
/** Get service id of management service.
|
||||||
|
*
|
||||||
|
* When using Coap Management port service this service is the only instance used to make client transactions.
|
||||||
|
*/
|
||||||
|
int8_t thread_management_server_service_id_get(int8_t interface_id);
|
||||||
|
|
||||||
int8_t thread_management_server_interface_id_get(int8_t coap_service_id);
|
int8_t thread_management_server_interface_id_get(int8_t coap_service_id);
|
||||||
|
|
||||||
int thread_management_server_commisoner_data_get(int8_t interface_id, thread_management_server_data_t *server_data);
|
int thread_management_server_commisoner_data_get(int8_t interface_id, thread_management_server_data_t *server_data);
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#ifdef HAVE_THREAD
|
#ifdef HAVE_THREAD
|
||||||
|
|
||||||
#include "ns_trace.h"
|
#include "ns_trace.h"
|
||||||
|
#include "string.h"
|
||||||
#include "common_functions.h"
|
#include "common_functions.h"
|
||||||
#include "NWK_INTERFACE/Include/protocol.h"
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
#include <nsdynmemLIB.h>
|
#include <nsdynmemLIB.h>
|
||||||
|
@ -53,6 +54,7 @@
|
||||||
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.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 "Common_Protocols/ipv6.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"
|
||||||
|
@ -699,6 +701,54 @@ static int thread_host_child_update_response_send(protocol_interface_info_entry_
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool thread_address_registration_tlv_search(if_address_entry_t *entry, mle_tlv_info_t *tlv_info)
|
||||||
|
{
|
||||||
|
uint8_t context;
|
||||||
|
uint16_t length = tlv_info->tlvLen;
|
||||||
|
uint8_t *ptr = tlv_info->dataPtr;
|
||||||
|
|
||||||
|
while (length) {
|
||||||
|
context = *ptr++;
|
||||||
|
if (context & 0x80) {
|
||||||
|
if (memcmp(ptr, entry->address + 8, 8) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
ptr += 8;
|
||||||
|
length -= 9;
|
||||||
|
} else {
|
||||||
|
if (memcmp(ptr, entry->address, 16) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
ptr += 16;
|
||||||
|
length -= 17;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool thread_address_registration_tlv_check(protocol_interface_info_entry_t *cur, mle_tlv_info_t *tlv_info)
|
||||||
|
{
|
||||||
|
bool ret_val = true;
|
||||||
|
|
||||||
|
ns_list_foreach_safe(if_address_entry_t, e, &cur->ip_addresses) {
|
||||||
|
if (addr_ipv6_scope(e->address, cur) == IPV6_SCOPE_GLOBAL || (addr_ipv6_scope(e->address, cur) == IPV6_SCOPE_REALM_LOCAL &&
|
||||||
|
!thread_addr_is_mesh_local_16(e->address, cur))) {
|
||||||
|
|
||||||
|
if (thread_address_registration_tlv_search(e, tlv_info) == false) {
|
||||||
|
tr_debug("Address %s registration to parent failed", trace_ipv6(e->address));
|
||||||
|
addr_set_preferred_lifetime(cur, e, 0); // deprecate address
|
||||||
|
ret_val = false;
|
||||||
|
} else if (e->preferred_lifetime == 0) {
|
||||||
|
addr_set_preferred_lifetime(cur, e, 0xffffffff); // set preferred lifetime to infinite
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
static void thread_host_child_update_request_process(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, uint8_t linkMargin)
|
static void thread_host_child_update_request_process(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, uint8_t linkMargin)
|
||||||
{
|
{
|
||||||
thread_leader_data_t leaderData;
|
thread_leader_data_t leaderData;
|
||||||
|
@ -710,6 +760,7 @@ static void thread_host_child_update_request_process(protocol_interface_info_ent
|
||||||
uint64_t pending_timestamp = 0;// means no pending timestamp
|
uint64_t pending_timestamp = 0;// means no pending timestamp
|
||||||
mac_neighbor_table_entry_t *entry_temp;
|
mac_neighbor_table_entry_t *entry_temp;
|
||||||
bool data_request_needed = false;
|
bool data_request_needed = false;
|
||||||
|
mle_tlv_info_t tlv_info = {0};
|
||||||
|
|
||||||
tr_debug("Child update request");
|
tr_debug("Child update request");
|
||||||
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), 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);
|
||||||
|
@ -738,6 +789,11 @@ static void thread_host_child_update_request_process(protocol_interface_info_ent
|
||||||
thread_bootstrap_network_data_update(cur);
|
thread_bootstrap_network_data_update(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check Address Registration TLV
|
||||||
|
if (true == mle_tlv_read_tlv(MLE_TYPE_ADDRESS_REGISTRATION, mle_msg->data_ptr, mle_msg->data_length, &tlv_info)) {
|
||||||
|
thread_address_registration_tlv_check(cur, &tlv_info);
|
||||||
|
}
|
||||||
|
|
||||||
if (thread_info(cur)->thread_leader_data->stableDataVersion != leaderData.stableDataVersion ||
|
if (thread_info(cur)->thread_leader_data->stableDataVersion != leaderData.stableDataVersion ||
|
||||||
thread_info(cur)->thread_leader_data->dataVersion != leaderData.dataVersion) {
|
thread_info(cur)->thread_leader_data->dataVersion != leaderData.dataVersion) {
|
||||||
// version numbers not in sync need to send data request
|
// version numbers not in sync need to send data request
|
||||||
|
@ -776,6 +832,7 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t *
|
||||||
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;
|
||||||
|
mle_tlv_info_t tlv_info = {0};
|
||||||
|
|
||||||
if (cur->thread_info->thread_endnode_parent == NULL) {
|
if (cur->thread_info->thread_endnode_parent == NULL) {
|
||||||
return;
|
return;
|
||||||
|
@ -822,6 +879,10 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t *
|
||||||
tr_debug("Setting child timeout, value=%"PRIu32, timeout);
|
tr_debug("Setting child timeout, value=%"PRIu32, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (true == mle_tlv_read_tlv(MLE_TYPE_ADDRESS_REGISTRATION, mle_msg->data_ptr, mle_msg->data_length, &tlv_info)) {
|
||||||
|
thread_address_registration_tlv_check(cur, &tlv_info);
|
||||||
|
}
|
||||||
|
|
||||||
tr_debug("Keep-Alive -->Respond from Parent");
|
tr_debug("Keep-Alive -->Respond from Parent");
|
||||||
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, timeout);
|
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, timeout);
|
||||||
|
|
||||||
|
|
|
@ -294,7 +294,7 @@ 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);
|
thread_extension_dua_address_generate(cur, ip_addr, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scan IPv6 neighbour cache for registered entries of children */
|
/* Scan IPv6 neighbour cache for registered entries of children */
|
||||||
|
@ -547,8 +547,7 @@ 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 && memcmp(nce_eui64, mac64, 8) != 0)
|
if (neigh->type == IP_NEIGHBOUR_REGISTERED && memcmp(nce_eui64, mac64, 8) != 0) {
|
||||||
{
|
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
#include "6LoWPAN/Thread/thread_joiner_application.h"
|
#include "6LoWPAN/Thread/thread_joiner_application.h"
|
||||||
#include "6LoWPAN/Thread/thread_network_data_lib.h"
|
#include "6LoWPAN/Thread/thread_network_data_lib.h"
|
||||||
#include "6LoWPAN/Thread/thread_network_data_storage.h"
|
#include "6LoWPAN/Thread/thread_network_data_storage.h"
|
||||||
#include "6LoWPAN/Thread/thread_dhcpv6_client.h"
|
#include "DHCPv6_client/dhcpv6_client_api.h"
|
||||||
#include "6LoWPAN/MAC/mac_helper.h"
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
#include "thread_management_if.h"
|
#include "thread_management_if.h"
|
||||||
#include "thread_meshcop_lib.h"
|
#include "thread_meshcop_lib.h"
|
||||||
|
@ -193,6 +193,7 @@ static uint16_t thread_nd_service_border_router_flags_read(thread_network_server
|
||||||
flags |= (cur->P_default_route << THREAD_P_DEF_ROUTE_BIT_MOVE);
|
flags |= (cur->P_default_route << THREAD_P_DEF_ROUTE_BIT_MOVE);
|
||||||
flags |= (cur->P_on_mesh << THREAD_P_ON_MESH_BIT_MOVE);
|
flags |= (cur->P_on_mesh << THREAD_P_ON_MESH_BIT_MOVE);
|
||||||
flags |= (cur->P_nd_dns << THREAD_P_ND_DNS_BIT_MOVE);
|
flags |= (cur->P_nd_dns << THREAD_P_ND_DNS_BIT_MOVE);
|
||||||
|
flags |= (cur->P_res1 << THREAD_P_ND_RES_BIT_MOVE);
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -872,6 +873,7 @@ static int thread_service_data_delete_mark_by_router_id(thread_network_data_serv
|
||||||
|
|
||||||
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)
|
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)
|
||||||
{
|
{
|
||||||
|
(void) id;
|
||||||
int retVal = -1;
|
int retVal = -1;
|
||||||
(void) prefixEntry;
|
(void) prefixEntry;
|
||||||
ns_list_foreach_safe(thread_network_data_context_entry_t, cur, listPtr) {
|
ns_list_foreach_safe(thread_network_data_context_entry_t, cur, listPtr) {
|
||||||
|
@ -881,9 +883,7 @@ static int thread_server_context_clean(int8_t id, thread_network_data_cache_entr
|
||||||
cachePtr->stableUpdatePushed = true;
|
cachePtr->stableUpdatePushed = true;
|
||||||
}
|
}
|
||||||
// Set context lifetime to 0 to delete
|
// Set context lifetime to 0 to delete
|
||||||
if (thread_extension_context_can_delete(id, prefixEntry->servicesPrefix, cur->contextPrefixLength)) {
|
lowpan_context_update(context_list, cur->cid, 0, NULL, 0, true);
|
||||||
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;
|
||||||
|
@ -930,11 +930,18 @@ static bool thread_server_data_clean_by_router_id(thread_network_data_cache_entr
|
||||||
|
|
||||||
if (cur->P_dhcp) {
|
if (cur->P_dhcp) {
|
||||||
tr_debug("Delete DHCPv6 given address");
|
tr_debug("Delete DHCPv6 given address");
|
||||||
thread_dhcp_client_global_address_delete(curInterface->id, addr, prefixEntry->servicesPrefix);
|
dhcp_client_global_address_delete(curInterface->id, addr, prefixEntry->servicesPrefix);
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
if (cur->P_slaac) {
|
||||||
tr_debug("Delete SLAAC address");
|
tr_debug("Delete SLAAC address");
|
||||||
addr_delete_matching(curInterface, prefixEntry->servicesPrefix, 64, ADDR_SOURCE_SLAAC);
|
addr_delete_matching(curInterface, prefixEntry->servicesPrefix, 64, ADDR_SOURCE_SLAAC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cur->P_res1) {
|
||||||
|
tr_debug("Delete thread domain address");
|
||||||
|
addr_delete_matching(curInterface, prefixEntry->servicesPrefix, 64, ADDR_SOURCE_THREAD_DOMAIN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ns_list_remove(listPtr, cur);
|
ns_list_remove(listPtr, cur);
|
||||||
|
@ -995,7 +1002,7 @@ void thread_network_local_server_data_base_init(thread_network_local_data_cache_
|
||||||
ns_list_init(&cachePtr->service_list);
|
ns_list_init(&cachePtr->service_list);
|
||||||
cachePtr->registered_rloc16 = 0xffff;
|
cachePtr->registered_rloc16 = 0xffff;
|
||||||
cachePtr->release_old_address = false;
|
cachePtr->release_old_address = false;
|
||||||
cachePtr->publish_active = false;
|
cachePtr->publish_coap_req_id = 0;
|
||||||
cachePtr->publish_pending = false;
|
cachePtr->publish_pending = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1077,6 +1084,7 @@ bool thread_network_data_router_id_free(thread_network_data_cache_entry_t *cache
|
||||||
|
|
||||||
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)
|
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)
|
||||||
{
|
{
|
||||||
|
(void) id;
|
||||||
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) {
|
||||||
if (!curContext->compression) {
|
if (!curContext->compression) {
|
||||||
|
@ -1090,9 +1098,7 @@ void thread_network_data_context_re_use_timer_update(int8_t id, thread_network_d
|
||||||
cachePtr->temporaryUpdatePushed = true;
|
cachePtr->temporaryUpdatePushed = true;
|
||||||
}
|
}
|
||||||
// Set context lifetime to 0 to delete
|
// Set context lifetime to 0 to delete
|
||||||
if (thread_extension_context_can_delete(id, cur->servicesPrefix,curContext->contextPrefixLength)) {
|
lowpan_context_update(context_list, curContext->cid, 0, NULL, 0, true);
|
||||||
lowpan_context_update(context_list, curContext->cid, 0, NULL, 0, true);
|
|
||||||
}
|
|
||||||
ns_dyn_mem_free(curContext);
|
ns_dyn_mem_free(curContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1162,7 +1168,7 @@ void thread_network_local_data_free_and_clean(thread_network_local_data_cache_en
|
||||||
}
|
}
|
||||||
|
|
||||||
cachePtr->publish_pending = false;
|
cachePtr->publish_pending = false;
|
||||||
cachePtr->publish_active = false;
|
cachePtr->publish_coap_req_id = 0;
|
||||||
cachePtr->release_old_address = false;
|
cachePtr->release_old_address = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1628,6 +1634,7 @@ int thread_nd_local_list_add_on_mesh_prefix(thread_network_data_cache_entry_t *n
|
||||||
server_entry->P_nd_dns = service->P_nd_dns;
|
server_entry->P_nd_dns = service->P_nd_dns;
|
||||||
trigDataPropagate = true;
|
trigDataPropagate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trigDataPropagate) {
|
if (trigDataPropagate) {
|
||||||
|
@ -1707,9 +1714,9 @@ int thread_nd_local_list_del_on_mesh_server(thread_network_data_cache_entry_t *n
|
||||||
int thread_local_server_list_add_on_mesh_server(thread_network_local_data_cache_entry_t *networkDataList, thread_prefix_tlv_t *prefixTlv, thread_border_router_tlv_entry_t *service)
|
int thread_local_server_list_add_on_mesh_server(thread_network_local_data_cache_entry_t *networkDataList, thread_prefix_tlv_t *prefixTlv, thread_border_router_tlv_entry_t *service)
|
||||||
{
|
{
|
||||||
int retVal = -1;
|
int retVal = -1;
|
||||||
tr_debug("Add prefix: %s prf:%d %s%s%s%s%s", trace_ipv6_prefix(prefixTlv->Prefix, prefixTlv->PrefixLen), service->Prf,
|
tr_debug("Add prefix: %s prf:%d %s%s%s%s%s%s", trace_ipv6_prefix(prefixTlv->Prefix, prefixTlv->PrefixLen), service->Prf,
|
||||||
service->P_default_route?"Default Route ":"",service->P_dhcp?"DHCPv6 Server ":"", service->P_configure?"DHCPv6 Configuration ":"",
|
service->P_default_route?"Default Route ":"",service->P_dhcp?"DHCPv6 Server ":"", service->P_configure?"DHCPv6 Configuration ":"",
|
||||||
service->P_slaac?"SLAAC ":"",service->P_preferred?"Preferred ":"");
|
service->P_slaac?"SLAAC ":"",service->P_preferred?"Preferred ":"",service->P_res1?"P_res1 ":"");
|
||||||
|
|
||||||
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);
|
||||||
|
@ -2341,7 +2348,9 @@ bool thread_nd_service_anycast_address_mapping_from_network_data(thread_network_
|
||||||
if (curService->S_id != S_id) {
|
if (curService->S_id != S_id) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ns_list_foreach(thread_network_data_service_server_entry_t, curServiceServer, &curService->server_list) {
|
/* any server will do - take first from the list */
|
||||||
|
thread_network_data_service_server_entry_t *curServiceServer = ns_list_get_first(&curService->server_list);
|
||||||
|
if (curServiceServer) {
|
||||||
*rlocAddress = curServiceServer->router_id;
|
*rlocAddress = curServiceServer->router_id;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2352,7 +2361,7 @@ bool thread_nd_service_anycast_address_mapping_from_network_data(thread_network_
|
||||||
bool thread_nd_on_mesh_address_valid(thread_network_server_data_entry_t *curRoute)
|
bool thread_nd_on_mesh_address_valid(thread_network_server_data_entry_t *curRoute)
|
||||||
{
|
{
|
||||||
bool onMeshActive = false;
|
bool onMeshActive = false;
|
||||||
if (curRoute->P_dhcp || curRoute->P_slaac || curRoute->P_preferred) {
|
if (curRoute->P_dhcp || curRoute->P_slaac || curRoute->P_preferred || curRoute->P_on_mesh) {
|
||||||
onMeshActive = true;
|
onMeshActive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -187,8 +187,8 @@ typedef struct thread_network_local_data_cache_entry_s {
|
||||||
thread_network_data_prefix_list_t prefix_list; /*!< Local parsed or generated service list */
|
thread_network_data_prefix_list_t prefix_list; /*!< Local parsed or generated service list */
|
||||||
thread_network_data_service_list_t service_list;
|
thread_network_data_service_list_t service_list;
|
||||||
uint16_t registered_rloc16;/*!< Address used for latest registration */
|
uint16_t registered_rloc16;/*!< Address used for latest registration */
|
||||||
|
uint16_t publish_coap_req_id;/*!< Non-zero when publish is active */
|
||||||
bool release_old_address:1;/*!< true if network data can be released from old address */
|
bool release_old_address:1;/*!< true if network data can be released from old address */
|
||||||
bool publish_active:1;/*!< true when publish is active */
|
|
||||||
bool publish_pending:1;/*!< true when publish attempt made during active publish */
|
bool publish_pending:1;/*!< true when publish attempt made during active publish */
|
||||||
} thread_network_local_data_cache_entry_t;
|
} thread_network_local_data_cache_entry_t;
|
||||||
|
|
||||||
|
@ -344,7 +344,7 @@ uint8_t *thread_network_data_prefix_set_write(thread_network_data_cache_entry_t
|
||||||
uint8_t *thread_network_data_service_set_write(thread_network_data_cache_entry_t *networkDataList, uint8_t *ptr);
|
uint8_t *thread_network_data_service_set_write(thread_network_data_cache_entry_t *networkDataList, uint8_t *ptr);
|
||||||
bool thread_network_data_service_hosted_by_this_router_id(thread_network_data_service_cache_entry_t *dataList, uint16_t router_id);
|
bool thread_network_data_service_hosted_by_this_router_id(thread_network_data_service_cache_entry_t *dataList, uint16_t router_id);
|
||||||
uint16_t thread_network_data_service_child_id_from_networkdata_get(thread_network_data_cache_entry_t *networkDataList, uint16_t router_short_addr);
|
uint16_t thread_network_data_service_child_id_from_networkdata_get(thread_network_data_cache_entry_t *networkDataList, uint16_t router_short_addr);
|
||||||
|
thread_network_data_prefix_cache_entry_t *thread_prefix_entry_find(thread_network_prefix_list_t *list, thread_prefix_tlv_t *prefixTlv);
|
||||||
uint8_t * thread_nd_own_service_list_data_write(thread_network_local_data_cache_entry_t *serverDataList, uint8_t *ptr, uint16_t routerID);
|
uint8_t * thread_nd_own_service_list_data_write(thread_network_local_data_cache_entry_t *serverDataList, uint8_t *ptr, uint16_t routerID);
|
||||||
|
|
||||||
uint16_t thread_nd_own_service_list_data_size(thread_network_local_data_cache_entry_t *serverDataList);
|
uint16_t thread_nd_own_service_list_data_size(thread_network_local_data_cache_entry_t *serverDataList);
|
||||||
|
|
|
@ -292,7 +292,11 @@ int thread_nvm_store_active_configuration_remove(void)
|
||||||
}
|
}
|
||||||
char ac_data_path[ACTIVE_CONF_STRING_LEN];
|
char ac_data_path[ACTIVE_CONF_STRING_LEN];
|
||||||
thread_nvm_store_create_path(ac_data_path, THREAD_NVM_ACTIVE_CONF_FILE);
|
thread_nvm_store_create_path(ac_data_path, THREAD_NVM_ACTIVE_CONF_FILE);
|
||||||
return remove(ac_data_path);
|
int status = remove(ac_data_path);
|
||||||
|
if (status != 0) {
|
||||||
|
return THREAD_NVM_FILE_REMOVE_ERROR;
|
||||||
|
}
|
||||||
|
return THREAD_NVM_FILE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_nvm_store_pending_configuration_remove(void)
|
int thread_nvm_store_pending_configuration_remove(void)
|
||||||
|
@ -302,7 +306,11 @@ int thread_nvm_store_pending_configuration_remove(void)
|
||||||
}
|
}
|
||||||
char ac_data_path[PENDING_CONF_STRING_LEN];
|
char ac_data_path[PENDING_CONF_STRING_LEN];
|
||||||
thread_nvm_store_create_path(ac_data_path, THREAD_NVM_PENDING_CONF_FILE);
|
thread_nvm_store_create_path(ac_data_path, THREAD_NVM_PENDING_CONF_FILE);
|
||||||
return remove(ac_data_path);
|
int status = remove(ac_data_path);
|
||||||
|
if (status != 0) {
|
||||||
|
return THREAD_NVM_FILE_REMOVE_ERROR;
|
||||||
|
}
|
||||||
|
return THREAD_NVM_FILE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "coap_service_api.h"
|
#include "coap_service_api.h"
|
||||||
|
|
||||||
#include "thread_config.h"
|
#include "thread_config.h"
|
||||||
|
#include "thread_management_server.h"
|
||||||
#include "thread_resolution_client.h"
|
#include "thread_resolution_client.h"
|
||||||
|
|
||||||
#define TRACE_GROUP TRACE_GROUP_THREAD_RESOLUTION_CLIENT
|
#define TRACE_GROUP TRACE_GROUP_THREAD_RESOLUTION_CLIENT
|
||||||
|
@ -294,7 +295,7 @@ void thread_resolution_client_init(int8_t interface_id)
|
||||||
this->error_cb_ptr = NULL;
|
this->error_cb_ptr = NULL;
|
||||||
ns_list_init(&this->queries);
|
ns_list_init(&this->queries);
|
||||||
//TODO: Check if to use ephemeral port here
|
//TODO: Check if to use ephemeral port here
|
||||||
this->coap_service_id = coap_service_initialize(this->interface_id, THREAD_MANAGEMENT_PORT, COAP_SERVICE_OPTIONS_NONE, NULL, NULL);
|
this->coap_service_id = thread_management_server_service_id_get(interface_id);
|
||||||
ns_list_add_to_start(&instance_list, this);
|
ns_list_add_to_start(&instance_list, this);
|
||||||
|
|
||||||
coap_service_register_uri(this->coap_service_id, THREAD_URI_ADDRESS_NOTIFICATION, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_resolution_client_notification_post_cb);
|
coap_service_register_uri(this->coap_service_id, THREAD_URI_ADDRESS_NOTIFICATION, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_resolution_client_notification_post_cb);
|
||||||
|
@ -309,7 +310,7 @@ void thread_resolution_client_delete(int8_t interface_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
coap_service_unregister_uri(this->coap_service_id, THREAD_URI_ADDRESS_NOTIFICATION);
|
coap_service_unregister_uri(this->coap_service_id, THREAD_URI_ADDRESS_NOTIFICATION);
|
||||||
coap_service_delete(this->coap_service_id);
|
coap_service_unregister_uri(this->coap_service_id, THREAD_URI_ADDRESS_ERROR);
|
||||||
ns_list_foreach_safe(address_query_t, query, &this->queries) {
|
ns_list_foreach_safe(address_query_t, query, &this->queries) {
|
||||||
ns_list_remove(&this->queries, query);
|
ns_list_remove(&this->queries, query);
|
||||||
ns_dyn_mem_free(query);
|
ns_dyn_mem_free(query);
|
||||||
|
@ -465,6 +466,7 @@ void thread_resolution_client_timer(int8_t interface_id, uint16_t seconds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HAVE_THREAD_NEIGHBOR_DISCOVERY
|
#endif // HAVE_THREAD_NEIGHBOR_DISCOVERY
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include "thread_config.h"
|
#include "thread_config.h"
|
||||||
#include "thread_tmfcop_lib.h"
|
#include "thread_tmfcop_lib.h"
|
||||||
#include "thread_management_if.h"
|
#include "thread_management_if.h"
|
||||||
|
#include "thread_management_server.h"
|
||||||
#include "thread_commissioning_if.h"
|
#include "thread_commissioning_if.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -170,9 +171,9 @@ int thread_resolution_server_init(int8_t interface_id, thread_resolution_server_
|
||||||
}
|
}
|
||||||
|
|
||||||
this->interface_id = interface_id;
|
this->interface_id = interface_id;
|
||||||
this->coap_service_id = coap_service_initialize(this->interface_id, THREAD_MANAGEMENT_PORT, COAP_SERVICE_OPTIONS_NONE, NULL, NULL);
|
this->coap_service_id = thread_management_server_service_id_get(interface_id);
|
||||||
if (this->coap_service_id < 0) {
|
if (this->coap_service_id < 0) {
|
||||||
tr_warn("Thread resolution init failed");
|
tr_warn("Thread resolution srv init failed");
|
||||||
ns_dyn_mem_free(this);
|
ns_dyn_mem_free(this);
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
@ -193,7 +194,6 @@ void thread_resolution_server_delete(int8_t interface_id)
|
||||||
|
|
||||||
coap_service_unregister_uri(this->coap_service_id, THREAD_URI_ADDRESS_QUERY_REQUEST);
|
coap_service_unregister_uri(this->coap_service_id, THREAD_URI_ADDRESS_QUERY_REQUEST);
|
||||||
|
|
||||||
coap_service_delete(this->coap_service_id);
|
|
||||||
ns_list_remove(&instance_list, this);
|
ns_list_remove(&instance_list, this);
|
||||||
ns_dyn_mem_free(this);
|
ns_dyn_mem_free(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@
|
||||||
#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/blacklist/blacklist.h"
|
#include "Service_Libs/blacklist/blacklist.h"
|
||||||
#include "thread_dhcpv6_client.h"
|
#include "DHCPv6_client/dhcpv6_client_api.h"
|
||||||
#include "6LoWPAN/MAC/mac_helper.h"
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
#include "mac_api.h"
|
#include "mac_api.h"
|
||||||
#include "6LoWPAN/MAC/mac_data_poll.h"
|
#include "6LoWPAN/MAC/mac_data_poll.h"
|
||||||
|
@ -1027,10 +1027,10 @@ static void thread_bootstrap_client_router_id_cb(int8_t interface_id, int8_t sta
|
||||||
if (!cur) {
|
if (!cur) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!cur->thread_info->routerIdReqCoapID) {
|
if (!cur->thread_info->routerIdRequested) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cur->thread_info->routerIdReqCoapID = 0;
|
cur->thread_info->routerIdRequested = false;
|
||||||
|
|
||||||
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->leader_private_data ) {
|
cur->thread_info->leader_private_data ) {
|
||||||
|
@ -1088,15 +1088,15 @@ void thread_router_bootstrap_router_id_request(protocol_interface_info_entry_t *
|
||||||
{
|
{
|
||||||
int router_id_req_status;
|
int router_id_req_status;
|
||||||
tr_debug("Router ID Request");
|
tr_debug("Router ID Request");
|
||||||
if (cur->thread_info->routerIdReqCoapID) {
|
if (cur->thread_info->routerIdRequested) {
|
||||||
tr_warn("Router ID already requested");
|
tr_warn("Router ID already requested");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
router_id_req_status = thread_management_client_router_id_get(cur->id, cur->mac, cur->thread_info->routerShortAddress, thread_bootstrap_client_router_id_cb, status);
|
router_id_req_status = thread_management_client_router_id_get(cur->id, cur->mac, cur->thread_info->routerShortAddress, thread_bootstrap_client_router_id_cb, status);
|
||||||
tr_debug("Coap address req, ID=%d", router_id_req_status);
|
tr_debug("RouterIDReq COAP ID=%d", router_id_req_status);
|
||||||
if (router_id_req_status > 0) {
|
if (router_id_req_status > 0) {
|
||||||
cur->thread_info->routerIdReqCoapID = (uint16_t)router_id_req_status;
|
cur->thread_info->routerIdRequested = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1196,6 +1196,32 @@ static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *c
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int thread_router_bootstrap_child_max_timeout_get(protocol_interface_info_entry_t *cur, uint32_t *max_child_timeout)
|
||||||
|
{
|
||||||
|
uint16_t router_address = thread_info(cur)->routerShortAddress;
|
||||||
|
uint32_t max_timeout = 0;
|
||||||
|
if (router_address >= 0xfffe) {
|
||||||
|
router_address = mac_helper_mac16_address_get(cur);
|
||||||
|
}
|
||||||
|
if (router_address & THREAD_CHILD_MASK) {
|
||||||
|
return -1; //I am child
|
||||||
|
}
|
||||||
|
if (router_address >= 0xfffe) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
|
||||||
|
|
||||||
|
ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) {
|
||||||
|
if (thread_router_addr_from_addr(cur_entry->mac16) == router_address &&
|
||||||
|
!cur_entry->ffd_device && cur_entry->lifetime > max_timeout) {
|
||||||
|
max_timeout = cur_entry->lifetime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*max_child_timeout = max_timeout;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
uint16_t child_count = 0;
|
uint16_t child_count = 0;
|
||||||
|
@ -1277,7 +1303,7 @@ void thread_router_bootstrap_child_id_handler(protocol_interface_info_entry_t *c
|
||||||
bool new_neigbour = false;
|
bool new_neigbour = false;
|
||||||
|
|
||||||
if (cur->thread_info->thread_attached_state == THREAD_STATE_CONNECTED) {
|
if (cur->thread_info->thread_attached_state == THREAD_STATE_CONNECTED) {
|
||||||
if (!cur->thread_info->routerIdReqCoapID) {
|
if (!cur->thread_info->routerIdRequested) {
|
||||||
tr_info("Upgrade REED to Router");
|
tr_info("Upgrade REED to Router");
|
||||||
thread_router_bootstrap_router_id_request(cur, THREAD_COAP_STATUS_TLV_HAVE_CHILD_ID_REQUEST);
|
thread_router_bootstrap_router_id_request(cur, THREAD_COAP_STATUS_TLV_HAVE_CHILD_ID_REQUEST);
|
||||||
}
|
}
|
||||||
|
@ -1366,7 +1392,7 @@ static void thread_address_registration_tlv_parse(uint8_t *ptr, uint16_t data_le
|
||||||
uint8_t tempIPv6Address[16];
|
uint8_t tempIPv6Address[16];
|
||||||
uint8_t ctxId;
|
uint8_t ctxId;
|
||||||
bool new_neighbour_created;
|
bool new_neighbour_created;
|
||||||
|
thread_child_mcast_entries_remove(cur,mac64);
|
||||||
while (data_length) {
|
while (data_length) {
|
||||||
//Read
|
//Read
|
||||||
ctxId = *ptr++;
|
ctxId = *ptr++;
|
||||||
|
@ -1389,8 +1415,8 @@ static void thread_address_registration_tlv_parse(uint8_t *ptr, uint16_t data_le
|
||||||
tr_debug("Register %s", trace_ipv6(ptr));
|
tr_debug("Register %s", trace_ipv6(ptr));
|
||||||
|
|
||||||
if (addr_is_ipv6_multicast(ptr)) {
|
if (addr_is_ipv6_multicast(ptr)) {
|
||||||
// Register multicast address (higher scope than link-local)
|
// Register multicast address (link-local & higher)
|
||||||
if (addr_ipv6_multicast_scope(ptr) > IPV6_SCOPE_LINK_LOCAL) {
|
if (addr_ipv6_multicast_scope(ptr) >= IPV6_SCOPE_LINK_LOCAL) {
|
||||||
addr_add_group(cur, ptr);
|
addr_add_group(cur, ptr);
|
||||||
if (thread_child_mcast_entry_get(cur, ptr, mac64)) {
|
if (thread_child_mcast_entry_get(cur, ptr, mac64)) {
|
||||||
tr_debug("Added sleepy multicast registration entry.");
|
tr_debug("Added sleepy multicast registration entry.");
|
||||||
|
@ -1665,6 +1691,11 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(id_req->mode & MLE_FFD_DEV) && addressRegisteredTlv.tlvLen == 0) {
|
||||||
|
tr_debug("No address registration TLV in MTD child id request");
|
||||||
|
thread_child_id_request_entry_remove(cur, id_req);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
id_req->keyId = security_headers->KeyIndex;
|
id_req->keyId = security_headers->KeyIndex;
|
||||||
id_req->keySeq = common_read_32_bit(security_headers->Keysource);
|
id_req->keySeq = common_read_32_bit(security_headers->Keysource);
|
||||||
|
@ -1991,10 +2022,22 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t mode = mle_mode_write_from_mac_entry(entry_temp);
|
||||||
|
/* check if thread neighbor class is not initialized */
|
||||||
|
if ((thread_neighbor_entry_linkmargin_get(&cur->thread_info->neighbor_class, entry_temp->index) == 0) &&
|
||||||
|
(thread_neighbor_last_communication_time_get(&cur->thread_info->neighbor_class, entry_temp->index) == 0)) {
|
||||||
|
/*
|
||||||
|
* Thread neighbor class is not yet initialized and we receive data_request from such child.
|
||||||
|
* Always send full network data in this case
|
||||||
|
*/
|
||||||
|
mode |= MLE_THREAD_REQ_FULL_DATA_SET | MLE_THREAD_SECURED_DATA_REQUEST;
|
||||||
|
} else {
|
||||||
|
mode |= thread_neighbor_class_mode_write_from_entry(&cur->thread_info->neighbor_class, entry_temp->index);
|
||||||
|
}
|
||||||
|
|
||||||
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index,linkMargin, false);
|
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_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);
|
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;
|
||||||
|
@ -2026,8 +2069,9 @@ static int8_t thread_router_bootstrap_synch_request_send(protocol_interface_info
|
||||||
tr_debug("Buffer overflow at message write");
|
tr_debug("Buffer overflow at message write");
|
||||||
}
|
}
|
||||||
|
|
||||||
timeout.retrans_max = THREAD_REQUEST_MAX_RETRY_CNT;
|
// timeout set to two seconds, no retries
|
||||||
timeout.timeout_init = 1;
|
timeout.retrans_max = 1;
|
||||||
|
timeout.timeout_init = 2;
|
||||||
timeout.timeout_max = 3;
|
timeout.timeout_max = 3;
|
||||||
timeout.delay = MLE_NO_DELAY;
|
timeout.delay = MLE_NO_DELAY;
|
||||||
|
|
||||||
|
@ -2325,7 +2369,6 @@ static uint32_t thread_reed_timeout_calculate(thread_router_select_t *routerSele
|
||||||
static int thread_reed_advertise (protocol_interface_info_entry_t *cur)
|
static int thread_reed_advertise (protocol_interface_info_entry_t *cur)
|
||||||
{
|
{
|
||||||
uint32_t keySequence;
|
uint32_t keySequence;
|
||||||
tr_debug("MLE REED ADVERTISEMENT STARTED");
|
|
||||||
struct link_configuration *linkConfiguration;
|
struct link_configuration *linkConfiguration;
|
||||||
linkConfiguration = thread_joiner_application_get_config(cur->id);
|
linkConfiguration = thread_joiner_application_get_config(cur->id);
|
||||||
if (!linkConfiguration) {
|
if (!linkConfiguration) {
|
||||||
|
@ -2336,11 +2379,17 @@ static int thread_reed_advertise (protocol_interface_info_entry_t *cur)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FED not allowed to send advertisements
|
||||||
|
if (thread_info(cur)->thread_device_mode == THREAD_DEVICE_MODE_FULL_END_DEVICE) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t bufId = mle_service_msg_allocate(cur->id, 16, false, MLE_COMMAND_ADVERTISEMENT);
|
uint16_t bufId = mle_service_msg_allocate(cur->id, 16, false, MLE_COMMAND_ADVERTISEMENT);
|
||||||
if (bufId == 0) {
|
if (bufId == 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tr_debug("MLE REED ADVERTISEMENT STARTED");
|
||||||
thread_management_get_current_keysequence(cur->id, &keySequence);
|
thread_management_get_current_keysequence(cur->id, &keySequence);
|
||||||
mle_service_msg_update_security_params(bufId, 5, 2, keySequence);
|
mle_service_msg_update_security_params(bufId, 5, 2, keySequence);
|
||||||
|
|
||||||
|
@ -2734,4 +2783,18 @@ void thread_router_bootstrap_address_change_notify_send(protocol_interface_info_
|
||||||
thread_info(cur)->proactive_an_timer = THREAD_PROACTIVE_AN_SEND_DELAY;
|
thread_info(cur)->proactive_an_timer = THREAD_PROACTIVE_AN_SEND_DELAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void thread_router_bootstrap_delay_reed_jitter(int8_t interface_id, uint16_t delay)
|
||||||
|
{
|
||||||
|
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
|
if (!cur) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cur->thread_info->thread_device_mode != THREAD_DEVICE_MODE_ROUTER) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// delay reed jitter timer to allow for settings changes to distribute
|
||||||
|
thread_info(cur)->reedJitterTimer += delay;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* HAVE_THREAD_ROUTER */
|
#endif /* HAVE_THREAD_ROUTER */
|
||||||
|
|
|
@ -52,6 +52,9 @@ int thread_router_bootstrap_mle_advertise(struct protocol_interface_info_entry *
|
||||||
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, struct mac_neighbor_table_entry *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);
|
||||||
|
|
||||||
|
// max_child_timeout is longest MLE Timeout a router has registered for all of its active MTD children
|
||||||
|
int thread_router_bootstrap_child_max_timeout_get(protocol_interface_info_entry_t *cur, uint32_t *max_child_timeout);
|
||||||
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);
|
||||||
void thread_router_bootstrap_router_id_request(struct protocol_interface_info_entry *cur, uint8_t status);
|
void thread_router_bootstrap_router_id_request(struct protocol_interface_info_entry *cur, uint8_t status);
|
||||||
|
@ -73,6 +76,7 @@ void thread_router_bootstrap_anycast_address_register(protocol_interface_info_en
|
||||||
void thread_router_bootstrap_network_data_distribute(protocol_interface_info_entry_t *cur);
|
void thread_router_bootstrap_network_data_distribute(protocol_interface_info_entry_t *cur);
|
||||||
bool thread_router_bootstrap_routing_allowed(struct protocol_interface_info_entry *cur);
|
bool thread_router_bootstrap_routing_allowed(struct protocol_interface_info_entry *cur);
|
||||||
void thread_router_bootstrap_address_change_notify_send(protocol_interface_info_entry_t *cur);
|
void thread_router_bootstrap_address_change_notify_send(protocol_interface_info_entry_t *cur);
|
||||||
|
void thread_router_bootstrap_delay_reed_jitter(int8_t interface_id, uint16_t delay);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@ -81,6 +85,7 @@ void thread_router_bootstrap_address_change_notify_send(protocol_interface_info_
|
||||||
|
|
||||||
#define thread_router_bootstrap_child_information_clear(cur)
|
#define thread_router_bootstrap_child_information_clear(cur)
|
||||||
#define thread_router_bootstrap_child_count_get(cur) 0
|
#define thread_router_bootstrap_child_count_get(cur) 0
|
||||||
|
#define thread_router_bootstrap_child_max_timeout_get(cur, max_child_timeout) 0
|
||||||
#define thread_router_bootstrap_child_id_handler(cur)
|
#define thread_router_bootstrap_child_id_handler(cur)
|
||||||
#define thread_router_bootstrap_child_id_reject(cur)
|
#define thread_router_bootstrap_child_id_reject(cur)
|
||||||
#define thread_router_bootstrap_router_id_request(cur, status)
|
#define thread_router_bootstrap_router_id_request(cur, status)
|
||||||
|
@ -104,7 +109,7 @@ void thread_router_bootstrap_address_change_notify_send(protocol_interface_info_
|
||||||
#define thread_router_bootstrap_routing_allowed(cur) false
|
#define thread_router_bootstrap_routing_allowed(cur) false
|
||||||
#define thread_router_bootstrap_address_change_notify_send(cur)
|
#define thread_router_bootstrap_address_change_notify_send(cur)
|
||||||
#define thread_router_bootstrap_reed_merge_advertisement(cur)
|
#define thread_router_bootstrap_reed_merge_advertisement(cur)
|
||||||
|
#define thread_router_bootstrap_delay_reed_jitter(interface_id, delay)
|
||||||
#endif/*HAVE_THREAD_ROUTER*/
|
#endif/*HAVE_THREAD_ROUTER*/
|
||||||
|
|
||||||
#endif /* THREAD_ROUTER_BOOTSTRAP_H_ */
|
#endif /* THREAD_ROUTER_BOOTSTRAP_H_ */
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
#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 "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
#include "6LoWPAN/Thread/thread_common.h"
|
#include "6LoWPAN/Thread/thread_common.h"
|
||||||
#include "6LoWPAN/ws/ws_common.h"
|
#include "6LoWPAN/ws/ws_common.h"
|
||||||
|
@ -72,7 +71,7 @@ typedef struct {
|
||||||
bool fragmented_data:1;
|
bool fragmented_data:1;
|
||||||
bool first_fragment:1;
|
bool first_fragment:1;
|
||||||
bool indirect_data:1;
|
bool indirect_data:1;
|
||||||
bool indirect_data_cached:1; /* Data cached for delayed transmission as mac request is already active */
|
bool indirect_data_cached:1; /*!< Data cached for delayed transmission as mac request is already active */
|
||||||
buffer_t *buf;
|
buffer_t *buf;
|
||||||
uint8_t *fragmenter_buf;
|
uint8_t *fragmenter_buf;
|
||||||
ns_list_link_t link; /*!< List link entry */
|
ns_list_link_t link; /*!< List link entry */
|
||||||
|
@ -132,7 +131,7 @@ 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, fragmenter_interface_t *interface_ptr);
|
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 bool 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);
|
||||||
|
|
||||||
|
@ -613,40 +612,35 @@ buffer_t * lowpan_adaptation_data_process_tx_preprocess(protocol_interface_info_
|
||||||
{
|
{
|
||||||
mac_neighbor_table_entry_t *neigh_entry_ptr = NULL;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If MLE is enabled, we will talk if we have an MLE association */
|
if (addr_check_broadcast(buf->dst_sa.address, buf->dst_sa.addr_type) == eOK ) {
|
||||||
if (buf->dst_sa.addr_type == ADDR_802_15_4_LONG ) {
|
|
||||||
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) {
|
|
||||||
neigh_entry_ptr = mac_neighbor_table_address_discover(mac_neighbor_info(cur), buf->dst_sa.address + 2, buf->dst_sa.addr_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Validate neighbour
|
|
||||||
if (!buf->options.ll_security_bypass_tx && neigh_entry_ptr) {
|
|
||||||
|
|
||||||
if (neigh_entry_ptr->connected_device || neigh_entry_ptr->trusted_device) {
|
|
||||||
|
|
||||||
} else {
|
|
||||||
//tr_warn("Drop TX to unassociated %s", trace_sockaddr(&buf->dst_sa, true));
|
|
||||||
goto tx_error_handler;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Check indirect
|
|
||||||
|
|
||||||
|
|
||||||
if (addr_check_broadcast(buf->dst_sa.address, buf->dst_sa.addr_type) == eOK) {
|
|
||||||
buf->dst_sa.addr_type = ADDR_802_15_4_SHORT;
|
buf->dst_sa.addr_type = ADDR_802_15_4_SHORT;
|
||||||
buf->dst_sa.address[2] = 0xff;
|
buf->dst_sa.address[2] = 0xff;
|
||||||
buf->dst_sa.address[3] = 0xff;
|
buf->dst_sa.address[3] = 0xff;
|
||||||
buf->link_specific.ieee802_15_4.indirectTxProcess = false;
|
buf->link_specific.ieee802_15_4.indirectTxProcess = false;
|
||||||
buf->link_specific.ieee802_15_4.requestAck = false;
|
buf->link_specific.ieee802_15_4.requestAck = false;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
neigh_entry_ptr = mac_neighbor_table_address_discover(mac_neighbor_info(cur), buf->dst_sa.address + 2, buf->dst_sa.addr_type);
|
||||||
|
|
||||||
|
//Validate neighbour
|
||||||
|
if (!buf->options.ll_security_bypass_tx && neigh_entry_ptr) {
|
||||||
|
|
||||||
|
if (neigh_entry_ptr->connected_device || neigh_entry_ptr->trusted_device) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//tr_warn("Drop TX to unassociated %s", trace_sockaddr(&buf->dst_sa, true));
|
||||||
|
goto tx_error_handler;
|
||||||
|
}
|
||||||
|
} else if (ws_info(cur) && !neigh_entry_ptr) {
|
||||||
|
//Do not accept to send unknow device
|
||||||
|
goto tx_error_handler;
|
||||||
|
}
|
||||||
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(neigh_entry_ptr);
|
buf->link_specific.ieee802_15_4.indirectTxProcess = lowpan_adaptation_indirect_data_request(neigh_entry_ptr);
|
||||||
}
|
}
|
||||||
|
@ -755,7 +749,7 @@ static bool lowpan_adaptation_indirect_cache_trigger(protocol_interface_info_ent
|
||||||
ns_list_foreach(fragmenter_tx_entry_t, fragmenter_tx_entry, &interface_ptr->indirect_tx_queue) {
|
ns_list_foreach(fragmenter_tx_entry_t, fragmenter_tx_entry, &interface_ptr->indirect_tx_queue) {
|
||||||
if (fragmenter_tx_entry->indirect_data_cached) {
|
if (fragmenter_tx_entry->indirect_data_cached) {
|
||||||
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, interface_ptr);
|
lowpan_data_request_to_mac(cur, fragmenter_tx_entry->buf, fragmenter_tx_entry, interface_ptr);
|
||||||
return true;
|
return true;
|
||||||
|
@ -805,7 +799,12 @@ static void lowpan_adaptation_make_room_for_small_packet(protocol_interface_info
|
||||||
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);
|
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);
|
tr_debug_extra("Purge seq: %d", tx_entry->buf->seq);
|
||||||
|
if (lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, tx_entry) == false) {
|
||||||
|
/* entry could not be purged from mac, try next entry */
|
||||||
|
tr_debug_extra("Purge failed, try next");
|
||||||
|
count--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -822,8 +821,12 @@ static void lowpan_adaptation_make_room_for_big_packet(struct protocol_interface
|
||||||
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) {
|
||||||
if (buffer_data_length(tx_entry->buf) > interface_ptr->indirect_big_packet_threshold) {
|
if (buffer_data_length(tx_entry->buf) > interface_ptr->indirect_big_packet_threshold) {
|
||||||
if (++count >= interface_ptr->max_indirect_big_packets_total) {
|
if (++count >= interface_ptr->max_indirect_big_packets_total) {
|
||||||
tr_debug_extra("free seq: %d", tx_entry->buf->seq);
|
tr_debug_extra("Purge seq: %d", tx_entry->buf->seq);
|
||||||
lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, tx_entry);
|
if (lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, tx_entry) == false) {
|
||||||
|
tr_debug("Purge failed, try next entry");
|
||||||
|
/* entry could not be purged from mac, try next entry */
|
||||||
|
count--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -911,6 +914,8 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
|
||||||
if (indirect) {
|
if (indirect) {
|
||||||
ns_dyn_mem_free(tx_ptr->fragmenter_buf);
|
ns_dyn_mem_free(tx_ptr->fragmenter_buf);
|
||||||
ns_dyn_mem_free(tx_ptr);
|
ns_dyn_mem_free(tx_ptr);
|
||||||
|
} else {
|
||||||
|
tx_ptr->buf = NULL;
|
||||||
}
|
}
|
||||||
goto tx_error_handler;
|
goto tx_error_handler;
|
||||||
}
|
}
|
||||||
|
@ -1281,29 +1286,44 @@ 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, fragmenter_interface_t *interface_ptr, uint8_t msduhandle)
|
static bool 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;
|
||||||
|
bool mac_purge_success = false;
|
||||||
if (interface_ptr->mpx_api) {
|
if (interface_ptr->mpx_api) {
|
||||||
interface_ptr->mpx_api->mpx_data_purge(interface_ptr->mpx_api, &purge_req, interface_ptr->mpx_user_id);
|
if (interface_ptr->mpx_api->mpx_data_purge(interface_ptr->mpx_api, &purge_req, interface_ptr->mpx_user_id) == 0) {
|
||||||
|
mac_purge_success = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (cur->mac_api->mcps_purge_req) {
|
if (cur->mac_api->mcps_purge_req) {
|
||||||
cur->mac_api->mcps_purge_req(cur->mac_api, &purge_req);
|
if (cur->mac_api->mcps_purge_req(cur->mac_api, &purge_req) == 0) {
|
||||||
|
mac_purge_success = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return mac_purge_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 bool 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, cached %d", tx_ptr->buf->seq, tx_ptr->indirect_data_cached);
|
||||||
lowpan_adaptation_purge_from_mac(cur, interface_ptr, tx_ptr->buf->seq);
|
if (tx_ptr->indirect_data_cached == false) {
|
||||||
|
if (lowpan_adaptation_purge_from_mac(cur, interface_ptr, tx_ptr->buf->seq) == false) {
|
||||||
|
// MAC purge failed
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lowpan_adaptation_data_process_clean(interface_ptr, tx_ptr, SOCKET_TX_FAIL);
|
lowpan_adaptation_data_process_clean(interface_ptr, tx_ptr, SOCKET_TX_FAIL);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lowpan_adaptation_remove_free_indirect_table(protocol_interface_info_entry_t *cur_interface, mac_neighbor_table_entry_t *entry_ptr)
|
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
|
//Free first by defined short address
|
||||||
if (entry_ptr->mac16 < 0xfffe) {
|
if (entry_ptr->mac16 < 0xfffe) {
|
||||||
uint8_t temp_address[2];
|
uint8_t temp_address[2];
|
||||||
common_write_16_bit(entry_ptr->mac16, temp_address);
|
common_write_16_bit(entry_ptr->mac16, temp_address);
|
||||||
|
@ -1323,7 +1343,6 @@ int8_t lowpan_adaptation_indirect_free_messages_from_queues_by_address(struct pr
|
||||||
|
|
||||||
//Check first indirect queue
|
//Check first indirect queue
|
||||||
ns_list_foreach_safe(fragmenter_tx_entry_t, entry, &interface_ptr->indirect_tx_queue) {
|
ns_list_foreach_safe(fragmenter_tx_entry_t, entry, &interface_ptr->indirect_tx_queue) {
|
||||||
|
|
||||||
if (lowpan_tx_buffer_address_compare(&entry->buf->dst_sa, address_ptr, adr_type)) {
|
if (lowpan_tx_buffer_address_compare(&entry->buf->dst_sa, address_ptr, adr_type)) {
|
||||||
//Purge from mac
|
//Purge from mac
|
||||||
lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, entry);
|
lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, entry);
|
||||||
|
@ -1331,7 +1350,6 @@ int8_t lowpan_adaptation_indirect_free_messages_from_queues_by_address(struct pr
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
@ -35,6 +35,8 @@ 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);
|
void ws_bootstrap_state_machine(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
|
int ws_bootstrap_restart(int8_t interface_id);
|
||||||
|
|
||||||
/*State machine transactions*/
|
/*State machine transactions*/
|
||||||
void ws_bootstrap_event_discovery_start(protocol_interface_info_entry_t *cur);
|
void ws_bootstrap_event_discovery_start(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
|
@ -50,12 +52,27 @@ void ws_bootstrap_configuration_trickle_reset(protocol_interface_info_entry_t *c
|
||||||
|
|
||||||
void ws_bootstrap_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds);
|
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);
|
void ws_bootstrap_trickle_timer(protocol_interface_info_entry_t *cur, uint16_t ticks);
|
||||||
|
|
||||||
|
void ws_primary_parent_update(protocol_interface_info_entry_t *interface, mac_neighbor_table_entry_t *neighbor);
|
||||||
|
|
||||||
|
void ws_secondary_parent_update(protocol_interface_info_entry_t *interface);
|
||||||
|
|
||||||
|
void ws_nud_entry_remove_active(protocol_interface_info_entry_t *cur, void *neighbor);
|
||||||
|
|
||||||
|
void ws_nud_active_timer(protocol_interface_info_entry_t *cur, uint16_t ticks);
|
||||||
|
|
||||||
|
void ws_dhcp_client_address_request(protocol_interface_info_entry_t *cur, uint8_t *prefix, uint8_t *parent_link_local);
|
||||||
|
|
||||||
|
void ws_dhcp_client_address_delete(protocol_interface_info_entry_t *cur, uint8_t *prefix);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define ws_bootstrap_init(interface_id, bootstrap_mode) (-1)
|
#define ws_bootstrap_init(interface_id, bootstrap_mode) (-1)
|
||||||
#define ws_bootstrap_state_machine(cur)
|
#define ws_bootstrap_state_machine(cur)
|
||||||
|
#define ws_bootstrap_restart(cur)
|
||||||
|
#define ws_primary_parent_update(interface, neighbor)
|
||||||
|
#define ws_secondary_parent_update(interface)
|
||||||
|
|
||||||
#endif //HAVE_WS
|
#endif //HAVE_WS
|
||||||
|
|
||||||
|
|
|
@ -20,11 +20,13 @@
|
||||||
|
|
||||||
|
|
||||||
#include "ns_types.h"
|
#include "ns_types.h"
|
||||||
|
#include "ns_list.h"
|
||||||
#include "fhss_api.h"
|
#include "fhss_api.h"
|
||||||
#include "fhss_config.h"
|
#include "fhss_config.h"
|
||||||
#include "net_fhss.h"
|
#include "net_fhss.h"
|
||||||
#include "6LoWPAN/ws/ws_common_defines.h"
|
#include "6LoWPAN/ws/ws_common_defines.h"
|
||||||
#include "6LoWPAN/ws/ws_neighbor_class.h"
|
#include "6LoWPAN/ws/ws_neighbor_class.h"
|
||||||
|
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||||
|
|
||||||
struct ws_pan_information_s;
|
struct ws_pan_information_s;
|
||||||
struct ws_neighbor_class_s;
|
struct ws_neighbor_class_s;
|
||||||
|
@ -40,6 +42,17 @@ typedef struct parent_info_s {
|
||||||
uint32_t timestamp; /**< Timestamp when packet was received */
|
uint32_t timestamp; /**< Timestamp when packet was received */
|
||||||
}parent_info_t;
|
}parent_info_t;
|
||||||
|
|
||||||
|
typedef struct ws_nud_table_entry {
|
||||||
|
void *neighbor_info;
|
||||||
|
uint16_t timer; /*!< Timer which resolution is 100ms*/
|
||||||
|
unsigned retry_count:2;
|
||||||
|
bool wait_response:1; /*!< True when NS is sended and wait NA, False when random timer is active*/
|
||||||
|
bool nud_process;
|
||||||
|
ns_list_link_t link;
|
||||||
|
} ws_nud_table_entry_t;
|
||||||
|
|
||||||
|
typedef NS_LIST_HEAD(ws_nud_table_entry_t, link) ws_nud_table_list_t;
|
||||||
|
|
||||||
typedef struct ws_info_s {
|
typedef struct ws_info_s {
|
||||||
char network_name[33]; // Network name max 32 octets + terminating 0.
|
char network_name[33]; // Network name max 32 octets + terminating 0.
|
||||||
uint16_t network_pan_id;
|
uint16_t network_pan_id;
|
||||||
|
@ -54,8 +67,24 @@ typedef struct ws_info_s {
|
||||||
uint32_t pan_version_timer; /**< border router version udate timeout */
|
uint32_t pan_version_timer; /**< border router version udate timeout */
|
||||||
uint32_t pan_version_timeout_timer; /**< routers will fallback to previous state after this */
|
uint32_t pan_version_timeout_timer; /**< routers will fallback to previous state after this */
|
||||||
uint8_t gtkhash[32];
|
uint8_t gtkhash[32];
|
||||||
|
bool address_registration_event_active : 1;
|
||||||
bool configuration_learned:1;
|
bool configuration_learned:1;
|
||||||
|
bool trickle_pas_running:1;
|
||||||
|
bool trickle_pa_running:1;
|
||||||
|
bool trickle_pcs_running:1;
|
||||||
|
bool trickle_pc_running:1;
|
||||||
|
// default fhss parameters for this device
|
||||||
|
uint8_t fhss_uc_dwell_interval;
|
||||||
|
uint8_t fhss_bc_dwell_interval;
|
||||||
|
uint32_t fhss_bc_interval;
|
||||||
|
uint8_t fhss_uc_channel_function;
|
||||||
|
uint8_t fhss_bc_channel_function;
|
||||||
|
uint16_t fhss_uc_fixed_channel;
|
||||||
|
uint16_t fhss_bc_fixed_channel;
|
||||||
|
uint32_t fhss_channel_mask[8];
|
||||||
|
ws_nud_table_entry_t nud_table_entrys[ACTIVE_NUD_PROCESS_MAX];
|
||||||
|
ws_nud_table_list_t active_nud_process;
|
||||||
|
ws_nud_table_list_t free_nud_entries;
|
||||||
struct ws_pan_information_s pan_information;
|
struct ws_pan_information_s pan_information;
|
||||||
ws_hopping_schedule_t hopping_schdule;
|
ws_hopping_schedule_t hopping_schdule;
|
||||||
struct ws_neighbor_class_s neighbor_storage;
|
struct ws_neighbor_class_s neighbor_storage;
|
||||||
|
@ -65,6 +94,8 @@ typedef struct ws_info_s {
|
||||||
|
|
||||||
#ifdef HAVE_WS
|
#ifdef HAVE_WS
|
||||||
|
|
||||||
|
int8_t ws_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_channels, uint8_t regulatory_domain);
|
||||||
|
|
||||||
int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur);
|
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);
|
int8_t ws_common_allocate_and_init(protocol_interface_info_entry_t *cur);
|
||||||
|
|
|
@ -73,12 +73,14 @@ typedef struct ws_hopping_schedule_s {
|
||||||
uint8_t operating_class; /**< PHY operating class default to 1 */
|
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 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_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 uc_channel_function; /**< 0: Fixed channel, 1:TR51CF, 2: Direct Hash, 3: Vendor defined */
|
||||||
|
uint8_t bc_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 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 number_of_channels; /**< derived from regulatory domain */
|
||||||
uint8_t clock_drift;
|
uint8_t clock_drift;
|
||||||
uint8_t timing_accurancy;
|
uint8_t timing_accurancy;
|
||||||
uint16_t fixed_channel;
|
uint16_t uc_fixed_channel;
|
||||||
|
uint16_t bc_fixed_channel;
|
||||||
uint16_t fhss_bsi;
|
uint16_t fhss_bsi;
|
||||||
uint32_t fhss_broadcast_interval;
|
uint32_t fhss_broadcast_interval;
|
||||||
uint32_t channel_mask[8];
|
uint32_t channel_mask[8];
|
||||||
|
@ -182,9 +184,19 @@ typedef struct ws_bs_ie {
|
||||||
|
|
||||||
#define WS_FAN_VERSION_1_0 1
|
#define WS_FAN_VERSION_1_0 1
|
||||||
|
|
||||||
#define WS_NEIGHBOR_LINK_TIMEOUT 240
|
#define WS_NEIGHBOR_LINK_TIMEOUT 2200
|
||||||
#define WS_NEIGHBOR_NUD_TIMEOUT WS_NEIGHBOR_LINK_TIMEOUT / 2
|
#define WS_NEIGHBOR_NUD_TIMEOUT WS_NEIGHBOR_LINK_TIMEOUT / 2
|
||||||
|
|
||||||
|
#define WS_NEIGBOR_ETX_SAMPLE_MAX 3
|
||||||
|
|
||||||
|
#define WS_PROBE_INIT_BASE_SECONDS 8
|
||||||
|
|
||||||
|
#define WS_NUD_RAND_PROBABILITY 1
|
||||||
|
|
||||||
|
#define WS_NUD_RANDOM_SAMPLE_LENGTH WS_NEIGHBOR_NUD_TIMEOUT / 2
|
||||||
|
|
||||||
|
#define WS_NUD_RANDOM_COMPARE (WS_NUD_RAND_PROBABILITY*WS_NUD_RANDOM_SAMPLE_LENGTH) / 100
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Threshold (referenced to DEVICE_MIN_SENS) above which a neighbor node may be considered for inclusion into candidate parent set
|
* Threshold (referenced to DEVICE_MIN_SENS) above which a neighbor node may be considered for inclusion into candidate parent set
|
||||||
*/
|
*/
|
||||||
|
@ -203,4 +215,12 @@ typedef struct ws_bs_ie {
|
||||||
*/
|
*/
|
||||||
#define WS_RPL_DIS_TIMEOUT 1800
|
#define WS_RPL_DIS_TIMEOUT 1800
|
||||||
|
|
||||||
|
/* Default FHSS timing information
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define WS_FHSS_UC_DWELL_INTERVAL 250;
|
||||||
|
#define WS_FHSS_BC_INTERVAL 800;
|
||||||
|
#define WS_FHSS_BC_DWELL_INTERVAL 200;
|
||||||
|
|
||||||
|
|
||||||
#endif /* WS_COMMON_DEFINES_H_ */
|
#endif /* WS_COMMON_DEFINES_H_ */
|
||||||
|
|
|
@ -21,11 +21,16 @@
|
||||||
#include "fhss_ws_extension.h"
|
#include "fhss_ws_extension.h"
|
||||||
#include "6LoWPAN/ws/ws_common_defines.h"
|
#include "6LoWPAN/ws/ws_common_defines.h"
|
||||||
|
|
||||||
|
#define RSL_UNITITIALIZED 0x7fff
|
||||||
|
|
||||||
typedef struct ws_neighbor_class_entry {
|
typedef struct ws_neighbor_class_entry {
|
||||||
fhss_ws_neighbor_timing_info_t fhss_data;
|
fhss_ws_neighbor_timing_info_t fhss_data;
|
||||||
uint16_t rsl_in; /*!< RSL EWMA heard from neighbour*/
|
uint16_t rsl_in; /*!< RSL EWMA heard from neighbour*/
|
||||||
uint16_t rsl_out; /*!< RSL EWMA heard by neighbour*/
|
uint16_t rsl_out; /*!< RSL EWMA heard by neighbour*/
|
||||||
|
uint16_t routing_cost; /*!< ETX to border Router. */
|
||||||
bool candidate_parent:1;
|
bool candidate_parent:1;
|
||||||
|
bool broadcast_timing_info_stored:1;
|
||||||
|
bool broadcast_shedule_info_stored:1;
|
||||||
} ws_neighbor_class_entry_t;
|
} ws_neighbor_class_entry_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -583,6 +583,24 @@ buffer_t *ipv6_forwarding_down(buffer_t *buf)
|
||||||
return icmpv6_error(buf, NULL, ICMPV6_TYPE_ERROR_DESTINATION_UNREACH, ICMPV6_CODE_DST_UNREACH_NO_ROUTE, 0);
|
return icmpv6_error(buf, NULL, ICMPV6_TYPE_ERROR_DESTINATION_UNREACH, ICMPV6_CODE_DST_UNREACH_NO_ROUTE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Consider multicast forwarding /before/ calling routing code to modify
|
||||||
|
* extension headers - if that actually decides to tunnel it will
|
||||||
|
* overwrite the buffer's src_sa and dst_sa, when we want to consider
|
||||||
|
* forwarding the inner packet. This ordering works out for our only
|
||||||
|
* header-modifying multicast case of MPL:
|
||||||
|
* 1) We never want to forward packets with MPL headers, which means the
|
||||||
|
* outer packet in a tunnel gets ignored anyway.
|
||||||
|
* 2) This also means we don't have to worry that we're forwarding packets
|
||||||
|
* with the extension header not filled in yet.
|
||||||
|
* If we ever do have a multicast system where we are working with
|
||||||
|
* extension headers and forwarding those across interfaces, ipv6_get_exthdrs
|
||||||
|
* system will need a rework - probably split the "try MODIFY" call from the
|
||||||
|
* subsequent "give me tunnel parameters" part.
|
||||||
|
*/
|
||||||
|
if (!buf->ip_routed_up && addr_is_ipv6_multicast(buf->dst_sa.address)) {
|
||||||
|
buf = ipv6_consider_forwarding_multicast_packet(buf, buf->interface, true);
|
||||||
|
}
|
||||||
|
|
||||||
/* Allow routing code to update extension headers */
|
/* Allow routing code to update extension headers */
|
||||||
int16_t exthdr_result;
|
int16_t exthdr_result;
|
||||||
buf = ipv6_get_exthdrs(buf, IPV6_EXTHDR_MODIFY, &exthdr_result);
|
buf = ipv6_get_exthdrs(buf, IPV6_EXTHDR_MODIFY, &exthdr_result);
|
||||||
|
@ -593,10 +611,6 @@ buffer_t *ipv6_forwarding_down(buffer_t *buf)
|
||||||
goto drop;
|
goto drop;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!buf->ip_routed_up && addr_is_ipv6_multicast(buf->dst_sa.address)) {
|
|
||||||
buf = ipv6_consider_forwarding_multicast_packet(buf, buf->interface, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Routing code may say it needs to tunnel to add headers - loop back to IP layer if requested */
|
/* Routing code may say it needs to tunnel to add headers - loop back to IP layer if requested */
|
||||||
if (exthdr_result == IPV6_EXTHDR_MODIFY_TUNNEL) {
|
if (exthdr_result == IPV6_EXTHDR_MODIFY_TUNNEL) {
|
||||||
/* Avoid an infinite loop in the event of routing code failure - never
|
/* Avoid an infinite loop in the event of routing code failure - never
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
#include "DHCPv6_Server/DHCPv6_server_service.h"
|
#include "DHCPv6_Server/DHCPv6_server_service.h"
|
||||||
#include "common_functions.h"
|
#include "common_functions.h"
|
||||||
#include "NWK_INTERFACE/Include/protocol.h"
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
#include "6LoWPAN/Thread/thread_bbr_api_internal.h"
|
|
||||||
#include "Common_Protocols/icmpv6.h"
|
#include "Common_Protocols/icmpv6.h"
|
||||||
#include "dhcp_service_api.h"
|
#include "dhcp_service_api.h"
|
||||||
|
|
||||||
|
@ -57,9 +56,6 @@ static int8_t dhcpv6_service_tasklet = -1;
|
||||||
|
|
||||||
static arm_event_storage_t *dhcp_timer_storage = NULL;
|
static arm_event_storage_t *dhcp_timer_storage = NULL;
|
||||||
|
|
||||||
static void DHCPV6_server_service_remove_GUA_from_neighcache(protocol_interface_info_entry_t *cur, uint8_t *targetAddress);
|
|
||||||
|
|
||||||
|
|
||||||
static bool DHCP_server_service_timer_start(void)
|
static bool DHCP_server_service_timer_start(void)
|
||||||
{
|
{
|
||||||
if(!dhcp_timer_storage) {
|
if(!dhcp_timer_storage) {
|
||||||
|
@ -101,19 +97,16 @@ int DHCPv6_server_respond_client(dhcpv6_gua_server_entry_s *serverBase, dhcpv6_r
|
||||||
nonTemporalAddress.validLifeTime = dhcp_allocated_address->lifetime;
|
nonTemporalAddress.validLifeTime = dhcp_allocated_address->lifetime;
|
||||||
nonTemporalAddress.preferredLifeTime = dhcp_allocated_address->preferredLifetime;
|
nonTemporalAddress.preferredLifeTime = dhcp_allocated_address->preferredLifetime;
|
||||||
|
|
||||||
// If this is solicit from existing address, flush ND cache.
|
if (serverBase->addCb) {
|
||||||
if (allocateNew) {
|
dhcp_address_cache_update_t update_info;
|
||||||
// coverity[returned_null] for ignoring protocol_stack_interface_info_get_by_id NULL return
|
update_info.allocatedAddress = dhcp_allocated_address->nonTemporalAddress;
|
||||||
DHCPV6_server_service_remove_GUA_from_neighcache(protocol_stack_interface_info_get_by_id(serverBase->interfaceId), nonTemporalAddress.requestedAddress);
|
update_info.allocatedNewAddress = allocateNew;
|
||||||
}
|
update_info.validLifeTime = nonTemporalAddress.validLifeTime;
|
||||||
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
|
if (!serverBase->addCb(serverBase->interfaceId, &update_info, serverBase->guaPrefix)) {
|
||||||
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) {
|
|
||||||
address_allocated = false;
|
address_allocated = false;
|
||||||
libdhcpv6_address_rm_from_allocated_list(serverBase,dhcp_allocated_address->nonTemporalAddress);
|
libdhcpv6_address_rm_from_allocated_list(serverBase,dhcp_allocated_address->nonTemporalAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,30 +206,6 @@ void DHCPv6_server_service_tasklet(arm_event_s *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DHCPV6_server_service_remove_GUA_from_neighcache(protocol_interface_info_entry_t *cur, uint8_t *targetAddress)
|
|
||||||
{
|
|
||||||
ipv6_neighbour_t *neighbour_entry;
|
|
||||||
|
|
||||||
neighbour_entry = ipv6_neighbour_lookup(&cur->ipv6_neighbour_cache, targetAddress);
|
|
||||||
if (neighbour_entry) {
|
|
||||||
tr_debug("Remove from neigh Cache: %s", tr_ipv6(targetAddress));
|
|
||||||
ipv6_neighbour_entry_remove(&cur->ipv6_neighbour_cache, neighbour_entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DHCPv6_server_service_address_preferred_timeout_handler(int8_t interfaceId, uint8_t *targetAddress)
|
|
||||||
{
|
|
||||||
tr_warn("Address Preferred Timeout");
|
|
||||||
protocol_interface_info_entry_t *cur = 0;
|
|
||||||
//allocate Socket Service
|
|
||||||
|
|
||||||
cur = protocol_stack_interface_info_get_by_id(interfaceId);
|
|
||||||
if (cur) {
|
|
||||||
ipv6_route_delete(targetAddress, 128, interfaceId, NULL, ROUTE_THREAD_PROXIED_HOST);
|
|
||||||
DHCPV6_server_service_remove_GUA_from_neighcache(cur, targetAddress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int8_t dhcpv6_server_service_tasklet_generated(void)
|
static int8_t dhcpv6_server_service_tasklet_generated(void)
|
||||||
{
|
{
|
||||||
if (dhcpv6_service_tasklet == -1) {
|
if (dhcpv6_service_tasklet == -1) {
|
||||||
|
@ -267,28 +236,21 @@ int DHCPv6_server_service_init(int8_t interface, uint8_t guaPrefix[static 16], u
|
||||||
//allocate Socket Service
|
//allocate Socket Service
|
||||||
socketInstance = dhcp_service_init(interface, DHCP_INSTANCE_SERVER, DHCPV6_server_service_request_handler);
|
socketInstance = dhcp_service_init(interface, DHCP_INSTANCE_SERVER, DHCPV6_server_service_request_handler);
|
||||||
cur = protocol_stack_interface_info_get_by_id(interface);
|
cur = protocol_stack_interface_info_get_by_id(interface);
|
||||||
if (cur) {
|
if (!cur) {
|
||||||
if (dhcpv6_server_service_tasklet_generated() < 0) {
|
return -1;
|
||||||
retVal = -2;
|
}
|
||||||
} else if (!DHCP_server_service_timer_start()) {
|
|
||||||
retVal = -2;
|
|
||||||
} else {
|
|
||||||
//allocate server
|
|
||||||
dhcpv6_gua_server_entry_s *serverInfo = libdhcpv6_gua_server_allocate(guaPrefix, interface, cur->mac, DHCPV6_DUID_HARDWARE_EUI64_TYPE, DHCPv6_server_service_address_preferred_timeout_handler);
|
|
||||||
if (serverInfo) {
|
|
||||||
//if_address_entry_t *def_address = NULL;
|
|
||||||
uint8_t temp[16];
|
|
||||||
uint8_t *ptr = temp;
|
|
||||||
//define address & Route advert's
|
|
||||||
memcpy(ptr, guaPrefix, 8);
|
|
||||||
ptr += 8;
|
|
||||||
memcpy(ptr, cur->iid_slaac, 8);
|
|
||||||
|
|
||||||
serverInfo->socketInstance_id = socketInstance;
|
if (dhcpv6_server_service_tasklet_generated() < 0) {
|
||||||
socketInstance = 0;
|
retVal = -2;
|
||||||
//Generate Address for current interface
|
} else if (!DHCP_server_service_timer_start()) {
|
||||||
retVal = 0;
|
retVal = -2;
|
||||||
}
|
} else {
|
||||||
|
//allocate server
|
||||||
|
dhcpv6_gua_server_entry_s *serverInfo = libdhcpv6_gua_server_allocate(guaPrefix, interface, cur->mac, DHCPV6_DUID_HARDWARE_EUI64_TYPE);
|
||||||
|
if (serverInfo) {
|
||||||
|
serverInfo->socketInstance_id = socketInstance;
|
||||||
|
socketInstance = 0;
|
||||||
|
retVal = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (socketInstance > 0) {
|
if (socketInstance > 0) {
|
||||||
|
@ -303,25 +265,6 @@ void DHCPv6_server_service_timeout_cb(uint32_t timeUpdateInSeconds)
|
||||||
libdhcpv6_gua_servers_time_update(timeUpdateInSeconds);
|
libdhcpv6_gua_servers_time_update(timeUpdateInSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DHCPv6_GUA64_ML64_route_control(int8_t interfaceId, uint8_t *allocatedGuaAddress, uint8_t *clientEUID64, uint8_t *meshLocalPrefix, bool deleteMapping)
|
|
||||||
{
|
|
||||||
uint8_t ml64[16];
|
|
||||||
uint8_t *ptr = ml64;
|
|
||||||
memcpy(ptr, meshLocalPrefix, 8);
|
|
||||||
ptr += 8;
|
|
||||||
memcpy(ptr, clientEUID64, 8);
|
|
||||||
*ptr ^= 2;
|
|
||||||
//Generate Route Info
|
|
||||||
if (deleteMapping) {
|
|
||||||
ipv6_route_delete(allocatedGuaAddress, 128, interfaceId, ml64, ROUTE_STATIC);
|
|
||||||
} else if (ipv6_route_add(allocatedGuaAddress, 128, interfaceId, ml64, ROUTE_STATIC, 0xffffffff, 0) == 0) {
|
|
||||||
tr_debug("Route ADD OK");
|
|
||||||
} else {
|
|
||||||
tr_warn("Route Add fail");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Delete dhcp thread dhcp router ID server.
|
/* Delete dhcp thread dhcp router ID server.
|
||||||
*
|
*
|
||||||
* When this is called it close selected service and free all allocated memory.
|
* When this is called it close selected service and free all allocated memory.
|
||||||
|
@ -332,30 +275,32 @@ void DHCPv6_GUA64_ML64_route_control(int8_t interfaceId, uint8_t *allocatedGuaAd
|
||||||
*/
|
*/
|
||||||
void DHCPv6_server_service_delete(int8_t interface, uint8_t guaPrefix[static 16], bool delete_gua_addresses)
|
void DHCPv6_server_service_delete(int8_t interface, uint8_t guaPrefix[static 16], bool delete_gua_addresses)
|
||||||
{
|
{
|
||||||
protocol_interface_info_entry_t *curPtr = 0;
|
dhcpv6_gua_server_entry_s *serverInfo = libdhcpv6_server_data_get_by_prefix_and_interfaceid(interface, guaPrefix);
|
||||||
//allocate Socket Service
|
if (serverInfo) {
|
||||||
|
ns_list_foreach_safe(dhcpv6_alloacted_address_entry_t, cur, &serverInfo->allocatedAddressList) {
|
||||||
curPtr = protocol_stack_interface_info_get_by_id(interface);
|
//Delete Server data base
|
||||||
if (curPtr) {
|
if (serverInfo->removeCb) {
|
||||||
dhcpv6_gua_server_entry_s *serverInfo = libdhcpv6_server_data_get_by_prefix_and_interfaceid(interface, guaPrefix);
|
serverInfo->removeCb(interface, cur->nonTemporalAddress, NULL);
|
||||||
if (serverInfo) {
|
|
||||||
ns_list_foreach_safe(dhcpv6_alloacted_address_entry_t, cur, &serverInfo->allocatedAddressList) {
|
|
||||||
//Delete Server data base
|
|
||||||
DHCPV6_server_service_remove_GUA_from_neighcache(curPtr, cur->nonTemporalAddress);
|
|
||||||
}
|
}
|
||||||
// Clean all /128 'Thread Proxy' routes to self and others added when acting as a DHCP server
|
|
||||||
ipv6_route_table_remove_info(curPtr->id, ROUTE_THREAD_PROXIED_HOST,serverInfo->guaPrefix);
|
|
||||||
dhcp_service_delete(serverInfo->socketInstance_id);
|
|
||||||
}
|
}
|
||||||
|
if (serverInfo->removeCb) {
|
||||||
|
// Clean all /128 'Thread Proxy' routes to self and others added when acting as a DHCP server
|
||||||
|
serverInfo->removeCb(interface, NULL, serverInfo->guaPrefix);
|
||||||
|
}
|
||||||
|
dhcp_service_delete(serverInfo->socketInstance_id);
|
||||||
|
}
|
||||||
|
|
||||||
if (delete_gua_addresses) {
|
if (delete_gua_addresses) {
|
||||||
|
protocol_interface_info_entry_t *curPtr = protocol_stack_interface_info_get_by_id(interface);
|
||||||
|
if (curPtr) {
|
||||||
protocol_core_dhcpv6_allocated_address_remove(curPtr, guaPrefix);
|
protocol_core_dhcpv6_allocated_address_remove(curPtr, guaPrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
libdhcpv6_gua_server_free_by_prefix_and_interfaceid(guaPrefix, interface);
|
|
||||||
|
|
||||||
DHCP_server_service_timer_stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
libdhcpv6_gua_server_free_by_prefix_and_interfaceid(guaPrefix, interface);
|
||||||
|
|
||||||
|
DHCP_server_service_timer_stop();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Control GUA address for client by DUI.Default value is true
|
/* Control GUA address for client by DUI.Default value is true
|
||||||
|
@ -379,33 +324,15 @@ int DHCPv6_server_service_set_address_autonous_flag(int8_t interface, uint8_t gu
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable or disable GUA64 Address mapping to ML64
|
void DHCPv6_server_service_callback_set(int8_t interface, uint8_t guaPrefix[static 16], dhcp_address_prefer_remove_cb *remove_cb, dhcp_address_add_notify_cb *add_cb)
|
||||||
*
|
|
||||||
*
|
|
||||||
* /param interface interface id of this thread instance.
|
|
||||||
* /param guaPrefix Prefix which will be removed
|
|
||||||
* /param mode
|
|
||||||
* /param meshLocalPrefix mesh local prefix for generate ML6 from client EUID64
|
|
||||||
*/
|
|
||||||
int DHCPv6_server_service_set_gua_address_mapping(int8_t interface, uint8_t guaPrefix[static 16], bool mode, uint8_t meshLocalPrefix[8])
|
|
||||||
{
|
{
|
||||||
int retVal = -1;
|
dhcpv6_gua_server_entry_s *serverInfo = libdhcpv6_server_data_get_by_prefix_and_interfaceid(interface, guaPrefix);
|
||||||
dhcpv6_gua_server_entry_s *serverInfo;
|
if (!serverInfo) {
|
||||||
|
return;
|
||||||
serverInfo = libdhcpv6_server_data_get_by_prefix_and_interfaceid(interface, guaPrefix);
|
|
||||||
if (serverInfo) {
|
|
||||||
if (mode == true && meshLocalPrefix == NULL) {
|
|
||||||
retVal = -2;
|
|
||||||
} else {
|
|
||||||
serverInfo->enableAddressMapping = mode;
|
|
||||||
if (meshLocalPrefix) {
|
|
||||||
memcpy(serverInfo->meshLocalPrefix, meshLocalPrefix, 8);
|
|
||||||
}
|
|
||||||
retVal = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return retVal;
|
serverInfo->addCb = add_cb;
|
||||||
|
serverInfo->removeCb = remove_cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SET max accepted clients to server, Default is 200
|
/* SET max accepted clients to server, Default is 200
|
||||||
|
@ -453,21 +380,6 @@ int DHCPv6_server_service_set_address_validlifetime(int8_t interface, uint8_t gu
|
||||||
}
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DHCPv6_server_service_gua_target_mac_check(int8_t interfaceId, const uint8_t *targetGUA, uint8_t *targetEUI64)
|
|
||||||
{
|
|
||||||
dhcpv6_gua_server_entry_s *serverInfo = libdhcpv6_server_data_get_by_prefix_and_interfaceid(interfaceId, targetGUA);
|
|
||||||
if (serverInfo) {
|
|
||||||
dhcpv6_alloacted_address_entry_t *entry = libdhcpv6_address_get_from_allocated_list(serverInfo, targetGUA);
|
|
||||||
if (entry) {
|
|
||||||
if (entry->preferredLifetime && (entry->linkType == DHCPV6_DUID_HARDWARE_EUI64_TYPE)) {
|
|
||||||
memcpy(targetEUI64, entry->linkId, 8);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
int DHCPv6_server_service_init(int8_t interface, uint8_t guaPrefix[static 16], uint8_t serverDUID[static 8], uint16_t serverDUIDType)
|
int DHCPv6_server_service_init(int8_t interface, uint8_t guaPrefix[static 16], uint8_t serverDUID[static 8], uint16_t serverDUIDType)
|
||||||
|
@ -497,15 +409,6 @@ int DHCPv6_server_service_set_address_autonous_flag(int8_t interface, uint8_t gu
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int DHCPv6_server_service_set_gua_address_mapping(int8_t interface, uint8_t guaPrefix[static 16], bool mode, uint8_t meshLocalPrefix[8])
|
|
||||||
{
|
|
||||||
(void) interface;
|
|
||||||
(void) guaPrefix;
|
|
||||||
(void) mode;
|
|
||||||
(void) meshLocalPrefix;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int DHCPv6_server_service_set_max_clients_accepts_count(int8_t interface, uint8_t guaPrefix[static 16], uint32_t maxClientCount)
|
int DHCPv6_server_service_set_max_clients_accepts_count(int8_t interface, uint8_t guaPrefix[static 16], uint32_t maxClientCount)
|
||||||
{
|
{
|
||||||
(void) interface;
|
(void) interface;
|
||||||
|
@ -522,13 +425,5 @@ int DHCPv6_server_service_set_address_validlifetime(int8_t interface, uint8_t gu
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int DHCPv6_server_service_gua_target_mac_check(int8_t interfaceId, const uint8_t *targetGUA, uint8_t *targetEUI64)
|
|
||||||
{
|
|
||||||
(void) interfaceId;
|
|
||||||
(void) targetGUA;
|
|
||||||
(void) targetEUI64;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,6 +23,10 @@
|
||||||
|
|
||||||
#ifndef DHCPV6_SERVER_SERVICE_H_
|
#ifndef DHCPV6_SERVER_SERVICE_H_
|
||||||
#define DHCPV6_SERVER_SERVICE_H_
|
#define DHCPV6_SERVER_SERVICE_H_
|
||||||
|
#ifdef HAVE_DHCPV6_SERVER
|
||||||
|
#include "libDHCPv6/libDHCPv6.h"
|
||||||
|
#include "libDHCPv6/libDHCPv6_server.h"
|
||||||
|
|
||||||
/* Initialize dhcp Global address server.
|
/* Initialize dhcp Global address server.
|
||||||
*
|
*
|
||||||
* This instance needs to bee initialized once for each thread network interface.
|
* This instance needs to bee initialized once for each thread network interface.
|
||||||
|
@ -38,6 +42,10 @@
|
||||||
*/
|
*/
|
||||||
int DHCPv6_server_service_init(int8_t interface, uint8_t guaPrefix[static 16], uint8_t serverDUID[static 8], uint16_t serverDUIDType);
|
int DHCPv6_server_service_init(int8_t interface, uint8_t guaPrefix[static 16], uint8_t serverDUID[static 8], uint16_t serverDUIDType);
|
||||||
|
|
||||||
|
|
||||||
|
void DHCPv6_server_service_callback_set(int8_t interface, uint8_t guaPrefix[static 16], dhcp_address_prefer_remove_cb *remove_cb, dhcp_address_add_notify_cb *add_cb);
|
||||||
|
|
||||||
|
|
||||||
/* Delete dhcp thread dhcp router ID server.
|
/* Delete dhcp thread dhcp router ID server.
|
||||||
*
|
*
|
||||||
* When this is called it close selected service and free all allocated memory.
|
* When this is called it close selected service and free all allocated memory.
|
||||||
|
@ -51,8 +59,6 @@ void DHCPv6_server_service_delete(int8_t interface, uint8_t guaPrefix[static 16]
|
||||||
|
|
||||||
void DHCPv6_server_service_timeout_cb(uint32_t timeUpdateInSeconds);
|
void DHCPv6_server_service_timeout_cb(uint32_t timeUpdateInSeconds);
|
||||||
|
|
||||||
//void DHCPv6_GUA64_ML64_route_control(int8_t interfaceId, uint8_t *allocatedGuaAddress, uint8_t *clientEUID64, uint8_t *meshLocalPrefix, bool deleteMapping);
|
|
||||||
|
|
||||||
/* Control GUA address for client by DUI.Default value is true
|
/* Control GUA address for client by DUI.Default value is true
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
@ -63,16 +69,6 @@ void DHCPv6_server_service_timeout_cb(uint32_t timeUpdateInSeconds);
|
||||||
int DHCPv6_server_service_set_address_autonous_flag(int8_t interface, uint8_t guaPrefix[static 16], bool mode);
|
int DHCPv6_server_service_set_address_autonous_flag(int8_t interface, uint8_t guaPrefix[static 16], bool mode);
|
||||||
|
|
||||||
|
|
||||||
/* Enable or disable GUA64 Address mapping to ML64
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* /param interface interface id of this thread instance.
|
|
||||||
* /param guaPrefix Prefix which will be removed
|
|
||||||
* /param mode
|
|
||||||
* /param meshLocalPrefix mesh local prefix for generate ML6 from client EUID64
|
|
||||||
*/
|
|
||||||
int DHCPv6_server_service_set_gua_address_mapping(int8_t interface, uint8_t guaPrefix[static 16], bool mode, uint8_t meshLocalPrefix[8]);
|
|
||||||
|
|
||||||
/* SET max accepted clients to server, Default is 200
|
/* SET max accepted clients to server, Default is 200
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
@ -91,7 +87,7 @@ int DHCPv6_server_service_set_max_clients_accepts_count(int8_t interface, uint8_
|
||||||
* /param validLifeTimne in seconds
|
* /param validLifeTimne in seconds
|
||||||
*/
|
*/
|
||||||
int DHCPv6_server_service_set_address_validlifetime(int8_t interface, uint8_t guaPrefix[static 16], uint32_t validLifeTimne);
|
int DHCPv6_server_service_set_address_validlifetime(int8_t interface, uint8_t guaPrefix[static 16], uint32_t validLifeTimne);
|
||||||
|
#else
|
||||||
|
#define DHCPv6_server_service_delete(interface, guaPrefix, delete_gua_addresses)
|
||||||
int DHCPv6_server_service_gua_target_mac_check(int8_t interfaceId, const uint8_t *targetGUA, uint8_t *targetEUI64);
|
#endif
|
||||||
#endif /* DHCPV6_SERVER_SERVICE_H_ */
|
#endif /* DHCPV6_SERVER_SERVICE_H_ */
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* 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 DHCPV6_CLIENT_API_H_
|
||||||
|
#define DHCPV6_CLIENT_API_H_
|
||||||
|
#include <ns_types.h>
|
||||||
|
|
||||||
|
/* DHCP client implementation.
|
||||||
|
*
|
||||||
|
* Responsibilities of this module are:
|
||||||
|
* - handle Global address queries and refresh inside network.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Initialize dhcp client.
|
||||||
|
*
|
||||||
|
* This instance needs to bee initialized once for each network interface.
|
||||||
|
* if only one thread instance is supported this is needed to call only once.
|
||||||
|
*
|
||||||
|
* /param interface interface id of this instance.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void dhcp_client_init(int8_t interface);
|
||||||
|
|
||||||
|
/* Delete dhcp client.
|
||||||
|
*
|
||||||
|
* When this is called all addressed assigned by this module are removed from stack.
|
||||||
|
*/
|
||||||
|
void dhcp_client_delete(int8_t interface);
|
||||||
|
|
||||||
|
/* Global address handler.
|
||||||
|
*
|
||||||
|
* This module updates the addresses from dhcp server and sets them in stack.
|
||||||
|
* this module makes refresh of address when needed.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* give dhcp server and prefix for global address assignment
|
||||||
|
*
|
||||||
|
* /param interface interface where address is got
|
||||||
|
* /param dhcp_addr dhcp server ML16 address where address is registered.
|
||||||
|
* /param prefix dhcp server ML16 address where address is registered.
|
||||||
|
* /param mac64 64 bit mac address for identifieng client.
|
||||||
|
* /param error_cb error callback that is called if address cannot be created or becomes invalid.
|
||||||
|
* /param register_status true if address registered.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef void (dhcp_client_global_adress_cb)(int8_t interface, uint8_t dhcp_addr[static 16], uint8_t prefix[static 16], bool register_status);
|
||||||
|
|
||||||
|
int dhcp_client_get_global_address(int8_t interface, uint8_t dhcp_addr[static 16], uint8_t prefix[static 16], uint8_t mac64[static 8], dhcp_client_global_adress_cb *error_cb);
|
||||||
|
|
||||||
|
/* Renew all leased adddresses might be used when short address changes
|
||||||
|
*
|
||||||
|
* /param interface interface where address is got
|
||||||
|
*/
|
||||||
|
void dhcp_client_global_address_renew(int8_t interface);
|
||||||
|
|
||||||
|
/* Delete address from device
|
||||||
|
* if prefix is NULL all are deleted
|
||||||
|
*
|
||||||
|
* /param interface interface where address is got
|
||||||
|
* /param prefix dhcp server ML16 address where address is registered.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void dhcp_client_global_address_delete(int8_t interface, uint8_t dhcp_addr[static 16], uint8_t prefix[static 16]);
|
||||||
|
|
||||||
|
|
||||||
|
void dhcp_relay_agent_enable(int8_t interface, uint8_t border_router_address[static 16]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* DHCPV6_CLIENT_API_H_ */
|
|
@ -1,34 +1,21 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2018, Arm Limited and affiliates.
|
* Copyright (c) 2018, Arm Limited and affiliates.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* 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"
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
* See the License for the specific language governing permissions and
|
||||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
* limitations under the License.
|
||||||
* 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 "nsconfig.h"
|
||||||
#ifdef HAVE_THREAD
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ns_types.h>
|
#include <ns_types.h>
|
||||||
#include <ns_trace.h>
|
#include <ns_trace.h>
|
||||||
|
@ -36,31 +23,30 @@
|
||||||
#include "ns_list.h"
|
#include "ns_list.h"
|
||||||
#include "common_functions.h"
|
#include "common_functions.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_DHCPV6
|
||||||
#include "dhcp_service_api.h"
|
#include "dhcp_service_api.h"
|
||||||
#include "thread_dhcpv6_client.h"
|
#include "dhcpv6_client_api.h"
|
||||||
#include "libDHCPv6/libDHCPv6.h"
|
#include "libDHCPv6/libDHCPv6.h"
|
||||||
#include "NWK_INTERFACE/Include/protocol.h"
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
#include "6LoWPAN/Thread/thread_common.h"
|
|
||||||
#include "6LoWPAN/Thread/thread_bootstrap.h"
|
|
||||||
|
|
||||||
#define TRACE_GROUP "TDHP"
|
#define TRACE_GROUP "DHP"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
thread_dhcp_client_global_adress_cb *global_address_cb;
|
dhcp_client_global_adress_cb *global_address_cb;
|
||||||
uint16_t service_instance;
|
uint16_t service_instance;
|
||||||
|
uint16_t relay_instance;
|
||||||
uint8_t libDhcp_instance;
|
uint8_t libDhcp_instance;
|
||||||
int8_t interface;
|
int8_t interface;
|
||||||
} thread_dhcp_client_class_t;
|
} dhcp_client_class_t;
|
||||||
|
|
||||||
thread_dhcp_client_class_t dhcp_client;
|
static dhcp_client_class_t dhcp_client;
|
||||||
|
|
||||||
void thread_dhcpv6_client_set_address(int8_t interface_id, dhcpv6_client_server_data_t *srv_data_ptr);
|
void dhcpv6_client_set_address(int8_t interface_id, dhcpv6_client_server_data_t *srv_data_ptr);
|
||||||
|
|
||||||
|
|
||||||
void thread_dhcp_client_init(int8_t interface)
|
void dhcp_client_init(int8_t interface)
|
||||||
{
|
{
|
||||||
// No support for multible thread instances yet.
|
// No support for multible instances yet.
|
||||||
dhcp_client.service_instance = dhcp_service_init(interface, DHCP_INSTANCE_CLIENT, NULL);
|
dhcp_client.service_instance = dhcp_service_init(interface, DHCP_INSTANCE_CLIENT, NULL);
|
||||||
dhcp_client.interface = interface;
|
dhcp_client.interface = interface;
|
||||||
dhcp_client.libDhcp_instance = libdhcpv6_nonTemporal_entry_get_unique_instance_id();
|
dhcp_client.libDhcp_instance = libdhcpv6_nonTemporal_entry_get_unique_instance_id();
|
||||||
|
@ -68,7 +54,13 @@ void thread_dhcp_client_init(int8_t interface)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_dhcp_client_delete(int8_t interface)
|
void dhcp_relay_agent_enable(int8_t interface, uint8_t border_router_address[static 16])
|
||||||
|
{
|
||||||
|
dhcp_client.relay_instance = dhcp_service_init(interface, DHCP_INTANCE_RELAY_AGENT, NULL);
|
||||||
|
dhcp_service_relay_instance_enable(dhcp_client.relay_instance, border_router_address);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dhcp_client_delete(int8_t interface)
|
||||||
{
|
{
|
||||||
protocol_interface_info_entry_t *cur = NULL;
|
protocol_interface_info_entry_t *cur = NULL;
|
||||||
dhcpv6_client_server_data_t *srv_data_ptr;
|
dhcpv6_client_server_data_t *srv_data_ptr;
|
||||||
|
@ -96,7 +88,7 @@ void thread_dhcp_client_delete(int8_t interface)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void thread_dhcpv6_client_send_error_cb(dhcpv6_client_server_data_t *srv_data_ptr)
|
void dhcpv6_client_send_error_cb(dhcpv6_client_server_data_t *srv_data_ptr)
|
||||||
{
|
{
|
||||||
if (srv_data_ptr != NULL) {
|
if (srv_data_ptr != NULL) {
|
||||||
|
|
||||||
|
@ -159,12 +151,11 @@ int dhcp_solicit_resp_cb(uint16_t instance_id, void *ptr, uint8_t msg_name, uin
|
||||||
srv_data_ptr->iaNontemporalAddress.validLifetime = dhcp_ia_non_temporal_params.validLifeTime;
|
srv_data_ptr->iaNontemporalAddress.validLifetime = dhcp_ia_non_temporal_params.validLifeTime;
|
||||||
memcpy(srv_data_ptr->serverLinkId, serverId.linkID, 8);
|
memcpy(srv_data_ptr->serverLinkId, serverId.linkID, 8);
|
||||||
srv_data_ptr->serverLinkType = serverId.linkType;
|
srv_data_ptr->serverLinkType = serverId.linkType;
|
||||||
srv_data_ptr->serverLinkType = serverId.linkType;
|
|
||||||
srv_data_ptr->T0 = dhcp_ia_non_temporal_params.T0;
|
srv_data_ptr->T0 = dhcp_ia_non_temporal_params.T0;
|
||||||
srv_data_ptr->T1 = dhcp_ia_non_temporal_params.T1;
|
srv_data_ptr->T1 = dhcp_ia_non_temporal_params.T1;
|
||||||
srv_data_ptr->iaNonTemporalStructValid = true;
|
srv_data_ptr->iaNonTemporalStructValid = true;
|
||||||
|
|
||||||
thread_dhcpv6_client_set_address(dhcp_client.interface, srv_data_ptr);
|
dhcpv6_client_set_address(dhcp_client.interface, srv_data_ptr);
|
||||||
|
|
||||||
|
|
||||||
if (dhcp_client.global_address_cb) {
|
if (dhcp_client.global_address_cb) {
|
||||||
|
@ -172,11 +163,11 @@ int dhcp_solicit_resp_cb(uint16_t instance_id, void *ptr, uint8_t msg_name, uin
|
||||||
}
|
}
|
||||||
return RET_MSG_ACCEPTED;
|
return RET_MSG_ACCEPTED;
|
||||||
error_exit:
|
error_exit:
|
||||||
thread_dhcpv6_client_send_error_cb(srv_data_ptr);
|
dhcpv6_client_send_error_cb(srv_data_ptr);
|
||||||
return RET_MSG_ACCEPTED;
|
return RET_MSG_ACCEPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_dhcp_client_get_global_address(int8_t interface, uint8_t dhcp_addr[static 16], uint8_t prefix[static 16], uint8_t mac64[static 8], thread_dhcp_client_global_adress_cb *error_cb)
|
int dhcp_client_get_global_address(int8_t interface, uint8_t dhcp_addr[static 16], uint8_t prefix[static 16], uint8_t mac64[static 8], dhcp_client_global_adress_cb *error_cb)
|
||||||
{
|
{
|
||||||
dhcpv6_solication_base_packet_s solPacket = {0};
|
dhcpv6_solication_base_packet_s solPacket = {0};
|
||||||
dhcpv6_ia_non_temporal_address_s nonTemporalAddress = {0};
|
dhcpv6_ia_non_temporal_address_s nonTemporalAddress = {0};
|
||||||
|
@ -190,16 +181,19 @@ int thread_dhcp_client_get_global_address(int8_t interface, uint8_t dhcp_addr[st
|
||||||
}
|
}
|
||||||
|
|
||||||
srv_data_ptr = libdhcvp6_nontemporalAddress_server_data_allocate(interface, dhcp_client.libDhcp_instance, mac64, DHCPV6_DUID_HARDWARE_EUI64_TYPE, prefix, dhcp_addr);
|
srv_data_ptr = libdhcvp6_nontemporalAddress_server_data_allocate(interface, dhcp_client.libDhcp_instance, mac64, DHCPV6_DUID_HARDWARE_EUI64_TYPE, prefix, dhcp_addr);
|
||||||
|
if (!srv_data_ptr) {
|
||||||
|
tr_error("OOM srv_data_ptr");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
payload_len = libdhcpv6_solication_message_length(DHCPV6_DUID_HARDWARE_EUI64_TYPE, true, 0);
|
payload_len = libdhcpv6_solication_message_length(DHCPV6_DUID_HARDWARE_EUI64_TYPE, true, 0);
|
||||||
payload_ptr = ns_dyn_mem_temporary_alloc(payload_len);
|
payload_ptr = ns_dyn_mem_temporary_alloc(payload_len);
|
||||||
|
if (!payload_ptr) {
|
||||||
if (payload_ptr == NULL || srv_data_ptr == NULL) {
|
|
||||||
ns_dyn_mem_free(payload_ptr);
|
|
||||||
libdhcvp6_nontemporalAddress_server_data_free(srv_data_ptr);
|
libdhcvp6_nontemporalAddress_server_data_free(srv_data_ptr);
|
||||||
tr_error("Out of memory");
|
tr_error("OOM payload_ptr");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dhcp_client.global_address_cb = error_cb; //TODO Only supporting one instance globaly if we need more for different instances needs code.
|
dhcp_client.global_address_cb = error_cb; //TODO Only supporting one instance globaly if we need more for different instances needs code.
|
||||||
srv_data_ptr->GlobalAddress = true;
|
srv_data_ptr->GlobalAddress = true;
|
||||||
// Build solicit
|
// Build solicit
|
||||||
|
@ -214,17 +208,22 @@ int thread_dhcp_client_get_global_address(int8_t interface, uint8_t dhcp_addr[st
|
||||||
|
|
||||||
// send solicit
|
// send solicit
|
||||||
srv_data_ptr->transActionId = dhcp_service_send_req(dhcp_client.service_instance, 0, srv_data_ptr , dhcp_addr, payload_ptr, payload_len, dhcp_solicit_resp_cb);
|
srv_data_ptr->transActionId = dhcp_service_send_req(dhcp_client.service_instance, 0, srv_data_ptr , dhcp_addr, payload_ptr, payload_len, dhcp_solicit_resp_cb);
|
||||||
return srv_data_ptr->transActionId ? 0 : -1;
|
if (srv_data_ptr->transActionId == 0) {
|
||||||
|
ns_dyn_mem_free(payload_ptr);
|
||||||
|
libdhcvp6_nontemporalAddress_server_data_free(srv_data_ptr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_dhcp_client_global_address_renew(int8_t interface)
|
void dhcp_client_global_address_renew(int8_t interface)
|
||||||
{
|
{
|
||||||
// only prepared for changes in thread specifications
|
|
||||||
(void)interface;
|
(void)interface;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_dhcp_client_global_address_delete(int8_t interface, uint8_t dhcp_addr[static 16], uint8_t prefix[static 16])
|
void dhcp_client_global_address_delete(int8_t interface, uint8_t dhcp_addr[static 16], uint8_t prefix[static 16])
|
||||||
{
|
{
|
||||||
protocol_interface_info_entry_t *cur;
|
protocol_interface_info_entry_t *cur;
|
||||||
dhcpv6_client_server_data_t *srv_data_ptr;
|
dhcpv6_client_server_data_t *srv_data_ptr;
|
||||||
|
@ -249,7 +248,7 @@ void thread_dhcp_client_global_address_delete(int8_t interface, uint8_t dhcp_add
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_dhcpv6_renew(protocol_interface_info_entry_t *interface, if_address_entry_t *addr, if_address_callback_t reason)
|
void dhcpv6_renew(protocol_interface_info_entry_t *interface, if_address_entry_t *addr, if_address_callback_t reason)
|
||||||
{
|
{
|
||||||
dhcpv6_ia_non_temporal_address_s nonTemporalAddress = {0};
|
dhcpv6_ia_non_temporal_address_s nonTemporalAddress = {0};
|
||||||
dhcp_link_options_params_t serverLink;
|
dhcp_link_options_params_t serverLink;
|
||||||
|
@ -275,7 +274,7 @@ void thread_dhcpv6_renew(protocol_interface_info_entry_t *interface, if_address_
|
||||||
payload_len = libdhcpv6_address_request_message_len(srv_data_ptr->clientLinkIdType, srv_data_ptr->serverLinkType, 0);
|
payload_len = libdhcpv6_address_request_message_len(srv_data_ptr->clientLinkIdType, srv_data_ptr->serverLinkType, 0);
|
||||||
payload_ptr = ns_dyn_mem_temporary_alloc(payload_len);
|
payload_ptr = ns_dyn_mem_temporary_alloc(payload_len);
|
||||||
if (payload_ptr == NULL) {
|
if (payload_ptr == NULL) {
|
||||||
addr->state_timer = 200;//Retry after? should there be maximum 20 second retry
|
addr->state_timer = 200; //Retry after 20 seconds
|
||||||
tr_error("Out of memory");
|
tr_error("Out of memory");
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
@ -299,9 +298,14 @@ void thread_dhcpv6_renew(protocol_interface_info_entry_t *interface, if_address_
|
||||||
libdhcpv6_generic_nontemporal_address_message_write(payload_ptr, &packetReq, &nonTemporalAddress, &serverLink);
|
libdhcpv6_generic_nontemporal_address_message_write(payload_ptr, &packetReq, &nonTemporalAddress, &serverLink);
|
||||||
// send solicit
|
// send solicit
|
||||||
srv_data_ptr->transActionId = dhcp_service_send_req(dhcp_client.service_instance, 0, srv_data_ptr, srv_data_ptr->server_address, payload_ptr, payload_len, dhcp_solicit_resp_cb);
|
srv_data_ptr->transActionId = dhcp_service_send_req(dhcp_client.service_instance, 0, srv_data_ptr, srv_data_ptr->server_address, payload_ptr, payload_len, dhcp_solicit_resp_cb);
|
||||||
|
if (srv_data_ptr->transActionId == 0) {
|
||||||
|
ns_dyn_mem_free(payload_ptr);
|
||||||
|
addr->state_timer = 200; //Retry after 20 seconds
|
||||||
|
tr_error("DHCP renew send failed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_dhcpv6_client_set_address(int8_t interface_id, dhcpv6_client_server_data_t *srv_data_ptr)
|
void dhcpv6_client_set_address(int8_t interface_id, dhcpv6_client_server_data_t *srv_data_ptr)
|
||||||
{
|
{
|
||||||
protocol_interface_info_entry_t *cur = NULL;
|
protocol_interface_info_entry_t *cur = NULL;
|
||||||
if_address_entry_t *address_entry = NULL;
|
if_address_entry_t *address_entry = NULL;
|
||||||
|
@ -335,6 +339,7 @@ void thread_dhcpv6_client_set_address(int8_t interface_id, dhcpv6_client_server_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
address_entry->state_timer = renewTimer;
|
address_entry->state_timer = renewTimer;
|
||||||
address_entry->cb = thread_dhcpv6_renew;
|
address_entry->cb = dhcpv6_renew;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -37,7 +37,9 @@ typedef enum mac_event_t {
|
||||||
MAC_TIMER_ACK,
|
MAC_TIMER_ACK,
|
||||||
MAC_TIMER_CCA,
|
MAC_TIMER_CCA,
|
||||||
MAC_TX_FAIL,
|
MAC_TX_FAIL,
|
||||||
MAC_TX_TIMEOUT
|
MAC_TX_TIMEOUT,
|
||||||
|
MAC_UNKNOWN_DESTINATION,
|
||||||
|
MAC_TX_PRECOND_FAIL
|
||||||
} mac_event_t;
|
} mac_event_t;
|
||||||
|
|
||||||
typedef enum mac_tx_status_type_t {
|
typedef enum mac_tx_status_type_t {
|
||||||
|
@ -89,8 +91,12 @@ typedef enum arm_nwk_mlme_event_type {
|
||||||
ARM_NWK_MAC_MLME_INDIRECT_DATA_POLL_AFTER_DATA = 5,
|
ARM_NWK_MAC_MLME_INDIRECT_DATA_POLL_AFTER_DATA = 5,
|
||||||
} arm_nwk_mlme_event_type_e;
|
} arm_nwk_mlme_event_type_e;
|
||||||
|
|
||||||
|
#define ENHANCED_ACK_MAX_LENGTH 255
|
||||||
|
|
||||||
typedef struct dev_driver_tx_buffer {
|
typedef struct dev_driver_tx_buffer {
|
||||||
uint8_t *buf;
|
uint8_t *buf;
|
||||||
|
uint8_t *enhanced_ack_buf;
|
||||||
|
uint16_t ack_len;
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
unsigned priority:2;
|
unsigned priority:2;
|
||||||
} dev_driver_tx_buffer_s;
|
} dev_driver_tx_buffer_s;
|
||||||
|
@ -134,6 +140,11 @@ typedef struct mac_tx_status_t {
|
||||||
uint8_t retry;
|
uint8_t retry;
|
||||||
} mac_tx_status_t;
|
} mac_tx_status_t;
|
||||||
|
|
||||||
|
typedef struct mac_mcps_data_conf_fail_s {
|
||||||
|
uint8_t msduHandle; /**< Handle associated with MSDU */
|
||||||
|
uint8_t status; /**< Status of the failing MSDU transmission */
|
||||||
|
} mac_mcps_data_conf_fail_t;
|
||||||
|
|
||||||
typedef struct protocol_interface_rf_mac_setup {
|
typedef struct protocol_interface_rf_mac_setup {
|
||||||
int8_t mac_interface_id;
|
int8_t mac_interface_id;
|
||||||
bool macUpState;
|
bool macUpState;
|
||||||
|
@ -229,6 +240,7 @@ typedef struct protocol_interface_rf_mac_setup {
|
||||||
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;
|
||||||
|
mac_mcps_data_conf_fail_t mac_mcps_data_conf_fail;
|
||||||
struct cca_structure_s *cca_structure;
|
struct cca_structure_s *cca_structure;
|
||||||
/* MAC Security components */
|
/* MAC Security components */
|
||||||
struct mlme_device_descriptor_s *device_description_table;
|
struct mlme_device_descriptor_s *device_description_table;
|
||||||
|
|
|
@ -65,13 +65,24 @@ uint32_t mac_read_phy_datarate(const fhss_api_t *fhss_api)
|
||||||
return datarate;
|
return datarate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t mac_read_phy_timestamp(const fhss_api_t *fhss_api)
|
||||||
|
{
|
||||||
|
protocol_interface_rf_mac_setup_s *mac_setup = get_sw_mac_ptr_by_fhss_api(fhss_api);
|
||||||
|
if (!mac_setup) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
uint32_t timestamp;
|
||||||
|
mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_GET_TIMESTAMP, (uint8_t *)×tamp);
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
protocol_interface_rf_mac_setup_s *mac_setup = get_sw_mac_ptr_by_fhss_api(fhss_api);
|
protocol_interface_rf_mac_setup_s *mac_setup = get_sw_mac_ptr_by_fhss_api(fhss_api);
|
||||||
if (!mac_setup) {
|
if (!mac_setup) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (mac_setup->mac_ack_tx_active || (mac_setup->active_pd_data_request && mac_setup->active_pd_data_request->asynch_request)) {
|
if (mac_setup->mac_ack_tx_active || (mac_setup->active_pd_data_request && (mac_setup->active_pd_data_request->asynch_request || mac_setup->timer_mac_event == MAC_TIMER_ACK))) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return mac_mlme_rf_channel_change(mac_setup, channel_number);
|
return mac_mlme_rf_channel_change(mac_setup, channel_number);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
uint16_t mac_read_tx_queue_sizes(const fhss_api_t *fhss_api, bool broadcast_queue);
|
uint16_t mac_read_tx_queue_sizes(const fhss_api_t *fhss_api, bool broadcast_queue);
|
||||||
int mac_read_64bit_mac_address(const fhss_api_t *fhss_api, uint8_t *mac_address);
|
int mac_read_64bit_mac_address(const fhss_api_t *fhss_api, uint8_t *mac_address);
|
||||||
uint32_t mac_read_phy_datarate(const fhss_api_t *fhss_api);
|
uint32_t mac_read_phy_datarate(const fhss_api_t *fhss_api);
|
||||||
|
uint32_t mac_read_phy_timestamp(const fhss_api_t *fhss_api);
|
||||||
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);
|
||||||
int mac_fhss_frame_tx(const fhss_api_t *fhss_api, int frame_type);
|
int mac_fhss_frame_tx(const fhss_api_t *fhss_api, int frame_type);
|
||||||
int mac_synch_lost(const fhss_api_t *fhss_api);
|
int mac_synch_lost(const fhss_api_t *fhss_api);
|
||||||
|
|
|
@ -337,16 +337,16 @@ void mac_header_security_components_read(mac_pre_parsed_frame_t *buffer, mlme_se
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t mac_header_get_src_panid(const mac_fcf_sequence_t *header, const uint8_t *ptr)
|
static bool mac_header_pan_full_compressed(const mac_fcf_sequence_t *header)
|
||||||
{
|
{
|
||||||
|
if (header->frameVersion == MAC_FRAME_VERSION_2015 && (!header->DstPanPresents && !header->SrcPanPresents) && header->intraPan) {
|
||||||
if (!header->SrcPanPresents) {
|
return true;
|
||||||
if (!header->DstPanPresents) {
|
|
||||||
return 0xffff;
|
|
||||||
}
|
|
||||||
return mac_header_get_dst_panid(header, ptr);
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t mac_header_read_src_pan(const mac_fcf_sequence_t *header, const uint8_t *ptr)
|
||||||
|
{
|
||||||
ptr += mac_fcf_lenght(header);//Skip FCF + DSN
|
ptr += mac_fcf_lenght(header);//Skip FCF + DSN
|
||||||
|
|
||||||
ptr += mac_dst_address_length_with_panid(header); //Skip Dst panID & Address
|
ptr += mac_dst_address_length_with_panid(header); //Skip Dst panID & Address
|
||||||
|
@ -354,17 +354,44 @@ uint16_t mac_header_get_src_panid(const mac_fcf_sequence_t *header, const uint8_
|
||||||
return common_read_16_bit_inverse(ptr);
|
return common_read_16_bit_inverse(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t mac_header_get_dst_panid(const mac_fcf_sequence_t *header, const uint8_t *ptr)
|
static uint16_t mac_header_read_dst_pan(const mac_fcf_sequence_t *header, const uint8_t *ptr)
|
||||||
{
|
{
|
||||||
if (!header->DstPanPresents) {
|
|
||||||
return 0xffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr += mac_fcf_lenght(header);//Skip FCF + DSN
|
ptr += mac_fcf_lenght(header);//Skip FCF + DSN
|
||||||
|
|
||||||
return common_read_16_bit_inverse(ptr);
|
return common_read_16_bit_inverse(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t mac_header_get_src_panid(const mac_fcf_sequence_t *header, const uint8_t *ptr, uint16_t configured_pan_id)
|
||||||
|
{
|
||||||
|
if (mac_header_pan_full_compressed(header)) {
|
||||||
|
return configured_pan_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!header->SrcPanPresents) {
|
||||||
|
if (!header->DstPanPresents) {
|
||||||
|
return 0xffff;
|
||||||
|
}
|
||||||
|
return mac_header_read_dst_pan(header, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mac_header_read_src_pan(header, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t mac_header_get_dst_panid(const mac_fcf_sequence_t *header, const uint8_t *ptr, uint16_t configured_pan_id)
|
||||||
|
{
|
||||||
|
if (mac_header_pan_full_compressed(header)) {
|
||||||
|
return configured_pan_id;
|
||||||
|
}
|
||||||
|
if (!header->DstPanPresents) {
|
||||||
|
if (header->SrcPanPresents && header->frameVersion == MAC_FRAME_VERSION_2015 && header->DstAddrMode == MAC_ADDR_MODE_NONE) {
|
||||||
|
return mac_header_read_src_pan(header, ptr);
|
||||||
|
}
|
||||||
|
return 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mac_header_read_dst_pan(header, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
void mac_header_get_src_address(const mac_fcf_sequence_t *header, const uint8_t *ptr, uint8_t *address_ptr)
|
void mac_header_get_src_address(const mac_fcf_sequence_t *header, const uint8_t *ptr, uint8_t *address_ptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -59,8 +59,8 @@ uint16_t mac_buffer_total_payload_length(struct mac_pre_build_frame *buffer);
|
||||||
/**
|
/**
|
||||||
* Next function should only call when address mode is not MAC_ADDR_MODE_NONE and parsed proper header!
|
* Next function should only call when address mode is not MAC_ADDR_MODE_NONE and parsed proper header!
|
||||||
*/
|
*/
|
||||||
uint16_t mac_header_get_src_panid(const struct mac_fcf_sequence_s *header, const uint8_t *ptr);
|
uint16_t mac_header_get_src_panid(const struct mac_fcf_sequence_s *header, const uint8_t *ptr, uint16_t configured_pan_id);
|
||||||
uint16_t mac_header_get_dst_panid(const struct mac_fcf_sequence_s *header, const uint8_t *ptr);
|
uint16_t mac_header_get_dst_panid(const struct mac_fcf_sequence_s *header, const uint8_t *ptr, uint16_t configured_pan_id);
|
||||||
void mac_header_get_src_address(const struct mac_fcf_sequence_s *header, const uint8_t *ptr, uint8_t *address_ptr);
|
void mac_header_get_src_address(const struct mac_fcf_sequence_s *header, const uint8_t *ptr, uint8_t *address_ptr);
|
||||||
void mac_header_get_dst_address(const struct mac_fcf_sequence_s *header, const uint8_t *ptr, uint8_t *address_ptr);
|
void mac_header_get_dst_address(const struct mac_fcf_sequence_s *header, const uint8_t *ptr, uint8_t *address_ptr);
|
||||||
uint8_t mac_address_length(uint8_t address_mode);
|
uint8_t mac_address_length(uint8_t address_mode);
|
||||||
|
|
|
@ -134,7 +134,7 @@ uint8_t mac_indirect_data_req_handle(mac_pre_parsed_frame_t *buf, protocol_inter
|
||||||
|
|
||||||
comm_status.status = MLME_DATA_POLL_NOTIFICATION;
|
comm_status.status = MLME_DATA_POLL_NOTIFICATION;
|
||||||
//Call com status
|
//Call com status
|
||||||
comm_status.PANId = mac_header_get_dst_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf));
|
comm_status.PANId = mac_header_get_dst_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf), mac_ptr->pan_id);
|
||||||
comm_status.DstAddrMode = buf->fcf_dsn.DstAddrMode;;
|
comm_status.DstAddrMode = buf->fcf_dsn.DstAddrMode;;
|
||||||
mac_header_get_dst_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), comm_status.DstAddr);
|
mac_header_get_dst_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), comm_status.DstAddr);
|
||||||
comm_status.SrcAddrMode = buf->fcf_dsn.SrcAddrMode;
|
comm_status.SrcAddrMode = buf->fcf_dsn.SrcAddrMode;
|
||||||
|
|
|
@ -70,6 +70,7 @@ static void mac_set_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup
|
||||||
static void mac_clear_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t event_type);
|
static void mac_clear_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t event_type);
|
||||||
static bool mac_read_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t event_type);
|
static bool mac_read_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t event_type);
|
||||||
static int8_t mcps_pd_data_cca_trig(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer);
|
static int8_t mcps_pd_data_cca_trig(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer);
|
||||||
|
static void mac_pd_data_confirm_failure_handle(protocol_interface_rf_mac_setup_s *rf_mac_setup);
|
||||||
|
|
||||||
static int8_t mac_tasklet_event_handler = -1;
|
static int8_t mac_tasklet_event_handler = -1;
|
||||||
|
|
||||||
|
@ -87,47 +88,18 @@ static uint32_t mac_mcps_sap_get_phy_timestamp(protocol_interface_rf_mac_setup_s
|
||||||
return timestamp;
|
return timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mac_data_request_init(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer)
|
|
||||||
{
|
|
||||||
rf_mac_setup->active_pd_data_request = buffer;
|
|
||||||
if (buffer->asynch_request) {
|
|
||||||
buffer->asynch_channel = rf_mac_setup->mac_channel; //Store Original channel
|
|
||||||
uint16_t channel = mlme_scan_analyze_next_channel(&buffer->asynch_channel_list);
|
|
||||||
if (channel <= 0xff) {
|
|
||||||
uint8_t switch_channel = channel;
|
|
||||||
if (rf_mac_setup->mac_channel != switch_channel) {
|
|
||||||
mac_mlme_mac_radio_disabled(rf_mac_setup);
|
|
||||||
rf_mac_setup->mac_channel = channel;
|
|
||||||
mac_mlme_mac_radio_enable(rf_mac_setup);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool mac_data_request_confirmation_finnish(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer)
|
static bool mac_data_request_confirmation_finnish(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer)
|
||||||
{
|
{
|
||||||
if (!buffer->asynch_request) {
|
if (!buffer->asynch_request) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t channel = mlme_scan_analyze_next_channel(&buffer->asynch_channel_list);
|
if (mlme_scan_analyze_next_channel(&buffer->asynch_channel_list, false) > 0x00ff) {
|
||||||
uint8_t switch_channel;
|
mac_mlme_rf_channel_change(rf_mac_setup, buffer->asynch_channel);
|
||||||
bool return_value;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (channel > 0x00ff) {
|
return false;
|
||||||
return_value = true;
|
|
||||||
switch_channel = buffer->asynch_channel;
|
|
||||||
} else {
|
|
||||||
switch_channel = channel;
|
|
||||||
return_value = false;
|
|
||||||
}
|
|
||||||
//Set original Channel back if channel is switched
|
|
||||||
if (rf_mac_setup->mac_channel != switch_channel) {
|
|
||||||
mac_mlme_mac_radio_disabled(rf_mac_setup);
|
|
||||||
rf_mac_setup->mac_channel = switch_channel;
|
|
||||||
mac_mlme_mac_radio_enable(rf_mac_setup);
|
|
||||||
}
|
|
||||||
return return_value;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +117,6 @@ static void mac_data_poll_radio_disable_check(protocol_interface_rf_mac_setup_s
|
||||||
|
|
||||||
static void mcps_data_confirm_cb(protocol_interface_rf_mac_setup_s *rf_mac_setup, mcps_data_conf_t *confirm, mac_pre_parsed_frame_t *ack_buf)
|
static void mcps_data_confirm_cb(protocol_interface_rf_mac_setup_s *rf_mac_setup, mcps_data_conf_t *confirm, mac_pre_parsed_frame_t *ack_buf)
|
||||||
{
|
{
|
||||||
|
|
||||||
mac_data_poll_radio_disable_check(rf_mac_setup);
|
mac_data_poll_radio_disable_check(rf_mac_setup);
|
||||||
|
|
||||||
if( get_sw_mac_api(rf_mac_setup) ) {
|
if( get_sw_mac_api(rf_mac_setup) ) {
|
||||||
|
@ -363,13 +334,14 @@ void mcps_sap_data_req_handler_ext(protocol_interface_rf_mac_setup_s *rf_mac_set
|
||||||
|
|
||||||
verify_status:
|
verify_status:
|
||||||
if (status != MLME_SUCCESS){
|
if (status != MLME_SUCCESS){
|
||||||
mcps_data_conf_t confirm;
|
|
||||||
memset(&confirm, 0, sizeof(mcps_data_conf_t));
|
|
||||||
confirm.msduHandle = data_req->msduHandle;
|
|
||||||
confirm.status = status;
|
|
||||||
tr_debug("DATA REQ Fail %u", status);
|
tr_debug("DATA REQ Fail %u", status);
|
||||||
|
rf_mac_setup->mac_mcps_data_conf_fail.msduHandle = data_req->msduHandle;
|
||||||
|
rf_mac_setup->mac_mcps_data_conf_fail.status = status;
|
||||||
mcps_sap_prebuild_frame_buffer_free(buffer);
|
mcps_sap_prebuild_frame_buffer_free(buffer);
|
||||||
mcps_data_confirm_cb(rf_mac_setup, &confirm, NULL);
|
if (mcps_sap_pd_confirm_failure(rf_mac_setup) != 0) {
|
||||||
|
// event sending failed, calling handler directly
|
||||||
|
mac_pd_data_confirm_failure_handle(rf_mac_setup);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,7 +540,7 @@ static uint8_t mac_data_interface_decrypt_packet(mac_pre_parsed_frame_t *b, mlme
|
||||||
|
|
||||||
//READ SRC Address
|
//READ SRC Address
|
||||||
|
|
||||||
uint16_t SrcPANId = mac_header_get_src_panid(&b->fcf_dsn, mac_header_message_start_pointer(b));
|
uint16_t SrcPANId = mac_header_get_src_panid(&b->fcf_dsn, mac_header_message_start_pointer(b), rf_mac_setup->pan_id);
|
||||||
mac_header_get_src_address(&b->fcf_dsn, mac_header_message_start_pointer(b), neighbour_validation.address);
|
mac_header_get_src_address(&b->fcf_dsn, mac_header_message_start_pointer(b), neighbour_validation.address);
|
||||||
neighbour_validation.addr_type = b->fcf_dsn.SrcAddrMode;
|
neighbour_validation.addr_type = b->fcf_dsn.SrcAddrMode;
|
||||||
neighbour_validation.keyId = security_params->KeyIndex;
|
neighbour_validation.keyId = security_params->KeyIndex;
|
||||||
|
@ -670,10 +642,11 @@ static uint8_t mac_data_interface_decrypt_packet(mac_pre_parsed_frame_t *b, mlme
|
||||||
static void mcps_comm_status_indication_generate(uint8_t status, mac_pre_parsed_frame_t *buf, mac_api_t * mac)
|
static void mcps_comm_status_indication_generate(uint8_t status, mac_pre_parsed_frame_t *buf, mac_api_t * mac)
|
||||||
{
|
{
|
||||||
mlme_comm_status_t comm_status;
|
mlme_comm_status_t comm_status;
|
||||||
|
protocol_interface_rf_mac_setup_s *rf_ptr = buf->mac_class_ptr;
|
||||||
memset(&comm_status,0 ,sizeof(mlme_comm_status_t) );
|
memset(&comm_status,0 ,sizeof(mlme_comm_status_t) );
|
||||||
comm_status.status = status;
|
comm_status.status = status;
|
||||||
//Call com status
|
//Call com status
|
||||||
comm_status.PANId = mac_header_get_dst_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf));
|
comm_status.PANId = mac_header_get_dst_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf), rf_ptr->pan_id);
|
||||||
comm_status.DstAddrMode = buf->fcf_dsn.DstAddrMode;;
|
comm_status.DstAddrMode = buf->fcf_dsn.DstAddrMode;;
|
||||||
mac_header_get_dst_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), comm_status.DstAddr);
|
mac_header_get_dst_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), comm_status.DstAddr);
|
||||||
comm_status.SrcAddrMode = buf->fcf_dsn.SrcAddrMode;
|
comm_status.SrcAddrMode = buf->fcf_dsn.SrcAddrMode;
|
||||||
|
@ -723,12 +696,14 @@ static int8_t mac_data_sap_rx_handler(mac_pre_parsed_frame_t *buf, protocol_inte
|
||||||
//Parse data
|
//Parse data
|
||||||
data_ind->DSN = buf->fcf_dsn.DSN;
|
data_ind->DSN = buf->fcf_dsn.DSN;
|
||||||
data_ind->DstAddrMode = buf->fcf_dsn.DstAddrMode;
|
data_ind->DstAddrMode = buf->fcf_dsn.DstAddrMode;
|
||||||
data_ind->DstPANId = mac_header_get_dst_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf));
|
|
||||||
mac_header_get_dst_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), data_ind->DstAddr);
|
mac_header_get_dst_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), data_ind->DstAddr);
|
||||||
data_ind->SrcAddrMode = buf->fcf_dsn.SrcAddrMode;
|
data_ind->SrcAddrMode = buf->fcf_dsn.SrcAddrMode;
|
||||||
data_ind->SrcPANId = mac_header_get_src_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf));
|
|
||||||
mac_header_get_src_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), data_ind->SrcAddr);
|
mac_header_get_src_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), data_ind->SrcAddr);
|
||||||
|
|
||||||
|
data_ind->SrcPANId = mac_header_get_src_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf), rf_mac_setup->pan_id);
|
||||||
|
data_ind->DstPANId = mac_header_get_dst_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf), rf_mac_setup->pan_id);
|
||||||
|
|
||||||
data_ind->mpduLinkQuality = buf->LQI;
|
data_ind->mpduLinkQuality = buf->LQI;
|
||||||
data_ind->signal_dbm = buf->dbm;
|
data_ind->signal_dbm = buf->dbm;
|
||||||
data_ind->timestamp = buf->timestamp;
|
data_ind->timestamp = buf->timestamp;
|
||||||
|
@ -739,7 +714,6 @@ static int8_t mac_data_sap_rx_handler(mac_pre_parsed_frame_t *buf, protocol_inte
|
||||||
if (buf->fcf_dsn.securityEnabled) {
|
if (buf->fcf_dsn.securityEnabled) {
|
||||||
status = mac_data_interface_decrypt_packet(buf, &data_ind->Key);
|
status = mac_data_interface_decrypt_packet(buf, &data_ind->Key);
|
||||||
if (status != MLME_SUCCESS) {
|
if (status != MLME_SUCCESS) {
|
||||||
tr_debug("Decrypt fail, %d", status);
|
|
||||||
mcps_comm_status_indication_generate(status, buf, mac);
|
mcps_comm_status_indication_generate(status, buf, mac);
|
||||||
goto DROP_PACKET;
|
goto DROP_PACKET;
|
||||||
}
|
}
|
||||||
|
@ -772,6 +746,12 @@ static int8_t mac_data_sap_rx_handler(mac_pre_parsed_frame_t *buf, protocol_inte
|
||||||
ie_list.payloadIeListLength = buf->payloadsIeLength;
|
ie_list.payloadIeListLength = buf->payloadsIeLength;
|
||||||
ie_list.headerIeList = buf->headerIePtr;
|
ie_list.headerIeList = buf->headerIePtr;
|
||||||
ie_list.headerIeListLength = buf->headerIeLength;
|
ie_list.headerIeListLength = buf->headerIeLength;
|
||||||
|
//Swap compressed address to broadcast when dst Address is elided
|
||||||
|
if (buf->fcf_dsn.DstAddrMode == MAC_ADDR_MODE_NONE) {
|
||||||
|
data_ind->DstAddrMode = MAC_ADDR_MODE_16_BIT;
|
||||||
|
data_ind->DstAddr[0] = 0xff;
|
||||||
|
data_ind->DstAddr[1] = 0xff;
|
||||||
|
}
|
||||||
mac->data_ind_ext_cb(mac, data_ind, &ie_list);
|
mac->data_ind_ext_cb(mac, data_ind, &ie_list);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -796,7 +776,7 @@ static void mac_lib_res_no_data_to_req(mac_pre_parsed_frame_t *buffer, protocol_
|
||||||
buf->fcf_dsn.SrcAddrMode = buffer->fcf_dsn.DstAddrMode;
|
buf->fcf_dsn.SrcAddrMode = buffer->fcf_dsn.DstAddrMode;
|
||||||
buf->fcf_dsn.DstAddrMode = buffer->fcf_dsn.SrcAddrMode;
|
buf->fcf_dsn.DstAddrMode = buffer->fcf_dsn.SrcAddrMode;
|
||||||
//SET PANID
|
//SET PANID
|
||||||
buf->SrcPANId = mac_header_get_dst_panid(&buffer->fcf_dsn, mac_header_message_start_pointer(buffer));
|
buf->SrcPANId = mac_header_get_dst_panid(&buffer->fcf_dsn, mac_header_message_start_pointer(buffer), rf_mac_setup->pan_id);
|
||||||
buf->DstPANId = buf->SrcPANId;
|
buf->DstPANId = buf->SrcPANId;
|
||||||
|
|
||||||
mac_header_get_dst_address(&buffer->fcf_dsn, mac_header_message_start_pointer(buffer), buf->SrcAddr);
|
mac_header_get_dst_address(&buffer->fcf_dsn, mac_header_message_start_pointer(buffer), buf->SrcAddr);
|
||||||
|
@ -910,7 +890,7 @@ static void mac_data_interface_parse_beacon(mac_pre_parsed_frame_t *buf, protoco
|
||||||
uint8_t *pending_address_list = NULL;
|
uint8_t *pending_address_list = NULL;
|
||||||
uint8_t SuperframeSpec[2];
|
uint8_t SuperframeSpec[2];
|
||||||
|
|
||||||
uint16_t src_pan_id = mac_header_get_src_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf));
|
uint16_t src_pan_id = mac_header_get_src_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf), rf_mac_setup->pan_id);
|
||||||
|
|
||||||
//validate beacon pan-id and filter other network out
|
//validate beacon pan-id and filter other network out
|
||||||
if (rf_mac_setup->pan_id < 0xffff && (rf_mac_setup->pan_id != src_pan_id && !rf_mac_setup->macAcceptAnyBeacon)) {
|
if (rf_mac_setup->pan_id < 0xffff && (rf_mac_setup->pan_id != src_pan_id && !rf_mac_setup->macAcceptAnyBeacon)) {
|
||||||
|
@ -1045,6 +1025,14 @@ static void mac_data_interface_frame_handler(mac_pre_parsed_frame_t *buf)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mac_mcps_asynch_finish(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer)
|
||||||
|
{
|
||||||
|
if (buffer->asynch_request && rf_mac_setup->fhss_api) {
|
||||||
|
// Must return to scheduled channel after asynch process by calling TX done
|
||||||
|
rf_mac_setup->fhss_api->data_tx_done(rf_mac_setup->fhss_api, false, true, buffer->msduHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void mac_mcps_trig_buffer_from_queue(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
void mac_mcps_trig_buffer_from_queue(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
||||||
{
|
{
|
||||||
if (!rf_mac_setup) {
|
if (!rf_mac_setup) {
|
||||||
|
@ -1064,9 +1052,10 @@ void mac_mcps_trig_buffer_from_queue(protocol_interface_rf_mac_setup_s *rf_mac_s
|
||||||
buffer = mcps_sap_pd_req_queue_read(rf_mac_setup, is_bc_queue, false);
|
buffer = mcps_sap_pd_req_queue_read(rf_mac_setup, is_bc_queue, false);
|
||||||
|
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
mac_data_request_init(rf_mac_setup, buffer);
|
rf_mac_setup->active_pd_data_request = buffer;
|
||||||
if (mcps_pd_data_request(rf_mac_setup, buffer) != 0) {
|
if (mcps_pd_data_request(rf_mac_setup, buffer) != 0) {
|
||||||
rf_mac_setup->active_pd_data_request = NULL;
|
rf_mac_setup->active_pd_data_request = NULL;
|
||||||
|
mac_mcps_asynch_finish(rf_mac_setup, buffer);
|
||||||
mcps_data_confirm_handle(rf_mac_setup, buffer, NULL);
|
mcps_data_confirm_handle(rf_mac_setup, buffer, NULL);
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
|
@ -1077,7 +1066,6 @@ void mac_mcps_trig_buffer_from_queue(protocol_interface_rf_mac_setup_s *rf_mac_s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int8_t mac_ack_sap_rx_handler(mac_pre_parsed_frame_t *buf, protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
static int8_t mac_ack_sap_rx_handler(mac_pre_parsed_frame_t *buf, protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
||||||
{
|
{
|
||||||
//allocate Data ind primitiv and parse packet to that
|
//allocate Data ind primitiv and parse packet to that
|
||||||
|
@ -1106,20 +1094,18 @@ static int8_t mac_ack_sap_rx_handler(mac_pre_parsed_frame_t *buf, protocol_inter
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mac_pd_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_mac_setup) {
|
static void mac_pd_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
||||||
|
{
|
||||||
if (rf_mac_setup->active_pd_data_request) {
|
if (rf_mac_setup->active_pd_data_request) {
|
||||||
mac_pre_build_frame_t *buffer = rf_mac_setup->active_pd_data_request;
|
mac_pre_build_frame_t *buffer = rf_mac_setup->active_pd_data_request;
|
||||||
if (mac_data_request_confirmation_finnish(rf_mac_setup, buffer) ) {
|
if (mac_data_request_confirmation_finnish(rf_mac_setup, buffer) ) {
|
||||||
rf_mac_setup->active_pd_data_request = NULL;
|
rf_mac_setup->active_pd_data_request = NULL;
|
||||||
if (buffer->asynch_request && rf_mac_setup->fhss_api) {
|
mac_mcps_asynch_finish(rf_mac_setup, buffer);
|
||||||
// Must return to scheduled channel after asynch process by calling TX done
|
|
||||||
rf_mac_setup->fhss_api->data_tx_done(rf_mac_setup->fhss_api, false, true, buffer->msduHandle);
|
|
||||||
}
|
|
||||||
mcps_data_confirm_handle(rf_mac_setup, buffer, NULL);
|
mcps_data_confirm_handle(rf_mac_setup, buffer, NULL);
|
||||||
} else {
|
} else {
|
||||||
if (mcps_pd_data_request(rf_mac_setup, buffer) != 0) {
|
if (mcps_pd_data_request(rf_mac_setup, buffer) != 0) {
|
||||||
rf_mac_setup->active_pd_data_request = NULL;
|
rf_mac_setup->active_pd_data_request = NULL;
|
||||||
|
mac_mcps_asynch_finish(rf_mac_setup, buffer);
|
||||||
mcps_data_confirm_handle(rf_mac_setup, buffer, NULL);
|
mcps_data_confirm_handle(rf_mac_setup, buffer, NULL);
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
|
@ -1130,9 +1116,17 @@ static void mac_pd_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_mac
|
||||||
mac_mcps_trig_buffer_from_queue(rf_mac_setup);
|
mac_mcps_trig_buffer_from_queue(rf_mac_setup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mac_pd_data_confirm_failure_handle(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
||||||
|
{
|
||||||
|
mcps_data_conf_t mcps_data_conf;
|
||||||
|
memset(&mcps_data_conf, 0, sizeof(mcps_data_conf_t));
|
||||||
|
mcps_data_conf.msduHandle = rf_mac_setup->mac_mcps_data_conf_fail.msduHandle;
|
||||||
|
mcps_data_conf.status = rf_mac_setup->mac_mcps_data_conf_fail.status;
|
||||||
|
mcps_data_confirm_cb(rf_mac_setup, &mcps_data_conf, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void mac_pd_data_ack_handler(mac_pre_parsed_frame_t *buf) {
|
static void mac_pd_data_ack_handler(mac_pre_parsed_frame_t *buf)
|
||||||
|
{
|
||||||
protocol_interface_rf_mac_setup_s *rf_mac_setup = buf->mac_class_ptr;
|
protocol_interface_rf_mac_setup_s *rf_mac_setup = buf->mac_class_ptr;
|
||||||
|
|
||||||
if (!rf_mac_setup->active_pd_data_request) {
|
if (!rf_mac_setup->active_pd_data_request) {
|
||||||
|
@ -1147,10 +1141,6 @@ static void mac_pd_data_ack_handler(mac_pre_parsed_frame_t *buf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
rf_mac_setup->active_pd_data_request = NULL;
|
rf_mac_setup->active_pd_data_request = NULL;
|
||||||
if (buffer->asynch_request && rf_mac_setup->fhss_api) {
|
|
||||||
// Must return to scheduled channel after asynch process by calling TX done
|
|
||||||
rf_mac_setup->fhss_api->data_tx_done(rf_mac_setup->fhss_api, false, true, buffer->msduHandle);
|
|
||||||
}
|
|
||||||
mcps_data_confirm_handle(rf_mac_setup, buffer, buf);
|
mcps_data_confirm_handle(rf_mac_setup, buffer, buf);
|
||||||
mcps_sap_pre_parsed_frame_buffer_free(buf);
|
mcps_sap_pre_parsed_frame_buffer_free(buf);
|
||||||
|
|
||||||
|
@ -1177,6 +1167,10 @@ static void mac_mcps_sap_data_tasklet(arm_event_s *event)
|
||||||
mac_pd_data_confirm_handle((protocol_interface_rf_mac_setup_s*)event->data_ptr);
|
mac_pd_data_confirm_handle((protocol_interface_rf_mac_setup_s*)event->data_ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MCPS_SAP_DATA_CNF_FAIL_EVENT:
|
||||||
|
mac_pd_data_confirm_failure_handle((protocol_interface_rf_mac_setup_s*)event->data_ptr);
|
||||||
|
break;
|
||||||
|
|
||||||
case MCPS_SAP_DATA_ACK_CNF_EVENT:
|
case MCPS_SAP_DATA_ACK_CNF_EVENT:
|
||||||
mac_pd_data_ack_handler((mac_pre_parsed_frame_t*)event->data_ptr);
|
mac_pd_data_ack_handler((mac_pre_parsed_frame_t*)event->data_ptr);
|
||||||
break;
|
break;
|
||||||
|
@ -1277,14 +1271,8 @@ static bool mac_frame_security_parameters_init(ccm_globals_t *ccm_ptr, protocol_
|
||||||
if (buffer->fcf_dsn.DstAddrMode && buffer->fcf_dsn.ackRequested) {
|
if (buffer->fcf_dsn.DstAddrMode && buffer->fcf_dsn.ackRequested) {
|
||||||
device_description = mac_sec_mib_device_description_get(rf_ptr, buffer->DstAddr, buffer->fcf_dsn.DstAddrMode);
|
device_description = mac_sec_mib_device_description_get(rf_ptr, buffer->DstAddr, buffer->fcf_dsn.DstAddrMode);
|
||||||
if (!device_description) {
|
if (!device_description) {
|
||||||
|
buffer->status = MLME_UNAVAILABLE_KEY;
|
||||||
if (rf_ptr->mac_security_bypass_unknow_device && (buffer->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_64_BIT
|
return false;
|
||||||
&& buffer->aux_header.securityLevel > AES_SECURITY_LEVEL_ENC)) {
|
|
||||||
|
|
||||||
} else {
|
|
||||||
buffer->status = MLME_UNAVAILABLE_KEY;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nonce_ext_64_ptr = rf_ptr->mac64;
|
nonce_ext_64_ptr = rf_ptr->mac64;
|
||||||
|
@ -1350,7 +1338,11 @@ static void mac_common_data_confirmation_handle (protocol_interface_rf_mac_setup
|
||||||
//Enable Radio
|
//Enable Radio
|
||||||
mac_mlme_mac_radio_enable(rf_mac_setup);
|
mac_mlme_mac_radio_enable(rf_mac_setup);
|
||||||
buf->status = MLME_TRANSACTION_EXPIRED;
|
buf->status = MLME_TRANSACTION_EXPIRED;
|
||||||
}
|
} else if (m_event == MAC_UNKNOWN_DESTINATION) {
|
||||||
|
buf->status = MLME_UNAVAILABLE_KEY;
|
||||||
|
}/** else if (m_event == MAC_TX_PRECOND_FAIL) {
|
||||||
|
* Nothing to do, status already set to buf->status.
|
||||||
|
}**/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1419,7 +1411,7 @@ static void mcps_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_ptr,
|
||||||
sw_mac_stats_update(rf_ptr, STAT_MAC_TX_CCA_ATT, rf_ptr->mac_tx_status.cca_cnt);
|
sw_mac_stats_update(rf_ptr, STAT_MAC_TX_CCA_ATT, rf_ptr->mac_tx_status.cca_cnt);
|
||||||
sw_mac_stats_update(rf_ptr, STAT_MAC_TX_RETRY, rf_ptr->mac_tx_status.retry);
|
sw_mac_stats_update(rf_ptr, STAT_MAC_TX_RETRY, rf_ptr->mac_tx_status.retry);
|
||||||
mcps_data_conf_t confirm;
|
mcps_data_conf_t confirm;
|
||||||
if (rf_ptr->fhss_api) {
|
if (rf_ptr->fhss_api && !buffer->asynch_request) {
|
||||||
// FHSS checks if this failed buffer needs to be pushed back to TX queue and retransmitted
|
// FHSS checks if this failed buffer needs to be pushed back to TX queue and retransmitted
|
||||||
if ((rf_ptr->mac_tx_result == MAC_TX_FAIL) || (rf_ptr->mac_tx_result == MAC_CCA_FAIL)) {
|
if ((rf_ptr->mac_tx_result == MAC_TX_FAIL) || (rf_ptr->mac_tx_result == MAC_CCA_FAIL)) {
|
||||||
if (rf_ptr->fhss_api->data_tx_fail(rf_ptr->fhss_api, buffer->msduHandle, mac_convert_frame_type_to_fhss(buffer->fcf_dsn.frametype)) == true) {
|
if (rf_ptr->fhss_api->data_tx_fail(rf_ptr->fhss_api, buffer->msduHandle, mac_convert_frame_type_to_fhss(buffer->fcf_dsn.frametype)) == true) {
|
||||||
|
@ -1615,6 +1607,7 @@ int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, const m
|
||||||
buffer->fcf_dsn.frameVersion = fcf->frameVersion;
|
buffer->fcf_dsn.frameVersion = fcf->frameVersion;
|
||||||
buffer->fcf_dsn.framePending = rf_ptr->mac_frame_pending;
|
buffer->fcf_dsn.framePending = rf_ptr->mac_frame_pending;
|
||||||
buffer->fcf_dsn.DSN = fcf->DSN;
|
buffer->fcf_dsn.DSN = fcf->DSN;
|
||||||
|
buffer->fcf_dsn.intraPan = fcf->intraPan;
|
||||||
buffer->fcf_dsn.sequenceNumberSuppress = fcf->sequenceNumberSuppress;
|
buffer->fcf_dsn.sequenceNumberSuppress = fcf->sequenceNumberSuppress;
|
||||||
buffer->fcf_dsn.DstPanPresents = fcf->DstPanPresents;
|
buffer->fcf_dsn.DstPanPresents = fcf->DstPanPresents;
|
||||||
buffer->fcf_dsn.SrcAddrMode = fcf->DstAddrMode;
|
buffer->fcf_dsn.SrcAddrMode = fcf->DstAddrMode;
|
||||||
|
@ -1628,9 +1621,8 @@ int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, const m
|
||||||
|
|
||||||
buffer->mac_header_length_with_security += mac_header_address_length(&buffer->fcf_dsn);
|
buffer->mac_header_length_with_security += mac_header_address_length(&buffer->fcf_dsn);
|
||||||
|
|
||||||
buffer->DstPANId = mac_header_get_src_panid(fcf, data_ptr);
|
buffer->DstPANId = mac_header_get_src_panid(fcf, data_ptr, rf_ptr->pan_id);
|
||||||
buffer->SrcPANId = mac_header_get_dst_panid(fcf, data_ptr);
|
buffer->SrcPANId = mac_header_get_dst_panid(fcf, data_ptr, rf_ptr->pan_id);
|
||||||
|
|
||||||
mac_header_get_src_address(fcf, data_ptr, buffer->DstAddr);
|
mac_header_get_src_address(fcf, data_ptr, buffer->DstAddr);
|
||||||
mac_header_get_dst_address(fcf, data_ptr, buffer->SrcAddr);
|
mac_header_get_dst_address(fcf, data_ptr, buffer->SrcAddr);
|
||||||
|
|
||||||
|
@ -1696,7 +1688,15 @@ int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, const m
|
||||||
|
|
||||||
//Add MHR length to total length
|
//Add MHR length to total length
|
||||||
frame_length += buffer->mac_header_length_with_security + buffer->security_mic_len;
|
frame_length += buffer->mac_header_length_with_security + buffer->security_mic_len;
|
||||||
if ((frame_length) > dev_driver->phy_MTU - 2) {
|
uint16_t ack_mtu_size;
|
||||||
|
if (ENHANCED_ACK_MAX_LENGTH > dev_driver->phy_MTU) {
|
||||||
|
ack_mtu_size = dev_driver->phy_MTU;
|
||||||
|
} else {
|
||||||
|
ack_mtu_size = ENHANCED_ACK_MAX_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((frame_length) > ack_mtu_size - 2) {
|
||||||
buffer->status = MLME_FRAME_TOO_LONG;
|
buffer->status = MLME_FRAME_TOO_LONG;
|
||||||
|
|
||||||
if (buffer->fcf_dsn.securityEnabled) {
|
if (buffer->fcf_dsn.securityEnabled) {
|
||||||
|
@ -1708,14 +1708,14 @@ int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, const m
|
||||||
}
|
}
|
||||||
|
|
||||||
rf_ptr->mac_tx_status.length = frame_length;
|
rf_ptr->mac_tx_status.length = frame_length;
|
||||||
uint8_t *ptr = tx_buf->buf;
|
uint8_t *ptr = tx_buf->enhanced_ack_buf;
|
||||||
if (dev_driver->phy_header_length) {
|
if (dev_driver->phy_header_length) {
|
||||||
ptr += dev_driver->phy_header_length;
|
ptr += dev_driver->phy_header_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
tx_buf->len = frame_length;
|
tx_buf->ack_len = frame_length;
|
||||||
uint8_t *mhr_start = ptr;
|
uint8_t *mhr_start = ptr;
|
||||||
buffer->tx_time = rx_time + 196; //Send 196 us later
|
buffer->tx_time = mac_mcps_sap_get_phy_timestamp(rf_ptr) + 300; //Send 300 us later
|
||||||
|
|
||||||
ptr = mac_generic_packet_write(rf_ptr, ptr, buffer);
|
ptr = mac_generic_packet_write(rf_ptr, ptr, buffer);
|
||||||
|
|
||||||
|
@ -1731,9 +1731,9 @@ int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, const m
|
||||||
csma_params.cca_enabled = false;
|
csma_params.cca_enabled = false;
|
||||||
rf_ptr->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_CSMA_PARAMETERS, (uint8_t*) &csma_params);
|
rf_ptr->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_CSMA_PARAMETERS, (uint8_t*) &csma_params);
|
||||||
if (rf_ptr->active_pd_data_request) {
|
if (rf_ptr->active_pd_data_request) {
|
||||||
|
timer_mac_stop(rf_ptr);
|
||||||
mac_pd_sap_set_phy_tx_time(rf_ptr, 0, false);
|
mac_pd_sap_set_phy_tx_time(rf_ptr, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mcps_pd_data_cca_trig(rf_ptr, buffer);
|
return mcps_pd_data_cca_trig(rf_ptr, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1803,6 +1803,7 @@ static int8_t mcps_generic_packet_rebuild(protocol_interface_rf_mac_setup_s *rf_
|
||||||
|
|
||||||
static int8_t mcps_pd_data_cca_trig(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer)
|
static int8_t mcps_pd_data_cca_trig(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer)
|
||||||
{
|
{
|
||||||
|
platform_enter_critical();
|
||||||
mac_mlme_mac_radio_enable(rf_ptr);
|
mac_mlme_mac_radio_enable(rf_ptr);
|
||||||
rf_ptr->macTxProcessActive = true;
|
rf_ptr->macTxProcessActive = true;
|
||||||
if (rf_ptr->rf_csma_extension_supported) {
|
if (rf_ptr->rf_csma_extension_supported) {
|
||||||
|
@ -1810,18 +1811,35 @@ static int8_t mcps_pd_data_cca_trig(protocol_interface_rf_mac_setup_s *rf_ptr, m
|
||||||
bool cca_enabled;
|
bool cca_enabled;
|
||||||
if (buffer->fcf_dsn.frametype == MAC_FRAME_ACK) {
|
if (buffer->fcf_dsn.frametype == MAC_FRAME_ACK) {
|
||||||
cca_enabled = false;
|
cca_enabled = false;
|
||||||
|
rf_ptr->mac_ack_tx_active = true;
|
||||||
} else {
|
} else {
|
||||||
|
if (rf_ptr->mac_ack_tx_active) {
|
||||||
|
mac_csma_backoff_start(rf_ptr);
|
||||||
|
platform_exit_critical();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
cca_enabled = true;
|
cca_enabled = true;
|
||||||
}
|
}
|
||||||
mac_pd_sap_set_phy_tx_time(rf_ptr, buffer->tx_time, cca_enabled);
|
mac_pd_sap_set_phy_tx_time(rf_ptr, buffer->tx_time, cca_enabled);
|
||||||
if (mac_plme_cca_req(rf_ptr) != 0) {
|
if (mac_plme_cca_req(rf_ptr) != 0) {
|
||||||
rf_ptr->macTxProcessActive = false;
|
if (buffer->fcf_dsn.frametype == MAC_FRAME_ACK) {
|
||||||
return -1;
|
rf_ptr->mac_ack_tx_active = false;
|
||||||
|
// For Ack, stop the active TX process
|
||||||
|
rf_ptr->macTxProcessActive = false;
|
||||||
|
// If MAC had TX process active before Ack transmission,
|
||||||
|
// the TX process has to be restarted in case the Ack transmission failed.
|
||||||
|
if (rf_ptr->active_pd_data_request) {
|
||||||
|
mac_csma_backoff_start(rf_ptr);
|
||||||
|
}
|
||||||
|
platform_exit_critical();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
mac_csma_backoff_start(rf_ptr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
timer_mac_start(rf_ptr, MAC_TIMER_CCA, (uint16_t)(buffer->tx_time / 50));
|
timer_mac_start(rf_ptr, MAC_TIMER_CCA, (uint16_t)(buffer->tx_time / 50));
|
||||||
}
|
}
|
||||||
|
platform_exit_critical();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1891,19 +1909,18 @@ void mcps_sap_pd_req_queue_write(protocol_interface_rf_mac_setup_s *rf_mac_setup
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Start TX process immediately
|
//Start TX process immediately
|
||||||
mac_data_request_init(rf_mac_setup, buffer);
|
rf_mac_setup->active_pd_data_request = buffer;
|
||||||
if (mcps_pd_data_request(rf_mac_setup, buffer) != 0) {
|
if (mcps_pd_data_request(rf_mac_setup, buffer) != 0) {
|
||||||
rf_mac_setup->active_pd_data_request = NULL;
|
rf_mac_setup->mac_tx_result = MAC_TX_PRECOND_FAIL;
|
||||||
mcps_data_conf_t confirm;
|
rf_mac_setup->macTxRequestAck = false;
|
||||||
memset(&confirm, 0, sizeof(mcps_data_conf_t));
|
if (mcps_sap_pd_confirm(rf_mac_setup) != 0) {
|
||||||
confirm.msduHandle = buffer->msduHandle;
|
// can't send event, try calling error handler directly
|
||||||
confirm.status = buffer->status;
|
rf_mac_setup->mac_mcps_data_conf_fail.msduHandle = buffer->msduHandle;
|
||||||
bool requested_from_up = buffer->upper_layer_request;
|
rf_mac_setup->mac_mcps_data_conf_fail.status = buffer->status;
|
||||||
mcps_sap_prebuild_frame_buffer_free(buffer);
|
mcps_sap_prebuild_frame_buffer_free(buffer);
|
||||||
if (requested_from_up) {
|
rf_mac_setup->active_pd_data_request = NULL;
|
||||||
mcps_data_confirm_cb(rf_mac_setup, &confirm, NULL);
|
mac_pd_data_confirm_failure_handle(rf_mac_setup);
|
||||||
}
|
}
|
||||||
//Call
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -1981,7 +1998,7 @@ static mac_pre_build_frame_t * mcps_sap_pd_req_queue_read(protocol_interface_rf_
|
||||||
// With FHSS, check TX conditions
|
// With FHSS, check TX conditions
|
||||||
if (rf_mac_setup->fhss_api) {
|
if (rf_mac_setup->fhss_api) {
|
||||||
while (buffer) {
|
while (buffer) {
|
||||||
if ((flush == true) || (rf_mac_setup->fhss_api->check_tx_conditions(rf_mac_setup->fhss_api, !mac_is_ack_request_set(buffer),
|
if (buffer->asynch_request || (flush == true) || (rf_mac_setup->fhss_api->check_tx_conditions(rf_mac_setup->fhss_api, !mac_is_ack_request_set(buffer),
|
||||||
buffer->msduHandle, mac_convert_frame_type_to_fhss(buffer->fcf_dsn.frametype), buffer->mac_payload_length,
|
buffer->msduHandle, mac_convert_frame_type_to_fhss(buffer->fcf_dsn.frametype), buffer->mac_payload_length,
|
||||||
rf_mac_setup->dev_driver->phy_driver->phy_header_length, rf_mac_setup->dev_driver->phy_driver->phy_tail_length) == true)) {
|
rf_mac_setup->dev_driver->phy_driver->phy_header_length, rf_mac_setup->dev_driver->phy_driver->phy_tail_length) == true)) {
|
||||||
break;
|
break;
|
||||||
|
@ -2083,10 +2100,10 @@ int8_t mcps_sap_pd_ind(mac_pre_parsed_frame_t *buffer)
|
||||||
return eventOS_event_send(&event);
|
return eventOS_event_send(&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mcps_sap_pd_confirm(void *mac_ptr)
|
int8_t mcps_sap_pd_confirm(void *mac_ptr)
|
||||||
{
|
{
|
||||||
if (mac_tasklet_event_handler < 0 || !mac_ptr) {
|
if (mac_tasklet_event_handler < 0 || !mac_ptr) {
|
||||||
return;
|
return -2;
|
||||||
}
|
}
|
||||||
arm_event_s event = {
|
arm_event_s event = {
|
||||||
.receiver = mac_tasklet_event_handler,
|
.receiver = mac_tasklet_event_handler,
|
||||||
|
@ -2097,8 +2114,24 @@ void mcps_sap_pd_confirm(void *mac_ptr)
|
||||||
.priority = ARM_LIB_HIGH_PRIORITY_EVENT,
|
.priority = ARM_LIB_HIGH_PRIORITY_EVENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
eventOS_event_send(&event);
|
return eventOS_event_send(&event);
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t mcps_sap_pd_confirm_failure(void *mac_ptr)
|
||||||
|
{
|
||||||
|
if (mac_tasklet_event_handler < 0 || !mac_ptr) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
arm_event_s event = {
|
||||||
|
.receiver = mac_tasklet_event_handler,
|
||||||
|
.sender = 0,
|
||||||
|
.event_id = 0,
|
||||||
|
.data_ptr = mac_ptr,
|
||||||
|
.event_type = MCPS_SAP_DATA_CNF_FAIL_EVENT,
|
||||||
|
.priority = ARM_LIB_HIGH_PRIORITY_EVENT,
|
||||||
|
};
|
||||||
|
|
||||||
|
return eventOS_event_send(&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mcps_sap_pd_ack(void *ack_ptr)
|
void mcps_sap_pd_ack(void *ack_ptr)
|
||||||
|
@ -2226,17 +2259,14 @@ static bool mcps_sap_purge_req_from_queue(protocol_interface_rf_mac_setup_s *rf_
|
||||||
uint8_t status = false;
|
uint8_t status = false;
|
||||||
rf_mac_setup->pd_data_request_queue_to_go = mcps_sap_purge_from_list(rf_mac_setup->pd_data_request_queue_to_go, msduhandle, &status);
|
rf_mac_setup->pd_data_request_queue_to_go = mcps_sap_purge_from_list(rf_mac_setup->pd_data_request_queue_to_go, msduhandle, &status);
|
||||||
|
|
||||||
if (status) {
|
if (!status) {
|
||||||
return true;
|
rf_mac_setup->indirect_pd_data_request_queue = mcps_sap_purge_from_list(rf_mac_setup->indirect_pd_data_request_queue, msduhandle, &status);
|
||||||
}
|
}
|
||||||
|
|
||||||
rf_mac_setup->indirect_pd_data_request_queue = mcps_sap_purge_from_list(rf_mac_setup->indirect_pd_data_request_queue, msduhandle, &status);
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mcps_sap_purge_reg_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mcps_purge_t *purge_req)
|
uint8_t mcps_sap_purge_reg_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mcps_purge_t *purge_req)
|
||||||
{
|
{
|
||||||
mcps_purge_conf_t confirmation;
|
mcps_purge_conf_t confirmation;
|
||||||
confirmation.msduHandle = purge_req->msduHandle;
|
confirmation.msduHandle = purge_req->msduHandle;
|
||||||
|
@ -2250,4 +2280,6 @@ void mcps_sap_purge_reg_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup,
|
||||||
if( get_sw_mac_api(rf_mac_setup) ) {
|
if( get_sw_mac_api(rf_mac_setup) ) {
|
||||||
get_sw_mac_api(rf_mac_setup)->purge_conf_cb(get_sw_mac_api(rf_mac_setup), &confirmation);
|
get_sw_mac_api(rf_mac_setup)->purge_conf_cb(get_sw_mac_api(rf_mac_setup), &confirmation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return confirmation.status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,14 +48,14 @@ typedef enum {
|
||||||
#define MAC_PD_DATA_MEDIUM_PRIORITY 1 //Indirect Data which is polled
|
#define MAC_PD_DATA_MEDIUM_PRIORITY 1 //Indirect Data which is polled
|
||||||
#define MAC_PD_DATA_HIGH_PRIOTITY 2 //Beacon request Beacon response
|
#define MAC_PD_DATA_HIGH_PRIOTITY 2 //Beacon request Beacon response
|
||||||
|
|
||||||
#define MCPS_SAP_DATA_IND_EVENT 1
|
#define MCPS_SAP_DATA_IND_EVENT 1
|
||||||
#define MCPS_SAP_DATA_CNF_EVENT 2
|
#define MCPS_SAP_DATA_CNF_EVENT 2
|
||||||
#define MAC_MLME_EVENT_HANDLER 3
|
#define MCPS_SAP_DATA_CNF_FAIL_EVENT 3
|
||||||
#define MAC_MCPS_INDIRECT_TIMER_CB 4
|
#define MAC_MLME_EVENT_HANDLER 4
|
||||||
#define MAC_MLME_SCAN_CONFIRM_HANDLER 5
|
#define MAC_MCPS_INDIRECT_TIMER_CB 5
|
||||||
#define MAC_SAP_TRIG_TX 6
|
#define MAC_MLME_SCAN_CONFIRM_HANDLER 6
|
||||||
#define MCPS_SAP_DATA_ACK_CNF_EVENT 7
|
#define MAC_SAP_TRIG_TX 7
|
||||||
|
#define MCPS_SAP_DATA_ACK_CNF_EVENT 8
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief struct mac_aux_security_header_t MAC auxiliarity security header structure
|
* @brief struct mac_aux_security_header_t MAC auxiliarity security header structure
|
||||||
|
@ -180,7 +180,9 @@ int8_t mcps_sap_pd_ind(mac_pre_parsed_frame_t *buffer);
|
||||||
/**
|
/**
|
||||||
* MAC MCPS SAP layer data confirmation event trig
|
* MAC MCPS SAP layer data confirmation event trig
|
||||||
*/
|
*/
|
||||||
void mcps_sap_pd_confirm(void *mac_ptr);
|
int8_t mcps_sap_pd_confirm(void *mac_ptr);
|
||||||
|
|
||||||
|
int8_t mcps_sap_pd_confirm_failure(void *mac_ptr);
|
||||||
|
|
||||||
void mcps_sap_pd_ack(void *ack_ptr);
|
void mcps_sap_pd_ack(void *ack_ptr);
|
||||||
|
|
||||||
|
@ -200,7 +202,7 @@ int mac_convert_frame_type_to_fhss(uint8_t frame_type);
|
||||||
|
|
||||||
void mcps_sap_trig_tx(void *mac_ptr);
|
void mcps_sap_trig_tx(void *mac_ptr);
|
||||||
|
|
||||||
void mcps_sap_purge_reg_handler(struct protocol_interface_rf_mac_setup *rf_mac_setup, const struct mcps_purge_s *purge_req);
|
uint8_t mcps_sap_purge_reg_handler(struct protocol_interface_rf_mac_setup *rf_mac_setup, const struct mcps_purge_s *purge_req);
|
||||||
|
|
||||||
int8_t mcps_pd_data_rebuild(struct protocol_interface_rf_mac_setup *rf_ptr, mac_pre_build_frame_t *buffer);
|
int8_t mcps_pd_data_rebuild(struct protocol_interface_rf_mac_setup *rf_ptr, mac_pre_build_frame_t *buffer);
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ static void mac_mlme_energy_scan_start(protocol_interface_rf_mac_setup_s *rf_mac
|
||||||
rf_mac_setup->macRfRadioTxActive = false;
|
rf_mac_setup->macRfRadioTxActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t mlme_scan_analyze_next_channel(channel_list_s *mac_channel_list)
|
uint16_t mlme_scan_analyze_next_channel(channel_list_s *mac_channel_list, bool clear_channel)
|
||||||
{
|
{
|
||||||
uint8_t i, j = 0, k = 1;
|
uint8_t i, j = 0, k = 1;
|
||||||
uint32_t mask = 1;
|
uint32_t mask = 1;
|
||||||
|
@ -101,7 +101,9 @@ uint16_t mlme_scan_analyze_next_channel(channel_list_s *mac_channel_list)
|
||||||
{
|
{
|
||||||
if (*channel_mask & mask)
|
if (*channel_mask & mask)
|
||||||
{
|
{
|
||||||
*channel_mask &= ~mask;
|
if (clear_channel) {
|
||||||
|
*channel_mask &= ~mask;
|
||||||
|
}
|
||||||
return (i+j*32);
|
return (i+j*32);
|
||||||
}
|
}
|
||||||
mask <<= 1;
|
mask <<= 1;
|
||||||
|
@ -280,7 +282,7 @@ static void mac_mlme_scan_start(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
||||||
{
|
{
|
||||||
uint8_t channel;
|
uint8_t channel;
|
||||||
|
|
||||||
channel = (uint8_t) mlme_scan_analyze_next_channel(&rf_mac_setup->mac_channel_list);
|
channel = (uint8_t) mlme_scan_analyze_next_channel(&rf_mac_setup->mac_channel_list, true);
|
||||||
mac_mlme_scan_init(channel, rf_mac_setup);
|
mac_mlme_scan_init(channel, rf_mac_setup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,14 +402,14 @@ int8_t mac_mlme_start_req(const mlme_start_t *s, struct protocol_interface_rf_ma
|
||||||
|
|
||||||
tr_debug("MAC: Start network %u channel %x panid", s->LogicalChannel, s->PANId);
|
tr_debug("MAC: Start network %u channel %x panid", s->LogicalChannel, s->PANId);
|
||||||
mac_mlme_set_panid(rf_mac_setup, s->PANId);
|
mac_mlme_set_panid(rf_mac_setup, s->PANId);
|
||||||
|
|
||||||
// Synchronize FHSS
|
// Synchronize FHSS
|
||||||
if (rf_mac_setup->fhss_api) {
|
if (rf_mac_setup->fhss_api) {
|
||||||
rf_mac_setup->fhss_api->synch_state_set(rf_mac_setup->fhss_api, FHSS_SYNCHRONIZED, s->PANId);
|
rf_mac_setup->mac_channel = rf_mac_setup->fhss_api->synch_state_set(rf_mac_setup->fhss_api, FHSS_SYNCHRONIZED, s->PANId);
|
||||||
}
|
} else {
|
||||||
|
|
||||||
if (!rf_mac_setup->fhss_api) {
|
|
||||||
rf_mac_setup->mac_channel = s->LogicalChannel;
|
rf_mac_setup->mac_channel = s->LogicalChannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
mac_mlme_start_request(rf_mac_setup);
|
mac_mlme_start_request(rf_mac_setup);
|
||||||
if (s->PANCoordinator) {
|
if (s->PANCoordinator) {
|
||||||
//tr_debug("Cordinator");
|
//tr_debug("Cordinator");
|
||||||
|
@ -795,7 +797,7 @@ static void mlme_scan_operation(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
||||||
resp->ResultListSize++;
|
resp->ResultListSize++;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel = mlme_scan_analyze_next_channel(&rf_mac_setup->mac_channel_list);
|
channel = mlme_scan_analyze_next_channel(&rf_mac_setup->mac_channel_list, true);
|
||||||
if (channel > 0xff || rf_mac_setup->mac_mlme_scan_resp->ResultListSize == MLME_MAC_RES_SIZE_MAX) {
|
if (channel > 0xff || rf_mac_setup->mac_mlme_scan_resp->ResultListSize == MLME_MAC_RES_SIZE_MAX) {
|
||||||
resp->status = MLME_SUCCESS;
|
resp->status = MLME_SUCCESS;
|
||||||
tr_debug("Scan Complete..Halt MAC");
|
tr_debug("Scan Complete..Halt MAC");
|
||||||
|
@ -981,6 +983,7 @@ void mac_mlme_data_base_deallocate(struct protocol_interface_rf_mac_setup *rf_ma
|
||||||
eventOS_callback_timer_unregister(rf_mac->mac_mcps_timer);
|
eventOS_callback_timer_unregister(rf_mac->mac_mcps_timer);
|
||||||
|
|
||||||
ns_dyn_mem_free(rf_mac->dev_driver_tx_buffer.buf);
|
ns_dyn_mem_free(rf_mac->dev_driver_tx_buffer.buf);
|
||||||
|
ns_dyn_mem_free(rf_mac->dev_driver_tx_buffer.enhanced_ack_buf);
|
||||||
ns_dyn_mem_free(rf_mac->mac_beacon_payload);
|
ns_dyn_mem_free(rf_mac->mac_beacon_payload);
|
||||||
|
|
||||||
mac_sec_mib_deinit(rf_mac);
|
mac_sec_mib_deinit(rf_mac);
|
||||||
|
@ -1510,8 +1513,9 @@ int8_t mac_mlme_rf_channel_change(protocol_interface_rf_mac_setup_s *rf_mac_setu
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
platform_enter_critical();
|
platform_enter_critical();
|
||||||
rf_mac_setup->mac_channel = new_channel;
|
if (rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_CHANNEL, &new_channel) == 0) {
|
||||||
rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_CHANNEL, &rf_mac_setup->mac_channel);
|
rf_mac_setup->mac_channel = new_channel;
|
||||||
|
}
|
||||||
platform_exit_critical();
|
platform_exit_critical();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,6 +125,6 @@ int8_t mac_mlme_beacon_tx(struct protocol_interface_rf_mac_setup *rf_ptr);
|
||||||
uint8_t mac_mlme_beacon_req_tx(struct protocol_interface_rf_mac_setup *rf_ptr);
|
uint8_t mac_mlme_beacon_req_tx(struct protocol_interface_rf_mac_setup *rf_ptr);
|
||||||
int8_t mac_mlme_virtual_confirmation_handle(int8_t driver_id, const uint8_t *data_ptr, uint16_t length);
|
int8_t mac_mlme_virtual_confirmation_handle(int8_t driver_id, const uint8_t *data_ptr, uint16_t length);
|
||||||
|
|
||||||
uint16_t mlme_scan_analyze_next_channel(struct channel_list_s *mac_channel_list);
|
uint16_t mlme_scan_analyze_next_channel(struct channel_list_s *mac_channel_list, bool clear_channel);
|
||||||
|
|
||||||
#endif /* MAC_MLME_H_ */
|
#endif /* MAC_MLME_H_ */
|
||||||
|
|
|
@ -38,8 +38,13 @@
|
||||||
/* Define TX Timeot Period */
|
/* Define TX Timeot Period */
|
||||||
// Hardcoded to 1200ms. Should be changed dynamic: (FHSS) channel retries needs longer timeout
|
// Hardcoded to 1200ms. Should be changed dynamic: (FHSS) channel retries needs longer timeout
|
||||||
#define NWKTX_TIMEOUT_PERIOD (1200*20)
|
#define NWKTX_TIMEOUT_PERIOD (1200*20)
|
||||||
|
// Measured 3750us with 1280 byte secured packet from calculating TX time to starting CSMA timer on PHY.
|
||||||
|
// Typically varies from 500us to several milliseconds depending on packet size and the platform.
|
||||||
|
// MAC should learn and make this dynamic by sending first few packets with predefined CSMA period.
|
||||||
|
#define MIN_FHSS_CSMA_PERIOD_US 4000
|
||||||
|
|
||||||
static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *rf_ptr, phy_link_tx_status_e status, uint8_t cca_retry, uint8_t tx_retry);
|
static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *rf_ptr, phy_link_tx_status_e status, uint8_t cca_retry, uint8_t tx_retry);
|
||||||
|
static void mac_sap_cca_fail_cb(protocol_interface_rf_mac_setup_s *rf_ptr);
|
||||||
|
|
||||||
void mac_csma_param_init(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
void mac_csma_param_init(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
||||||
{
|
{
|
||||||
|
@ -64,7 +69,7 @@ static uint16_t mac_csma_backoff_period_convert_to50us(uint8_t random, uint8_t b
|
||||||
return (random * backoff_period_in_10us) / 5;
|
return (random * backoff_period_in_10us) / 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mac_csma_backoff_start(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
void mac_csma_backoff_start(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
||||||
{
|
{
|
||||||
uint8_t backoff = mac_csma_random_backoff_get(rf_mac_setup);
|
uint8_t backoff = mac_csma_random_backoff_get(rf_mac_setup);
|
||||||
uint16_t backoff_slots = mac_csma_backoff_period_convert_to50us(backoff, rf_mac_setup->backoff_period_in_10us);
|
uint16_t backoff_slots = mac_csma_backoff_period_convert_to50us(backoff, rf_mac_setup->backoff_period_in_10us);
|
||||||
|
@ -90,6 +95,13 @@ uint32_t mac_csma_backoff_get(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
||||||
if (backoff_in_us == 0) {
|
if (backoff_in_us == 0) {
|
||||||
backoff_in_us = 1;
|
backoff_in_us = 1;
|
||||||
}
|
}
|
||||||
|
if (rf_mac_setup->fhss_api) {
|
||||||
|
// Synchronization error when backoff time is shorter than allowed.
|
||||||
|
// TODO: Make this dynamic.
|
||||||
|
if (backoff_in_us < MIN_FHSS_CSMA_PERIOD_US) {
|
||||||
|
backoff_in_us += MIN_FHSS_CSMA_PERIOD_US;
|
||||||
|
}
|
||||||
|
}
|
||||||
return backoff_in_us;
|
return backoff_in_us;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,21 +148,31 @@ int8_t mac_plme_cca_req(protocol_interface_rf_mac_setup_s *rf_mac_setup) {
|
||||||
dev_driver_tx_buffer_s *tx_buf = &rf_mac_setup->dev_driver_tx_buffer;
|
dev_driver_tx_buffer_s *tx_buf = &rf_mac_setup->dev_driver_tx_buffer;
|
||||||
phy_device_driver_s *dev_driver = rf_mac_setup->dev_driver->phy_driver;
|
phy_device_driver_s *dev_driver = rf_mac_setup->dev_driver->phy_driver;
|
||||||
|
|
||||||
|
rf_mac_setup->macRfRadioTxActive = true;
|
||||||
if (dev_driver->arm_net_virtual_tx_cb) {
|
if (dev_driver->arm_net_virtual_tx_cb) {
|
||||||
if (dev_driver->tx(tx_buf->buf, tx_buf->len, 1, PHY_LAYER_PAYLOAD) == 0) {
|
if (dev_driver->tx(tx_buf->buf, tx_buf->len, 1, PHY_LAYER_PAYLOAD) == 0) {
|
||||||
rf_mac_setup->macRfRadioTxActive = true;
|
|
||||||
timer_mac_start(rf_mac_setup, MAC_TX_TIMEOUT, NWKTX_TIMEOUT_PERIOD); /*Start Timeout timer for virtual packet loss*/
|
timer_mac_start(rf_mac_setup, MAC_TX_TIMEOUT, NWKTX_TIMEOUT_PERIOD); /*Start Timeout timer for virtual packet loss*/
|
||||||
} else {
|
} else {
|
||||||
|
rf_mac_setup->macRfRadioTxActive = false;
|
||||||
mac_data_interface_tx_to_cb(rf_mac_setup);
|
mac_data_interface_tx_to_cb(rf_mac_setup);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev_driver->tx(tx_buf->buf, tx_buf->len, 1, PHY_LAYER_PAYLOAD) == 0) {
|
uint8_t *buffer;
|
||||||
rf_mac_setup->macRfRadioTxActive = true;
|
uint16_t length;
|
||||||
|
if (rf_mac_setup->mac_ack_tx_active) {
|
||||||
|
buffer = tx_buf->enhanced_ack_buf;
|
||||||
|
length = tx_buf->ack_len;
|
||||||
|
} else {
|
||||||
|
buffer = tx_buf->buf;
|
||||||
|
length = tx_buf->len;
|
||||||
|
}
|
||||||
|
if (dev_driver->tx(buffer, length, 1, PHY_LAYER_PAYLOAD) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rf_mac_setup->macRfRadioTxActive = false;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,6 +241,12 @@ void mac_pd_sap_state_machine(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
||||||
if (rf_mac_setup->macUpState && rf_mac_setup->macTxProcessActive) {
|
if (rf_mac_setup->macUpState && rf_mac_setup->macTxProcessActive) {
|
||||||
|
|
||||||
if (rf_mac_setup->mac_tx_result == MAC_TIMER_CCA) {
|
if (rf_mac_setup->mac_tx_result == MAC_TIMER_CCA) {
|
||||||
|
|
||||||
|
if (rf_mac_setup->rf_csma_extension_supported) {
|
||||||
|
mac_sap_cca_fail_cb(rf_mac_setup);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (rf_mac_setup->fhss_api) {
|
if (rf_mac_setup->fhss_api) {
|
||||||
uint8_t *synch_info = NULL;
|
uint8_t *synch_info = NULL;
|
||||||
mac_pre_build_frame_t *active_buf = rf_mac_setup->active_pd_data_request;
|
mac_pre_build_frame_t *active_buf = rf_mac_setup->active_pd_data_request;
|
||||||
|
@ -254,6 +282,9 @@ void mac_pd_sap_state_machine(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
||||||
if (tx_handle_retval == -3) {
|
if (tx_handle_retval == -3) {
|
||||||
mac_tx_done_state_set(rf_mac_setup, MAC_CCA_FAIL);
|
mac_tx_done_state_set(rf_mac_setup, MAC_CCA_FAIL);
|
||||||
return;
|
return;
|
||||||
|
} else if (tx_handle_retval == -2) {
|
||||||
|
mac_tx_done_state_set(rf_mac_setup, MAC_UNKNOWN_DESTINATION);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mac_plme_cca_req(rf_mac_setup) != 0) {
|
if (mac_plme_cca_req(rf_mac_setup) != 0) {
|
||||||
|
@ -267,16 +298,24 @@ void mac_pd_sap_state_machine(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mac_sap_cca_fail_cb(protocol_interface_rf_mac_setup_s *rf_ptr) {
|
static void mac_sap_cca_fail_cb(protocol_interface_rf_mac_setup_s *rf_ptr)
|
||||||
rf_ptr->macRfRadioTxActive = false;
|
{
|
||||||
if (rf_ptr->mac_cca_retry > rf_ptr->macMaxCSMABackoffs || (rf_ptr->active_pd_data_request && rf_ptr->active_pd_data_request->asynch_request)) {
|
if (rf_ptr->mac_ack_tx_active) {
|
||||||
//Send MAC_CCA_FAIL
|
if (rf_ptr->active_pd_data_request) {
|
||||||
mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL);
|
mac_csma_backoff_start(rf_ptr);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
timer_mac_stop(rf_ptr);
|
|
||||||
mac_csma_BE_update(rf_ptr);
|
rf_ptr->macRfRadioTxActive = false;
|
||||||
if (mcps_pd_data_rebuild(rf_ptr, rf_ptr->active_pd_data_request) ) {
|
if (rf_ptr->mac_cca_retry > rf_ptr->macMaxCSMABackoffs || (rf_ptr->active_pd_data_request && rf_ptr->active_pd_data_request->asynch_request)) {
|
||||||
|
//Send MAC_CCA_FAIL
|
||||||
mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL);
|
mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL);
|
||||||
|
} else {
|
||||||
|
timer_mac_stop(rf_ptr);
|
||||||
|
mac_csma_BE_update(rf_ptr);
|
||||||
|
if (mcps_pd_data_rebuild(rf_ptr, rf_ptr->active_pd_data_request) ) {
|
||||||
|
mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -322,6 +361,20 @@ static bool mac_data_counter_too_small(uint32_t current_counter, uint32_t packet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool mac_data_asynch_channel_switch(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *active_buf)
|
||||||
|
{
|
||||||
|
if (!active_buf || !active_buf->asynch_request) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
active_buf->asynch_channel = rf_ptr->mac_channel; //Store Original channel
|
||||||
|
uint16_t channel = mlme_scan_analyze_next_channel(&active_buf->asynch_channel_list, true);
|
||||||
|
if (channel <= 0xff) {
|
||||||
|
mac_mlme_rf_channel_change(rf_ptr, channel);
|
||||||
|
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *rf_ptr, phy_link_tx_status_e status, uint8_t cca_retry, uint8_t tx_retry)
|
static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *rf_ptr, phy_link_tx_status_e status, uint8_t cca_retry, uint8_t tx_retry)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -330,10 +383,16 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == PHY_LINK_CCA_PREPARE) {
|
if (status == PHY_LINK_CCA_PREPARE) {
|
||||||
|
|
||||||
|
if (rf_ptr->mac_ack_tx_active) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mac_data_asynch_channel_switch(rf_ptr, rf_ptr->active_pd_data_request) ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (rf_ptr->fhss_api) {
|
if (rf_ptr->fhss_api) {
|
||||||
if (rf_ptr->mac_ack_tx_active) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
mac_pre_build_frame_t *active_buf = rf_ptr->active_pd_data_request;
|
mac_pre_build_frame_t *active_buf = rf_ptr->active_pd_data_request;
|
||||||
if (!active_buf) {
|
if (!active_buf) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -345,25 +404,28 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r
|
||||||
uint8_t *synch_info = tx_buf->buf + rf_ptr->dev_driver->phy_driver->phy_header_length + tx_buf->len - FHSS_SYNCH_INFO_LENGTH;
|
uint8_t *synch_info = tx_buf->buf + rf_ptr->dev_driver->phy_driver->phy_header_length + tx_buf->len - FHSS_SYNCH_INFO_LENGTH;
|
||||||
rf_ptr->fhss_api->write_synch_info(rf_ptr->fhss_api, synch_info, 0, FHSS_SYNCH_FRAME, 0);
|
rf_ptr->fhss_api->write_synch_info(rf_ptr->fhss_api, synch_info, 0, FHSS_SYNCH_FRAME, 0);
|
||||||
}
|
}
|
||||||
if (active_buf->asynch_request == false) {
|
|
||||||
// Change to destination channel and write synchronization info to Beacon frames here
|
// Change to destination channel and write synchronization info to Beacon frames here
|
||||||
int tx_handle_retval = rf_ptr->fhss_api->tx_handle(rf_ptr->fhss_api, !mac_is_ack_request_set(active_buf),
|
int tx_handle_retval = rf_ptr->fhss_api->tx_handle(rf_ptr->fhss_api, !mac_is_ack_request_set(active_buf),
|
||||||
active_buf->DstAddr, mac_convert_frame_type_to_fhss(active_buf->fcf_dsn.frametype),
|
active_buf->DstAddr, mac_convert_frame_type_to_fhss(active_buf->fcf_dsn.frametype),
|
||||||
active_buf->mac_payload_length, rf_ptr->dev_driver->phy_driver->phy_header_length,
|
active_buf->mac_payload_length, rf_ptr->dev_driver->phy_driver->phy_header_length,
|
||||||
rf_ptr->dev_driver->phy_driver->phy_tail_length, active_buf->tx_time);
|
rf_ptr->dev_driver->phy_driver->phy_tail_length, active_buf->tx_time);
|
||||||
// When FHSS TX handle returns -1, transmission of the packet is currently not allowed -> restart CCA timer
|
// When FHSS TX handle returns -1, transmission of the packet is currently not allowed -> restart CCA timer
|
||||||
if (tx_handle_retval == -1) {
|
if (tx_handle_retval == -1) {
|
||||||
mac_sap_cca_fail_cb(rf_ptr);
|
mac_sap_cca_fail_cb(rf_ptr);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
// When FHSS TX handle returns -3, we are trying to transmit broadcast packet on unicast channel -> push back
|
// When FHSS TX handle returns -3, we are trying to transmit broadcast packet on unicast channel -> push back
|
||||||
// to queue by using CCA fail event
|
// to queue by using CCA fail event
|
||||||
if (tx_handle_retval == -3) {
|
if (tx_handle_retval == -3) {
|
||||||
mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL);
|
mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL);
|
||||||
return -3;
|
return -3;
|
||||||
}
|
} else if (tx_handle_retval == -2) {
|
||||||
|
mac_tx_done_state_set(rf_ptr, MAC_UNKNOWN_DESTINATION);
|
||||||
|
return -2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,6 +435,10 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r
|
||||||
|
|
||||||
if (rf_ptr->mac_ack_tx_active) {
|
if (rf_ptr->mac_ack_tx_active) {
|
||||||
rf_ptr->mac_ack_tx_active = false;
|
rf_ptr->mac_ack_tx_active = false;
|
||||||
|
if (rf_ptr->fhss_api) {
|
||||||
|
//SET tx completed false because ack isnot never queued
|
||||||
|
rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, false, false, 0xff);
|
||||||
|
}
|
||||||
if (rf_ptr->active_pd_data_request) {
|
if (rf_ptr->active_pd_data_request) {
|
||||||
|
|
||||||
if (rf_ptr->active_pd_data_request->fcf_dsn.securityEnabled) {
|
if (rf_ptr->active_pd_data_request->fcf_dsn.securityEnabled) {
|
||||||
|
@ -450,7 +516,7 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r
|
||||||
static int8_t mac_data_interface_tx_done_by_ack_cb(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_parsed_frame_t *buf)
|
static int8_t mac_data_interface_tx_done_by_ack_cb(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_parsed_frame_t *buf)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!rf_ptr->macRfRadioTxActive) {
|
if (!rf_ptr->macRfRadioTxActive || !rf_ptr->active_pd_data_request || rf_ptr->active_pd_data_request->fcf_dsn.DSN != buf->fcf_dsn.DSN) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,9 +531,7 @@ static int8_t mac_data_interface_tx_done_by_ack_cb(protocol_interface_rf_mac_set
|
||||||
mcps_sap_pd_ack(buf);
|
mcps_sap_pd_ack(buf);
|
||||||
|
|
||||||
if (rf_ptr->fhss_api) {
|
if (rf_ptr->fhss_api) {
|
||||||
if (rf_ptr->active_pd_data_request->asynch_request == false) {
|
rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, false, true, rf_ptr->active_pd_data_request->msduHandle);
|
||||||
rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, false, true, rf_ptr->active_pd_data_request->msduHandle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -611,8 +675,6 @@ int8_t mac_pd_sap_data_cb(void *identifier, arm_phy_sap_msg_t *message)
|
||||||
if (mcps_generic_ack_build(rf_ptr, &fcf_read, pd_data_ind->data_ptr, &ack_payload, time_stamp) !=0) {
|
if (mcps_generic_ack_build(rf_ptr, &fcf_read, pd_data_ind->data_ptr, &ack_payload, time_stamp) !=0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rf_ptr->mac_ack_tx_active = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,8 @@ int8_t mac_pd_sap_data_cb(void *identifier, struct arm_phy_sap_msg_s *message);
|
||||||
void mac_csma_param_init(struct protocol_interface_rf_mac_setup *rf_mac_setup);
|
void mac_csma_param_init(struct protocol_interface_rf_mac_setup *rf_mac_setup);
|
||||||
|
|
||||||
uint32_t mac_csma_backoff_get(struct protocol_interface_rf_mac_setup *rf_mac_setup);
|
uint32_t mac_csma_backoff_get(struct protocol_interface_rf_mac_setup *rf_mac_setup);
|
||||||
|
|
||||||
|
void mac_csma_backoff_start(struct protocol_interface_rf_mac_setup *rf_mac_setup);
|
||||||
/**
|
/**
|
||||||
* Run Mac data interface state Machine.
|
* Run Mac data interface state Machine.
|
||||||
*
|
*
|
||||||
|
|
|
@ -54,7 +54,7 @@ static int8_t ns_sw_mac_api_enable_mcps_ext(mac_api_t *api, mcps_data_indication
|
||||||
static void mlme_req(const mac_api_t* api, mlme_primitive id, const void *data);
|
static void mlme_req(const mac_api_t* api, mlme_primitive id, const void *data);
|
||||||
static void mcps_req(const mac_api_t* api, const mcps_data_req_t *data);
|
static void mcps_req(const mac_api_t* api, const mcps_data_req_t *data);
|
||||||
static void mcps_req_ext(const mac_api_t* api, const mcps_data_req_t *data, const mcps_data_req_ie_list_t *ie_ext, const channel_list_s *asynch_channel_list);
|
static void mcps_req_ext(const mac_api_t* api, const mcps_data_req_t *data, const mcps_data_req_ie_list_t *ie_ext, const channel_list_s *asynch_channel_list);
|
||||||
static void purge_req(const mac_api_t* api, const mcps_purge_t *data);
|
static uint8_t purge_req(const mac_api_t* api, const mcps_purge_t *data);
|
||||||
static int8_t macext_mac64_address_set( const mac_api_t* api, const uint8_t *mac64);
|
static int8_t macext_mac64_address_set( const mac_api_t* api, const uint8_t *mac64);
|
||||||
static int8_t macext_mac64_address_get( const mac_api_t* api, mac_extended_address_type type, uint8_t *mac64_buf);
|
static int8_t macext_mac64_address_get( const mac_api_t* api, mac_extended_address_type type, uint8_t *mac64_buf);
|
||||||
|
|
||||||
|
@ -176,6 +176,7 @@ int ns_sw_mac_fhss_register(mac_api_t *mac_api, fhss_api_t *fhss_api)
|
||||||
fhss_callback_t callbacks;
|
fhss_callback_t callbacks;
|
||||||
callbacks.read_tx_queue_size = &mac_read_tx_queue_sizes;
|
callbacks.read_tx_queue_size = &mac_read_tx_queue_sizes;
|
||||||
callbacks.read_datarate = &mac_read_phy_datarate;
|
callbacks.read_datarate = &mac_read_phy_datarate;
|
||||||
|
callbacks.read_timestamp = &mac_read_phy_timestamp;
|
||||||
callbacks.read_mac_address = &mac_read_64bit_mac_address;
|
callbacks.read_mac_address = &mac_read_64bit_mac_address;
|
||||||
callbacks.change_channel = &mac_set_channel;
|
callbacks.change_channel = &mac_set_channel;
|
||||||
callbacks.send_fhss_frame = &mac_fhss_frame_tx;
|
callbacks.send_fhss_frame = &mac_fhss_frame_tx;
|
||||||
|
@ -251,6 +252,22 @@ static int8_t ns_sw_mac_api_enable_mcps_ext(mac_api_t *api, mcps_data_indication
|
||||||
cur->data_ind_ext_cb = data_ind_cb;
|
cur->data_ind_ext_cb = data_ind_cb;
|
||||||
cur->enhanced_ack_data_req_cb = ack_data_req_cb;
|
cur->enhanced_ack_data_req_cb = ack_data_req_cb;
|
||||||
if (data_cnf_cb && data_ind_cb && ack_data_req_cb) {
|
if (data_cnf_cb && data_ind_cb && ack_data_req_cb) {
|
||||||
|
arm_device_driver_list_s *dev_driver = mac_store.setup->dev_driver;
|
||||||
|
ns_dyn_mem_free(mac_store.setup->dev_driver_tx_buffer.enhanced_ack_buf);
|
||||||
|
|
||||||
|
uint16_t total_length;
|
||||||
|
if (ENHANCED_ACK_MAX_LENGTH > dev_driver->phy_driver->phy_MTU) {
|
||||||
|
total_length = dev_driver->phy_driver->phy_MTU;
|
||||||
|
} else {
|
||||||
|
total_length = ENHANCED_ACK_MAX_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_length += (dev_driver->phy_driver->phy_header_length + dev_driver->phy_driver->phy_tail_length);
|
||||||
|
mac_store.setup->dev_driver_tx_buffer.enhanced_ack_buf = ns_dyn_mem_alloc(total_length);
|
||||||
|
if (!mac_store.setup->dev_driver_tx_buffer.enhanced_ack_buf) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
mac_store.setup->mac_extension_enabled = true;
|
mac_store.setup->mac_extension_enabled = true;
|
||||||
} else {
|
} else {
|
||||||
mac_store.setup->mac_extension_enabled = false;
|
mac_store.setup->mac_extension_enabled = false;
|
||||||
|
@ -509,11 +526,12 @@ void mcps_req_ext(const mac_api_t* api, const mcps_data_req_t *data, const mcps_
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void purge_req(const mac_api_t* api, const mcps_purge_t *data)
|
static uint8_t purge_req(const mac_api_t* api, const mcps_purge_t *data)
|
||||||
{
|
{
|
||||||
if (mac_store.mac_api == api) {
|
if (mac_store.mac_api == api) {
|
||||||
mcps_sap_purge_reg_handler(mac_store.setup , data );
|
return mcps_sap_purge_reg_handler(mac_store.setup , data );
|
||||||
}
|
}
|
||||||
|
return MLME_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int8_t macext_mac64_address_set( const mac_api_t* api, const uint8_t *mac64)
|
static int8_t macext_mac64_address_set( const mac_api_t* api, const uint8_t *mac64)
|
||||||
|
@ -587,8 +605,7 @@ static int8_t sw_mac_net_phy_tx_done(int8_t driver_id, uint8_t tx_handle, phy_li
|
||||||
phy_msg.message.mac15_4_pd_sap_confirm.cca_retry = cca_retry;
|
phy_msg.message.mac15_4_pd_sap_confirm.cca_retry = cca_retry;
|
||||||
phy_msg.message.mac15_4_pd_sap_confirm.tx_retry = tx_retry;
|
phy_msg.message.mac15_4_pd_sap_confirm.tx_retry = tx_retry;
|
||||||
|
|
||||||
mac_pd_sap_data_cb(driver->phy_sap_identifier, &phy_msg);
|
return mac_pd_sap_data_cb(driver->phy_sap_identifier, &phy_msg);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bc_enable_timer_cb(int8_t timer_id, uint16_t slots)
|
static void bc_enable_timer_cb(int8_t timer_id, uint16_t slots)
|
||||||
|
|
|
@ -1011,17 +1011,41 @@ void mpl_clear_realm_scope_seeds(protocol_interface_info_entry_t *cur)
|
||||||
static buffer_t *mpl_exthdr_provider(buffer_t *buf, ipv6_exthdr_stage_t stage, int16_t *result)
|
static buffer_t *mpl_exthdr_provider(buffer_t *buf, ipv6_exthdr_stage_t stage, int16_t *result)
|
||||||
{
|
{
|
||||||
mpl_domain_t *domain = mpl_domain_lookup_with_realm_check(buf->interface, buf->dst_sa.address);
|
mpl_domain_t *domain = mpl_domain_lookup_with_realm_check(buf->interface, buf->dst_sa.address);
|
||||||
if (!domain) {
|
|
||||||
// We need to tunnel
|
|
||||||
|
|
||||||
if (stage != IPV6_EXTHDR_MODIFY) {
|
/* Deal with simpler modify-already-created-header case first. Note that no error returns. */
|
||||||
*result = 0;
|
if (stage == IPV6_EXTHDR_MODIFY) {
|
||||||
|
if (!domain) {
|
||||||
|
*result = IPV6_EXTHDR_MODIFY_TUNNEL;
|
||||||
|
memcpy(buf->dst_sa.address, ADDR_ALL_MPL_FORWARDERS, 16);
|
||||||
|
buf->src_sa.addr_type = ADDR_NONE; // force auto-selection
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
*result = IPV6_EXTHDR_MODIFY_TUNNEL;
|
if (buf->options.ip_extflags & IPEXT_HBH_MPL_UNFILLED) {
|
||||||
memcpy(buf->dst_sa.address, ADDR_ALL_MPL_FORWARDERS, 16);
|
/* We assume we created this, therefore our option is in place
|
||||||
buf->src_sa.addr_type = ADDR_NONE; // force auto-selection
|
* in the expected place. Sequence is set now, AFTER
|
||||||
|
* fragmentation.
|
||||||
|
*/
|
||||||
|
uint8_t *iphdr = buffer_data_pointer(buf);
|
||||||
|
uint8_t *ext = iphdr + IPV6_HDRLEN;
|
||||||
|
if (iphdr[IPV6_HDROFF_NH] != IPV6_NH_HOP_BY_HOP || ext[2] != IPV6_OPTION_MPL) {
|
||||||
|
tr_err("modify");
|
||||||
|
return buffer_free(buf);
|
||||||
|
}
|
||||||
|
/* We don't bother setting the M flag on these initial packets. Setting to 0 is always acceptable. */
|
||||||
|
ext[5] = domain->sequence++;
|
||||||
|
buf->options.ip_extflags &=~ IPEXT_HBH_MPL_UNFILLED;
|
||||||
|
buf->mpl_option_data_offset = IPV6_HDRLEN + 4;
|
||||||
|
mpl_forwarder_process_message(buf, domain, true);
|
||||||
|
}
|
||||||
|
*result = 0;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rest of code deals with header insertion */
|
||||||
|
if (!domain) {
|
||||||
|
// We will need to tunnel - do nothing on the inner packet
|
||||||
|
*result = 0;
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1112,26 +1136,6 @@ static buffer_t *mpl_exthdr_provider(buffer_t *buf, ipv6_exthdr_stage_t stage, i
|
||||||
buf->options.ip_extflags |= IPEXT_HBH_MPL | IPEXT_HBH_MPL_UNFILLED;
|
buf->options.ip_extflags |= IPEXT_HBH_MPL | IPEXT_HBH_MPL_UNFILLED;
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
case IPV6_EXTHDR_MODIFY:
|
|
||||||
if (buf->options.ip_extflags & IPEXT_HBH_MPL_UNFILLED) {
|
|
||||||
/* We assume we created this, therefore our option is in place
|
|
||||||
* in the expected place. Sequence is set now, AFTER
|
|
||||||
* fragmentation.
|
|
||||||
*/
|
|
||||||
uint8_t *iphdr = buffer_data_pointer(buf);
|
|
||||||
uint8_t *ext = iphdr + IPV6_HDRLEN;
|
|
||||||
if (iphdr[IPV6_HDROFF_NH] != IPV6_NH_HOP_BY_HOP || ext[2] != IPV6_OPTION_MPL) {
|
|
||||||
tr_err("modify");
|
|
||||||
return buffer_free(buf);
|
|
||||||
}
|
|
||||||
/* We don't bother setting the M flag on these initial packets. Setting to 0 is always acceptable. */
|
|
||||||
ext[5] = domain->sequence++;
|
|
||||||
buf->options.ip_extflags &=~ IPEXT_HBH_MPL_UNFILLED;
|
|
||||||
buf->mpl_option_data_offset = IPV6_HDRLEN + 4;
|
|
||||||
mpl_forwarder_process_message(buf, domain, true);
|
|
||||||
}
|
|
||||||
*result = 0;
|
|
||||||
return buf;
|
|
||||||
default:
|
default:
|
||||||
return buffer_free(buf);
|
return buffer_free(buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,9 +348,10 @@ void rpl_control_remove_domain_from_interface(protocol_interface_info_entry_t *c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rpl_control_set_callback(rpl_domain_t *domain, rpl_domain_callback_t callback, void *cb_handle)
|
void rpl_control_set_callback(rpl_domain_t *domain, rpl_domain_callback_t callback, rpl_prefix_callback_t prefix_learn_cb, void *cb_handle)
|
||||||
{
|
{
|
||||||
domain->callback = callback;
|
domain->callback = callback;
|
||||||
|
domain->prefix_cb = prefix_learn_cb;
|
||||||
domain->cb_handle = cb_handle;
|
domain->cb_handle = cb_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,28 +678,22 @@ static void rpl_control_process_prefix_options(protocol_interface_info_entry_t *
|
||||||
const uint8_t *prefix = ptr + 16;
|
const uint8_t *prefix = ptr + 16;
|
||||||
|
|
||||||
if (!pref_parent || neighbour == pref_parent) {
|
if (!pref_parent || neighbour == pref_parent) {
|
||||||
//Check is L Flag active
|
|
||||||
if (flags & PIO_L) {
|
|
||||||
//define ONLink Route Information
|
|
||||||
//tr_debug("Register On Link Prefix to routing table");
|
|
||||||
ipv6_route_add(prefix, prefix_len, cur->id, NULL, ROUTE_RADV, valid, 0);
|
|
||||||
}
|
|
||||||
/* Check if A-Flag.
|
|
||||||
* A RPL node may use this option for the purpose of Stateless Address Autoconfiguration (SLAAC)
|
|
||||||
* from a prefix advertised by a parent.
|
|
||||||
*/
|
|
||||||
if (pref_parent && (flags & PIO_A)) {
|
|
||||||
if (icmpv6_slaac_prefix_update(cur, prefix, prefix_len, valid, preferred) != 0) {
|
|
||||||
ipv6_interface_slaac_handler(cur, prefix, prefix_len, valid, preferred);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store prefixes for possible forwarding */
|
/* Store prefixes for possible forwarding */
|
||||||
/* XXX if leaf - don't bother? Or do we want to remember them for
|
/* XXX if leaf - don't bother? Or do we want to remember them for
|
||||||
* when we switch DODAG, as mentioned above?
|
* when we switch DODAG, as mentioned above?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
rpl_dodag_update_dio_prefix(dodag, prefix, prefix_len, flags, valid, preferred, false, true);
|
prefix_entry_t *prefix_entry = rpl_dodag_update_dio_prefix(dodag, prefix, prefix_len, flags, valid, preferred, false, true);
|
||||||
|
if (prefix_entry && pref_parent) {
|
||||||
|
rpl_control_process_prefix_option(prefix_entry, cur);
|
||||||
|
rpl_domain_t *domain = cur->rpl_domain;
|
||||||
|
if (domain && domain->prefix_cb) {
|
||||||
|
uint8_t ll_address[16];
|
||||||
|
memcpy(ll_address, rpl_neighbour_ll_address(pref_parent), 16);
|
||||||
|
domain->prefix_cb(prefix_entry, domain->cb_handle,ll_address);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & PIO_R) && !router_addr_set) {
|
if ((flags & PIO_R) && !router_addr_set) {
|
||||||
|
@ -715,6 +710,18 @@ static void rpl_control_process_prefix_options(protocol_interface_info_entry_t *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rpl_control_process_prefix_option(prefix_entry_t *prefix, protocol_interface_info_entry_t *cur)
|
||||||
|
{
|
||||||
|
//Check is L Flag active
|
||||||
|
if (prefix->options & PIO_L) {
|
||||||
|
//define ONLink Route Information
|
||||||
|
//tr_debug("Register On Link Prefix to routing table");
|
||||||
|
ipv6_route_add(prefix->prefix, prefix->prefix_len, cur->id, NULL, ROUTE_RADV, prefix->lifetime, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 0 1 2 3
|
* 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 4 5 6 7 8 9 0 1
|
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
@ -1004,7 +1011,7 @@ static buffer_t *rpl_control_dio_handler(protocol_interface_info_entry_t *cur, r
|
||||||
rpl_instance_consistent_rx(instance);
|
rpl_instance_consistent_rx(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl_instance_neighbours_changed(instance);
|
rpl_instance_neighbours_changed(instance, dodag);
|
||||||
|
|
||||||
return buffer_free(buf);
|
return buffer_free(buf);
|
||||||
|
|
||||||
|
|
|
@ -29,15 +29,19 @@ struct rpl_dodag;
|
||||||
struct buffer;
|
struct buffer;
|
||||||
struct protocol_interface_info_entry;
|
struct protocol_interface_info_entry;
|
||||||
struct rpl_dodag_info_t;
|
struct rpl_dodag_info_t;
|
||||||
|
struct prefix_entry_t;
|
||||||
|
|
||||||
typedef enum rpl_event {
|
typedef enum rpl_event {
|
||||||
RPL_EVENT_DAO_DONE, /* Simplistic trigger for bootstrap advance - a DAO registration completed */
|
RPL_EVENT_DAO_DONE, /* Simplistic trigger for bootstrap advance - a DAO registration completed */
|
||||||
RPL_EVENT_LOCAL_REPAIR_START, /* RPL start scanning new parent by multicast DIS user can disable beacon request responser here*/
|
RPL_EVENT_LOCAL_REPAIR_START, /* RPL start scanning new parent by multicast DIS user can disable beacon request responser here*/
|
||||||
RPL_EVENT_LOCAL_REPAIR_NO_MORE_DIS, /* RPL not sending DIS anymore user can report bootstrap error */
|
RPL_EVENT_LOCAL_REPAIR_NO_MORE_DIS, /* RPL not sending DIS anymore user can report bootstrap error */
|
||||||
|
RPL_EVENT_DAO_PARENT_SWITCH, /* RPL indicate that DAO downward Parent state have been updated */
|
||||||
} rpl_event_t;
|
} rpl_event_t;
|
||||||
|
|
||||||
typedef void rpl_domain_callback_t(rpl_event_t event, void *handle);
|
typedef void rpl_domain_callback_t(rpl_event_t event, void *handle);
|
||||||
|
|
||||||
|
typedef void rpl_prefix_callback_t(struct prefix_entry_t *prefix, void *handle, uint8_t *parent_link_local);
|
||||||
|
|
||||||
typedef struct rpl_domain
|
typedef struct rpl_domain
|
||||||
{
|
{
|
||||||
NS_LIST_HEAD_INCOMPLETE(struct rpl_instance) instances;
|
NS_LIST_HEAD_INCOMPLETE(struct rpl_instance) instances;
|
||||||
|
@ -50,6 +54,7 @@ typedef struct rpl_domain
|
||||||
/* As part of shutdown, we can force entering leaf mode */
|
/* As part of shutdown, we can force entering leaf mode */
|
||||||
bool force_leaf;
|
bool force_leaf;
|
||||||
rpl_domain_callback_t *callback;
|
rpl_domain_callback_t *callback;
|
||||||
|
rpl_prefix_callback_t *prefix_cb;
|
||||||
void *cb_handle;
|
void *cb_handle;
|
||||||
} rpl_domain_t;
|
} rpl_domain_t;
|
||||||
|
|
||||||
|
@ -100,6 +105,7 @@ void rpl_control_transmit_dio(struct rpl_domain *domain, struct protocol_interfa
|
||||||
bool rpl_control_transmit_dao(struct rpl_domain *domain, struct protocol_interface_info_entry *cur, struct rpl_instance *instance, uint8_t instance_id, uint8_t dao_sequence, const uint8_t dodagid[16], const uint8_t *opts, uint16_t opts_size, const uint8_t *dst);
|
bool rpl_control_transmit_dao(struct rpl_domain *domain, struct protocol_interface_info_entry *cur, struct rpl_instance *instance, uint8_t instance_id, uint8_t dao_sequence, const uint8_t dodagid[16], const uint8_t *opts, uint16_t opts_size, const uint8_t *dst);
|
||||||
void rpl_control_disable_ra_routes(struct rpl_domain *domain);
|
void rpl_control_disable_ra_routes(struct rpl_domain *domain);
|
||||||
void rpl_control_event(struct rpl_domain *domain, rpl_event_t event);
|
void rpl_control_event(struct rpl_domain *domain, rpl_event_t event);
|
||||||
|
void rpl_control_process_prefix_option(struct prefix_entry_t *prefix, struct protocol_interface_info_entry *cur);
|
||||||
|
|
||||||
/*********************** RPL control API to rest of system *******************/
|
/*********************** RPL control API to rest of system *******************/
|
||||||
|
|
||||||
|
@ -138,7 +144,7 @@ rpl_domain_t *rpl_control_create_domain(void);
|
||||||
void rpl_control_delete_domain(rpl_domain_t *domain);
|
void rpl_control_delete_domain(rpl_domain_t *domain);
|
||||||
void rpl_control_set_domain_on_interface(struct protocol_interface_info_entry *cur, rpl_domain_t *domain, bool downstream);
|
void rpl_control_set_domain_on_interface(struct protocol_interface_info_entry *cur, rpl_domain_t *domain, bool downstream);
|
||||||
void rpl_control_remove_domain_from_interface(struct protocol_interface_info_entry *cur);
|
void rpl_control_remove_domain_from_interface(struct protocol_interface_info_entry *cur);
|
||||||
void rpl_control_set_callback(rpl_domain_t *domain, rpl_domain_callback_t callback, void *cb_handle);
|
void rpl_control_set_callback(rpl_domain_t *domain, rpl_domain_callback_t callback, rpl_prefix_callback_t prefix_learn_cb, void *cb_handle);
|
||||||
|
|
||||||
/* Target publishing */
|
/* Target publishing */
|
||||||
void rpl_control_publish_host_address(rpl_domain_t *domain, const uint8_t addr[16], uint32_t lifetime);
|
void rpl_control_publish_host_address(rpl_domain_t *domain, const uint8_t addr[16], uint32_t lifetime);
|
||||||
|
@ -160,7 +166,6 @@ const rpl_dodag_conf_t *rpl_control_get_dodag_config(const struct rpl_instance *
|
||||||
const uint8_t *rpl_control_preferred_parent_addr(const struct rpl_instance *instance, bool global);
|
const uint8_t *rpl_control_preferred_parent_addr(const struct rpl_instance *instance, bool global);
|
||||||
uint16_t rpl_control_current_rank(const struct rpl_instance *instance);
|
uint16_t rpl_control_current_rank(const struct rpl_instance *instance);
|
||||||
|
|
||||||
|
|
||||||
#else /* HAVE_RPL */
|
#else /* HAVE_RPL */
|
||||||
|
|
||||||
#define rpl_control_fast_timer(ticks) ((void) 0)
|
#define rpl_control_fast_timer(ticks) ((void) 0)
|
||||||
|
|
|
@ -243,6 +243,8 @@ void rpl_downward_process_dao_parent_changes(rpl_instance_t *instance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//GENERATE PARENT Update event
|
||||||
|
rpl_control_event(instance->domain, RPL_EVENT_DAO_PARENT_SWITCH);
|
||||||
rpl_instance_dao_trigger(instance, 0);
|
rpl_instance_dao_trigger(instance, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -588,7 +590,7 @@ void rpl_instance_send_address_registration(protocol_interface_info_entry_t *int
|
||||||
|
|
||||||
aro.status = ARO_SUCCESS;
|
aro.status = ARO_SUCCESS;
|
||||||
aro.present = true;
|
aro.present = true;
|
||||||
aro.lifetime = addr->preferred_lifetime;
|
aro.lifetime = addr->valid_lifetime;
|
||||||
memcpy(aro.eui64, interface->mac, 8);
|
memcpy(aro.eui64, interface->mac, 8);
|
||||||
|
|
||||||
// go through neighbour list, and send to all assigned parents.
|
// go through neighbour list, and send to all assigned parents.
|
||||||
|
|
|
@ -134,6 +134,7 @@ typedef struct rpl_dao_non_root
|
||||||
uint32_t refresh_timer; /* Refresh timer (seconds) - 0xFFFFFFFF = infinite, 0 = not yet set */
|
uint32_t refresh_timer; /* Refresh timer (seconds) - 0xFFFFFFFF = infinite, 0 = not yet set */
|
||||||
} rpl_dao_non_root_t;
|
} rpl_dao_non_root_t;
|
||||||
|
|
||||||
|
|
||||||
/* Descriptor for a RPL DAO target */
|
/* Descriptor for a RPL DAO target */
|
||||||
struct rpl_dao_target
|
struct rpl_dao_target
|
||||||
{
|
{
|
||||||
|
|
|
@ -427,7 +427,7 @@ void rpl_delete_neighbour(rpl_instance_t *instance, rpl_neighbour_t *neighbour)
|
||||||
}
|
}
|
||||||
if (neighbour->dodag_parent) {
|
if (neighbour->dodag_parent) {
|
||||||
rpl_instance_remove_system_routes_through_parent(instance, neighbour);
|
rpl_instance_remove_system_routes_through_parent(instance, neighbour);
|
||||||
rpl_instance_neighbours_changed(instance);
|
rpl_instance_neighbours_changed(instance, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl_free(neighbour, sizeof *neighbour);
|
rpl_free(neighbour, sizeof *neighbour);
|
||||||
|
@ -1171,13 +1171,18 @@ bool rpl_instance_purge(rpl_instance_t *instance)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rpl_instance_neighbours_changed(rpl_instance_t *instance)
|
void rpl_instance_neighbours_changed(rpl_instance_t *instance, const rpl_dodag_t *dodag)
|
||||||
{
|
{
|
||||||
instance->neighbours_changed = true;
|
instance->neighbours_changed = true;
|
||||||
if (!rpl_instance_preferred_parent(instance)) {
|
uint16_t delay = rpl_policy_dio_parent_selection_delay(instance->domain);
|
||||||
rpl_instance_set_local_repair(instance, true);
|
if (dodag) {
|
||||||
|
//Convert imin 100ms tick to seconds
|
||||||
|
uint16_t i_min_delay = dodag->dio_timer_params.Imin / 10;
|
||||||
|
if (i_min_delay > delay) {
|
||||||
|
delay = i_min_delay;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rpl_instance_trigger_parent_selection(instance, rpl_policy_dio_parent_selection_delay(instance->domain));
|
rpl_instance_trigger_parent_selection(instance, delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rpl_instance_remove_parents(rpl_instance_t *instance)
|
static void rpl_instance_remove_parents(rpl_instance_t *instance)
|
||||||
|
@ -1366,7 +1371,18 @@ void rpl_instance_run_parent_selection(rpl_instance_t *instance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl_instance_set_local_repair(instance, preferred_parent == NULL);
|
//Control Local repair state
|
||||||
|
if (preferred_parent) {
|
||||||
|
// Always stop repair if we find a parent
|
||||||
|
rpl_instance_set_local_repair(instance, false);
|
||||||
|
} else if (original_preferred) {
|
||||||
|
// Only start repair if we just lost a parent
|
||||||
|
rpl_instance_set_local_repair(instance, true);
|
||||||
|
} else {
|
||||||
|
// !preferred_parent && !original_preferred - didn't have a parent,
|
||||||
|
// still don't. Leave repair flag as-is (would be off on initial start
|
||||||
|
// up, may be on if having problems mid-session).
|
||||||
|
}
|
||||||
|
|
||||||
if (rpl_instance_mop(instance) != RPL_MODE_NO_DOWNWARD) {
|
if (rpl_instance_mop(instance) != RPL_MODE_NO_DOWNWARD) {
|
||||||
rpl_downward_process_dao_parent_changes(instance);
|
rpl_downward_process_dao_parent_changes(instance);
|
||||||
|
@ -1384,6 +1400,20 @@ void rpl_instance_run_parent_selection(rpl_instance_t *instance)
|
||||||
rpl_control_print(trace_info_print);
|
rpl_control_print(trace_info_print);
|
||||||
/* Changing DODAG version is an inconsistency */
|
/* Changing DODAG version is an inconsistency */
|
||||||
if (original_version != instance->current_dodag_version) {
|
if (original_version != instance->current_dodag_version) {
|
||||||
|
//learn Routes an Prefixes
|
||||||
|
if (preferred_parent && instance->current_dodag_version) {
|
||||||
|
rpl_dodag_t *dodag = instance->current_dodag_version->dodag;
|
||||||
|
protocol_interface_info_entry_t *rpl_interface = protocol_stack_interface_info_get_by_id(preferred_parent->interface_id);
|
||||||
|
if (rpl_interface) {
|
||||||
|
ns_list_foreach(prefix_entry_t, prefix, &dodag->prefixes) {
|
||||||
|
rpl_control_process_prefix_option(prefix, rpl_interface);
|
||||||
|
if (instance->domain->prefix_cb) {
|
||||||
|
instance->domain->prefix_cb(prefix, rpl_interface, preferred_parent->ll_address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rpl_instance_inconsistency(instance);
|
rpl_instance_inconsistency(instance);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1536,6 +1566,7 @@ void rpl_instance_slow_timer(rpl_instance_t *instance, uint16_t seconds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void rpl_upward_dio_timer(rpl_instance_t *instance, uint16_t ticks)
|
void rpl_upward_dio_timer(rpl_instance_t *instance, uint16_t ticks)
|
||||||
{
|
{
|
||||||
rpl_dodag_version_t *dodag_version = instance->current_dodag_version;
|
rpl_dodag_version_t *dodag_version = instance->current_dodag_version;
|
||||||
|
|
|
@ -135,7 +135,7 @@ void rpl_neighbour_update_dodag_version(rpl_neighbour_t *neighbour, rpl_dodag_ve
|
||||||
bool rpl_neighbour_update_dtsn(rpl_neighbour_t *neighbour, uint8_t dtsn);
|
bool rpl_neighbour_update_dtsn(rpl_neighbour_t *neighbour, uint8_t dtsn);
|
||||||
rpl_instance_t *rpl_neighbour_instance(const rpl_neighbour_t *neighbour);
|
rpl_instance_t *rpl_neighbour_instance(const rpl_neighbour_t *neighbour);
|
||||||
|
|
||||||
void rpl_instance_neighbours_changed(rpl_instance_t *instance);
|
void rpl_instance_neighbours_changed(rpl_instance_t *instance, const rpl_dodag_t *dodag);
|
||||||
void rpl_instance_run_parent_selection(rpl_instance_t *instance);
|
void rpl_instance_run_parent_selection(rpl_instance_t *instance);
|
||||||
|
|
||||||
void rpl_upward_print_instance(rpl_instance_t *instance, route_print_fn_t *print_fn);
|
void rpl_upward_print_instance(rpl_instance_t *instance, route_print_fn_t *print_fn);
|
||||||
|
|
|
@ -81,6 +81,9 @@ void etx_transm_attempts_update(int8_t interface_id, uint8_t attempts, bool succ
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (entry->etx_samples < 7) {
|
||||||
|
entry->etx_samples++;
|
||||||
|
}
|
||||||
|
|
||||||
accumulated_failures = entry->accumulated_failures;
|
accumulated_failures = entry->accumulated_failures;
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ typedef struct etx_storage_s {
|
||||||
unsigned accumulated_failures: 5;
|
unsigned accumulated_failures: 5;
|
||||||
unsigned tmp_etx: 1;
|
unsigned tmp_etx: 1;
|
||||||
unsigned linkIdr: 4;
|
unsigned linkIdr: 4;
|
||||||
|
unsigned etx_samples: 3;
|
||||||
} etx_storage_t;
|
} etx_storage_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -17,25 +17,44 @@
|
||||||
#ifndef CHANNEL_FUNC_H_
|
#ifndef CHANNEL_FUNC_H_
|
||||||
#define CHANNEL_FUNC_H_
|
#define CHANNEL_FUNC_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function calculates nearest (higher) prime number for given start value.
|
||||||
|
* @param start_value Start value.
|
||||||
|
* @return Calculated prime number.
|
||||||
|
*/
|
||||||
|
uint16_t tr51_calc_nearest_prime_number(uint16_t start_value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize channel table for TR51 channel function.
|
||||||
|
* @param channel_table Channel table to be initialized.
|
||||||
|
* @param number_of_channels Number of channels.
|
||||||
|
* @return 0 Success, -1 Failure.
|
||||||
|
*/
|
||||||
|
int tr51_init_channel_table(int16_t *channel_table, int16_t number_of_channels);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compute the unicast schedule channel index using tr51 channel function.
|
* @brief Compute the unicast schedule channel index using tr51 channel function.
|
||||||
|
* @param channel_table Channel table.
|
||||||
|
* @param output_table Table used to generate output channel.
|
||||||
* @param slot_number Current slot number.
|
* @param slot_number Current slot number.
|
||||||
* @param mac MAC address of the node for which the index is calculated.
|
* @param mac MAC address of the node for which the index is calculated.
|
||||||
* @param number_of_channels Number of channels.
|
* @param number_of_channels Number of channels.
|
||||||
* @param excluded_channels Excluded channels.
|
* @param excluded_channels Excluded channels.
|
||||||
* @return Channel index.
|
* @return Channel index.
|
||||||
*/
|
*/
|
||||||
int32_t tr51_get_uc_channel_index(uint16_t slot_number, uint8_t *mac, int16_t number_of_channels, uint32_t *excluded_channels);
|
int32_t tr51_get_uc_channel_index(int16_t *channel_table, uint8_t *output_table, uint16_t slot_number, uint8_t *mac, int16_t number_of_channels, uint32_t *excluded_channels);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compute the broadcast schedule channel index using tr51 channel function.
|
* @brief Compute the broadcast schedule channel index using tr51 channel function.
|
||||||
|
* @param channel_table Channel table.
|
||||||
|
* @param output_table Table used to generate output channel.
|
||||||
* @param slot_number Current slot number.
|
* @param slot_number Current slot number.
|
||||||
* @param bsi Broadcast schedule identifier of the node for which the index is calculated.
|
* @param bsi Broadcast schedule identifier of the node for which the index is calculated.
|
||||||
* @param number_of_channels Number of channels.
|
* @param number_of_channels Number of channels.
|
||||||
* @param excluded_channels Excluded channels.
|
* @param excluded_channels Excluded channels.
|
||||||
* @return Channel index.
|
* @return Channel index.
|
||||||
*/
|
*/
|
||||||
int32_t tr51_get_bc_channel_index(uint16_t slot_number, uint16_t bsi, int16_t number_of_channels, uint32_t *excluded_channels);
|
int32_t tr51_get_bc_channel_index(int16_t *channel_table, uint8_t *output_table, uint16_t slot_number, uint16_t bsi, int16_t number_of_channels, uint32_t *excluded_channels);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compute the unicast schedule channel index using direct hash channel function.
|
* @brief Compute the unicast schedule channel index using direct hash channel function.
|
||||||
|
|
|
@ -88,6 +88,19 @@ uint8_t channel_list_get_channel(const uint32_t* list, int current_index)
|
||||||
return found_index;
|
return found_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void channel_list_set_channel(uint32_t* list, int channel, bool active)
|
||||||
|
{
|
||||||
|
if (channel >= CHANNEL_LIST_SIZE_IN_BITS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (active) {
|
||||||
|
list[channel/32] |= (1 << channel % 32);
|
||||||
|
} else {
|
||||||
|
list[channel/32] &= ~(1 << channel % 32);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// count the amount of channels enabled in a list
|
// count the amount of channels enabled in a list
|
||||||
int channel_list_count_channels(const uint32_t* list)
|
int channel_list_count_channels(const uint32_t* list)
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,6 +31,16 @@ extern "C" {
|
||||||
* @return channel number
|
* @return channel number
|
||||||
*/
|
*/
|
||||||
uint8_t channel_list_get_channel(const uint32_t* list, int current_index);
|
uint8_t channel_list_get_channel(const uint32_t* list, int current_index);
|
||||||
|
/**
|
||||||
|
* set matching bit on in in channel mask.
|
||||||
|
*
|
||||||
|
* @param list channel mask
|
||||||
|
* @param channel channel number
|
||||||
|
* @param active set the channel on if true, disable channel if false.
|
||||||
|
*
|
||||||
|
* @return channel number
|
||||||
|
*/
|
||||||
|
void channel_list_set_channel(uint32_t* list, int channel, bool active);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count the amount of channels enabled in a list.
|
* Count the amount of channels enabled in a list.
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
#define TRACE_GROUP "fhss"
|
#define TRACE_GROUP "fhss"
|
||||||
|
|
||||||
|
static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots);
|
||||||
static int fhss_reset(fhss_structure_t *fhss_structure);
|
static int fhss_reset(fhss_structure_t *fhss_structure);
|
||||||
static bool fhss_is_bc_sending_superframe(fhss_structure_t *fhss_structure);
|
static bool fhss_is_bc_sending_superframe(fhss_structure_t *fhss_structure);
|
||||||
static bool fhss_check_remaining_tx_time(fhss_structure_t *fhss_structure, uint16_t tx_length, uint8_t phy_header_length, uint8_t phy_tail_length);
|
static bool fhss_check_remaining_tx_time(fhss_structure_t *fhss_structure, uint16_t tx_length, uint8_t phy_header_length, uint8_t phy_tail_length);
|
||||||
|
@ -67,6 +68,7 @@ fhss_structure_t *fhss_enable(fhss_api_t *fhss_api, const fhss_configuration_t *
|
||||||
}
|
}
|
||||||
memset(fhss_struct->bs, 0, sizeof(fhss_bs_t));
|
memset(fhss_struct->bs, 0, sizeof(fhss_bs_t));
|
||||||
|
|
||||||
|
fhss_struct->fhss_event_timer = eventOS_callback_timer_register(fhss_event_timer_cb);
|
||||||
fhss_struct->bs->fhss_configuration = *fhss_configuration;
|
fhss_struct->bs->fhss_configuration = *fhss_configuration;
|
||||||
fhss_struct->bs->fhss_stats_ptr = fhss_statistics;
|
fhss_struct->bs->fhss_stats_ptr = fhss_statistics;
|
||||||
fhss_struct->number_of_channels = channel_count;
|
fhss_struct->number_of_channels = channel_count;
|
||||||
|
@ -99,6 +101,15 @@ bool fhss_is_synch_root(fhss_structure_t *fhss_structure)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots)
|
||||||
|
{
|
||||||
|
(void) slots;
|
||||||
|
fhss_structure_t *fhss_structure = fhss_get_object_with_timer_id(timer_id);
|
||||||
|
if (fhss_structure) {
|
||||||
|
fhss_structure->callbacks.tx_poll(fhss_structure->fhss_api);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool fhss_is_bc_sending_superframe(fhss_structure_t *fhss_structure)
|
static bool fhss_is_bc_sending_superframe(fhss_structure_t *fhss_structure)
|
||||||
{
|
{
|
||||||
if (fhss_structure->bs->current_superframe >= fhss_structure->bs->broadcast_start_superframe) {
|
if (fhss_structure->bs->current_superframe >= fhss_structure->bs->broadcast_start_superframe) {
|
||||||
|
@ -689,16 +700,16 @@ static void fhss_update_beacon_info_lifetimes(fhss_structure_t *fhss_structure,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fhss_synch_state_set_callback(const fhss_api_t *api, fhss_states fhss_state, uint16_t pan_id)
|
static int16_t fhss_synch_state_set_callback(const fhss_api_t *api, fhss_states fhss_state, uint16_t pan_id)
|
||||||
{
|
{
|
||||||
fhss_structure_t *fhss_structure = fhss_get_object_with_api(api);
|
fhss_structure_t *fhss_structure = fhss_get_object_with_api(api);
|
||||||
if (!fhss_structure) {
|
if (!fhss_structure) {
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
// State is already set
|
// State is already set
|
||||||
if (fhss_structure->fhss_state == fhss_state) {
|
if (fhss_structure->fhss_state == fhss_state) {
|
||||||
tr_debug("Synch same state %u", fhss_state);
|
tr_debug("Synch same state %u", fhss_state);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fhss_state == FHSS_UNSYNCHRONIZED) {
|
if (fhss_state == FHSS_UNSYNCHRONIZED) {
|
||||||
|
@ -712,7 +723,7 @@ static void fhss_synch_state_set_callback(const fhss_api_t *api, fhss_states fhs
|
||||||
// Do not synchronize to current pan
|
// Do not synchronize to current pan
|
||||||
if (fhss_structure->bs->synch_panid == pan_id) {
|
if (fhss_structure->bs->synch_panid == pan_id) {
|
||||||
tr_debug("Synch same panid %u", pan_id);
|
tr_debug("Synch same panid %u", pan_id);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
fhss_generate_scramble_table(fhss_structure);
|
fhss_generate_scramble_table(fhss_structure);
|
||||||
|
|
||||||
|
@ -737,11 +748,11 @@ static void fhss_synch_state_set_callback(const fhss_api_t *api, fhss_states fhs
|
||||||
fhss_start_timer(fhss_structure, fhss_structure->bs->synch_configuration.fhss_superframe_length, fhss_superframe_handler);
|
fhss_start_timer(fhss_structure, fhss_structure->bs->synch_configuration.fhss_superframe_length, fhss_superframe_handler);
|
||||||
} else {
|
} else {
|
||||||
tr_error("Synch info not found");
|
tr_error("Synch info not found");
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fhss_structure->fhss_state = fhss_state;
|
fhss_structure->fhss_state = fhss_state;
|
||||||
return;
|
return fhss_structure->rx_channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fhss_beacon_decode_raw(fhss_synchronization_beacon_payload_s* dest, const uint8_t* buffer)
|
static void fhss_beacon_decode_raw(fhss_synchronization_beacon_payload_s* dest, const uint8_t* buffer)
|
||||||
|
|
|
@ -34,8 +34,6 @@
|
||||||
|
|
||||||
static fhss_structure_t *fhss_struct = NULL;
|
static fhss_structure_t *fhss_struct = NULL;
|
||||||
|
|
||||||
static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots);
|
|
||||||
static fhss_structure_t *fhss_get_object_with_timer_id(const int8_t timer_id);
|
|
||||||
static void fhss_set_active_event(fhss_structure_t *fhss_structure, uint8_t event_type);
|
static void fhss_set_active_event(fhss_structure_t *fhss_structure, uint8_t event_type);
|
||||||
static bool fhss_read_active_event(fhss_structure_t *fhss_structure, uint8_t event_type);
|
static bool fhss_read_active_event(fhss_structure_t *fhss_structure, uint8_t event_type);
|
||||||
|
|
||||||
|
@ -52,7 +50,6 @@ fhss_structure_t *fhss_allocate_instance(fhss_api_t *fhss_api, const fhss_timer_
|
||||||
memset(fhss_struct, 0, sizeof(fhss_structure_t));
|
memset(fhss_struct, 0, sizeof(fhss_structure_t));
|
||||||
fhss_struct->fhss_api = fhss_api;
|
fhss_struct->fhss_api = fhss_api;
|
||||||
fhss_struct->platform_functions = *fhss_timer;
|
fhss_struct->platform_functions = *fhss_timer;
|
||||||
fhss_struct->fhss_event_timer = eventOS_callback_timer_register(fhss_event_timer_cb);
|
|
||||||
if (!fhss_struct->platform_functions.fhss_resolution_divider) {
|
if (!fhss_struct->platform_functions.fhss_resolution_divider) {
|
||||||
fhss_struct->platform_functions.fhss_resolution_divider = 1;
|
fhss_struct->platform_functions.fhss_resolution_divider = 1;
|
||||||
}
|
}
|
||||||
|
@ -69,16 +66,7 @@ int8_t fhss_free_instance(fhss_api_t *fhss_api)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots)
|
fhss_structure_t *fhss_get_object_with_timer_id(const int8_t timer_id)
|
||||||
{
|
|
||||||
(void) slots;
|
|
||||||
fhss_structure_t *fhss_structure = fhss_get_object_with_timer_id(timer_id);
|
|
||||||
if (fhss_structure) {
|
|
||||||
fhss_structure->callbacks.tx_poll(fhss_structure->fhss_api);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static fhss_structure_t *fhss_get_object_with_timer_id(const int8_t timer_id)
|
|
||||||
{
|
{
|
||||||
if (timer_id < 0 || !fhss_struct) {
|
if (timer_id < 0 || !fhss_struct) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -142,6 +130,13 @@ void fhss_start_timer(fhss_structure_t *fhss_structure, uint32_t time, void (*ca
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fhss_stop_timer(fhss_structure_t *fhss_structure, void (*callback)(const fhss_api_t *fhss_api, uint16_t))
|
||||||
|
{
|
||||||
|
if (callback){
|
||||||
|
fhss_structure->platform_functions.fhss_timer_stop(callback, fhss_structure->fhss_api);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int fhss_timeout_start(fhss_structure_t *fhss_structure, uint32_t time)
|
int fhss_timeout_start(fhss_structure_t *fhss_structure, uint32_t time)
|
||||||
{
|
{
|
||||||
if (!fhss_structure) {
|
if (!fhss_structure) {
|
||||||
|
|
|
@ -54,6 +54,7 @@ struct fhss_structure
|
||||||
uint8_t synch_parent[8];
|
uint8_t synch_parent[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fhss_structure_t *fhss_get_object_with_timer_id(const int8_t timer_id);
|
||||||
fhss_structure_t *fhss_allocate_instance(fhss_api_t *fhss_api, const fhss_timer_t *fhss_timer);
|
fhss_structure_t *fhss_allocate_instance(fhss_api_t *fhss_api, const fhss_timer_t *fhss_timer);
|
||||||
int8_t fhss_free_instance(fhss_api_t *fhss_api);
|
int8_t fhss_free_instance(fhss_api_t *fhss_api);
|
||||||
int8_t fhss_set_datarate(fhss_structure_t *fhss_structure, uint32_t datarate);
|
int8_t fhss_set_datarate(fhss_structure_t *fhss_structure, uint32_t datarate);
|
||||||
|
@ -61,6 +62,7 @@ fhss_structure_t *fhss_get_object_with_api(const fhss_api_t *fhss_api);
|
||||||
void fhss_clear_active_event(fhss_structure_t *fhss_structure, uint8_t event_type);
|
void fhss_clear_active_event(fhss_structure_t *fhss_structure, uint8_t event_type);
|
||||||
int8_t fhss_disable(fhss_structure_t *fhss_structure);
|
int8_t fhss_disable(fhss_structure_t *fhss_structure);
|
||||||
void fhss_start_timer(fhss_structure_t *fhss_structure, uint32_t time, void (*callback)(const fhss_api_t *fhss_api, uint16_t));
|
void fhss_start_timer(fhss_structure_t *fhss_structure, uint32_t time, void (*callback)(const fhss_api_t *fhss_api, uint16_t));
|
||||||
|
void fhss_stop_timer(fhss_structure_t *fhss_structure, void (*callback)(const fhss_api_t *fhss_api, uint16_t));
|
||||||
int fhss_timeout_start(fhss_structure_t *fhss_structure, uint32_t time);
|
int fhss_timeout_start(fhss_structure_t *fhss_structure, uint32_t time);
|
||||||
int fhss_timeout_stop(fhss_structure_t *fhss_structure);
|
int fhss_timeout_stop(fhss_structure_t *fhss_structure);
|
||||||
int fhss_update_synch_parent_address(fhss_structure_t *fhss_structure);
|
int fhss_update_synch_parent_address(fhss_structure_t *fhss_structure);
|
||||||
|
|
|
@ -62,13 +62,13 @@ fhss_api_t *ns_fhss_ws_create(const fhss_ws_configuration_t *fhss_configuration,
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
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, const bool force_synch)
|
||||||
{
|
{
|
||||||
fhss_structure_t *fhss_structure = fhss_get_object_with_api(fhss_api);
|
fhss_structure_t *fhss_structure = fhss_get_object_with_api(fhss_api);
|
||||||
if (!fhss_structure || !eui64 || !bc_timing_info) {
|
if (!fhss_structure || !eui64 || !bc_timing_info) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return fhss_ws_set_parent(fhss_structure, eui64, bc_timing_info);
|
return fhss_ws_set_parent(fhss_structure, eui64, bc_timing_info, force_synch);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ns_fhss_ws_remove_parent(const fhss_api_t *fhss_api, const uint8_t eui64[8])
|
int ns_fhss_ws_remove_parent(const fhss_api_t *fhss_api, const uint8_t eui64[8])
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#define WS_NUMBER_OF_CHANNEL_RETRIES 4
|
#define WS_NUMBER_OF_CHANNEL_RETRIES 4
|
||||||
//TX/RX slot length in milliseconds
|
//TX/RX slot length in milliseconds
|
||||||
#define WS_MAX_TXRX_SLOT_LEN_MS 100
|
#define WS_MAX_TXRX_SLOT_LEN_MS 100
|
||||||
|
// Default minimum broadcast synchronization interval in seconds
|
||||||
|
#define DEFAULT_MIN_SYNCH_INTERVAL 60
|
||||||
typedef struct fhss_ws fhss_ws_t;
|
typedef struct fhss_ws fhss_ws_t;
|
||||||
|
|
||||||
struct fhss_ws
|
struct fhss_ws
|
||||||
|
@ -30,6 +32,12 @@ struct fhss_ws
|
||||||
uint8_t bc_channel;
|
uint8_t bc_channel;
|
||||||
uint16_t uc_slot;
|
uint16_t uc_slot;
|
||||||
uint16_t bc_slot;
|
uint16_t bc_slot;
|
||||||
|
uint16_t min_synch_interval;
|
||||||
|
uint32_t txrx_slot_length_ms;
|
||||||
|
uint32_t synchronization_time;
|
||||||
|
int16_t *tr51_channel_table;
|
||||||
|
uint8_t *tr51_output_table;
|
||||||
|
bool unicast_timer_running;
|
||||||
bool is_on_bc_channel;
|
bool is_on_bc_channel;
|
||||||
struct fhss_ws_configuration fhss_configuration;
|
struct fhss_ws_configuration fhss_configuration;
|
||||||
const struct broadcast_timing_info *parent_bc_info;
|
const struct broadcast_timing_info *parent_bc_info;
|
||||||
|
@ -38,7 +46,7 @@ struct fhss_ws
|
||||||
|
|
||||||
fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer);
|
fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer);
|
||||||
int fhss_ws_set_callbacks(fhss_structure_t *fhss_structure);
|
int fhss_ws_set_callbacks(fhss_structure_t *fhss_structure);
|
||||||
int fhss_ws_set_parent(fhss_structure_t *fhss_structure, const uint8_t eui64[8], const broadcast_timing_info_t *bc_timing_info);
|
int fhss_ws_set_parent(fhss_structure_t *fhss_structure, const uint8_t eui64[8], const broadcast_timing_info_t *bc_timing_info, const bool force_synch);
|
||||||
int fhss_ws_remove_parent(fhss_structure_t *fhss_structure, const uint8_t eui64[8]);
|
int fhss_ws_remove_parent(fhss_structure_t *fhss_structure, const uint8_t eui64[8]);
|
||||||
int fhss_ws_configuration_set(fhss_structure_t *fhss_structure, const fhss_ws_configuration_t *fhss_configuration);
|
int fhss_ws_configuration_set(fhss_structure_t *fhss_structure, const fhss_ws_configuration_t *fhss_configuration);
|
||||||
int fhss_ws_set_hop_count(fhss_structure_t *fhss_structure, const uint8_t hop_count);
|
int fhss_ws_set_hop_count(fhss_structure_t *fhss_structure, const uint8_t hop_count);
|
||||||
|
|
|
@ -46,7 +46,7 @@ int fhss_ws_set_callbacks(fhss_structure_t *fhss_structure)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fhss_ws_set_parent(fhss_structure_t *fhss_structure, const uint8_t eui64[8], const broadcast_timing_info_t *bc_timing_info)
|
int fhss_ws_set_parent(fhss_structure_t *fhss_structure, const uint8_t eui64[8], const broadcast_timing_info_t *bc_timing_info, const bool force_synch)
|
||||||
{
|
{
|
||||||
(void) fhss_structure;
|
(void) fhss_structure;
|
||||||
(void) eui64;
|
(void) eui64;
|
||||||
|
|
|
@ -192,6 +192,9 @@ void mac_neighbor_table_neighbor_connected(mac_neighbor_table_t *table_class, ma
|
||||||
void mac_neighbor_table_trusted_neighbor(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry, bool trusted_device)
|
void mac_neighbor_table_trusted_neighbor(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry, bool trusted_device)
|
||||||
{
|
{
|
||||||
(void)table_class;
|
(void)table_class;
|
||||||
|
if (!neighbor_entry->trusted_device && trusted_device) {
|
||||||
|
neighbor_entry->lifetime = neighbor_entry->link_lifetime;
|
||||||
|
}
|
||||||
neighbor_entry->trusted_device = trusted_device;
|
neighbor_entry->trusted_device = trusted_device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,4 +274,13 @@ mac_neighbor_table_entry_t *mac_neighbor_entry_get_by_mac64(mac_neighbor_table_t
|
||||||
return mac_neighbor_table_entry_allocate(table_class, mac64);
|
return mac_neighbor_table_entry_allocate(table_class, mac64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mac_neighbor_table_entry_t* mac_neighbor_entry_get_priority(mac_neighbor_table_t *table_class)
|
||||||
|
{
|
||||||
|
|
||||||
|
ns_list_foreach(mac_neighbor_table_entry_t, entry, &table_class->neighbour_list) {
|
||||||
|
if (entry->link_role == PRIORITY_PARENT_NEIGHBOUR) {
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
|
@ -202,4 +202,6 @@ mac_neighbor_table_entry_t *mac_neighbor_entry_get_by_ll64(mac_neighbor_table_t
|
||||||
|
|
||||||
mac_neighbor_table_entry_t *mac_neighbor_entry_get_by_mac64(mac_neighbor_table_t *table_class, const uint8_t *mac64, bool allocateNew, bool *new_entry_allocated);
|
mac_neighbor_table_entry_t *mac_neighbor_entry_get_by_mac64(mac_neighbor_table_t *table_class, const uint8_t *mac64, bool allocateNew, bool *new_entry_allocated);
|
||||||
|
|
||||||
|
mac_neighbor_table_entry_t* mac_neighbor_entry_get_priority(mac_neighbor_table_t *table_class);
|
||||||
|
|
||||||
#endif /* MAC_NEIGHBOR_TABLE_H_ */
|
#endif /* MAC_NEIGHBOR_TABLE_H_ */
|
||||||
|
|
|
@ -72,10 +72,9 @@ fnet_bool_t fnet_netif_get_ip6_addr (fnet_netif_desc_t netif_desc, fnet_index_t
|
||||||
addr_info->type = FNET_NETIF_IP_ADDR_TYPE_AUTOCONFIGURABLE; /* How the address was acquired.*/
|
addr_info->type = FNET_NETIF_IP_ADDR_TYPE_AUTOCONFIGURABLE; /* How the address was acquired.*/
|
||||||
result = FNET_TRUE;
|
result = FNET_TRUE;
|
||||||
}
|
}
|
||||||
|
FNET_DEBUG("fnet_netif_get_ip6_addr(), if=%d: %s", (int8_t)netif->scope_id, trace_ipv6(addr_info->address.addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
FNET_DEBUG("fnet_netif_get_ip6_addr(), if=%d: %s", (int8_t)netif->scope_id, trace_ipv6(addr_info->address.addr));
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1589,6 +1589,7 @@ ipv6_route_t *ipv6_route_add_metric(const uint8_t *prefix, uint8_t prefix_len, i
|
||||||
route->metric = metric;
|
route->metric = metric;
|
||||||
changed_info = UPDATED;
|
changed_info = UPDATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed_info != UNCHANGED) {
|
if (changed_info != UNCHANGED) {
|
||||||
|
|
|
@ -394,14 +394,14 @@ void ipv6_stack_route_advert_update(uint8_t *address, uint8_t prefixLength, uint
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (addr_interface_gp_prefix_compare(cur, address) == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ns_list_foreach(ipv6_interface_route_on_link_t, cur_prefix, &route_on_link) {
|
||||||
if (addr_interface_gp_prefix_compare(cur, address) != 0) {
|
if ((cur_prefix->prefix_len == prefixLength) && bitsequal(cur_prefix->prefix, address, prefixLength)) {
|
||||||
ns_list_foreach(ipv6_interface_route_on_link_t, cur_prefix, &route_on_link) {
|
cur_prefix->routePrefer = routePrefer;
|
||||||
if ((cur_prefix->prefix_len == prefixLength) && bitsequal(cur_prefix->prefix, address, prefixLength)) {
|
return;
|
||||||
cur_prefix->routePrefer = routePrefer;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,16 @@ typedef struct {
|
||||||
} server_instance_t;
|
} server_instance_t;
|
||||||
typedef NS_LIST_HEAD(server_instance_t, link) server_instance_list_t;
|
typedef NS_LIST_HEAD(server_instance_t, link) server_instance_list_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t instance_id;
|
||||||
|
int8_t interface_id;
|
||||||
|
uint8_t server_address[16];
|
||||||
|
bool relay_activated;
|
||||||
|
ns_list_link_t link;
|
||||||
|
} relay_instance_t;
|
||||||
|
typedef NS_LIST_HEAD(relay_instance_t, link) relay_instance_list_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ns_address_t addr;
|
ns_address_t addr;
|
||||||
dhcp_service_receive_resp_cb *recv_resp_cb;
|
dhcp_service_receive_resp_cb *recv_resp_cb;
|
||||||
|
@ -71,6 +81,7 @@ typedef struct {
|
||||||
uint8_t retrans;
|
uint8_t retrans;
|
||||||
uint8_t *msg_ptr;
|
uint8_t *msg_ptr;
|
||||||
uint16_t msg_len;
|
uint16_t msg_len;
|
||||||
|
uint8_t *relay_start;
|
||||||
ns_list_link_t link;
|
ns_list_link_t link;
|
||||||
} msg_tr_t;
|
} msg_tr_t;
|
||||||
typedef NS_LIST_HEAD(msg_tr_t, link) tr_list_t;
|
typedef NS_LIST_HEAD(msg_tr_t, link) tr_list_t;
|
||||||
|
@ -78,9 +89,11 @@ typedef NS_LIST_HEAD(msg_tr_t, link) tr_list_t;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ns_address_t src_address;
|
ns_address_t src_address;
|
||||||
server_instance_list_t srv_list;
|
server_instance_list_t srv_list;
|
||||||
|
relay_instance_list_t relay_list;
|
||||||
tr_list_t tr_list;
|
tr_list_t tr_list;
|
||||||
int8_t dhcp_server_socket;
|
int8_t dhcp_server_socket;
|
||||||
int8_t dhcp_client_socket;
|
int8_t dhcp_client_socket;
|
||||||
|
int8_t dhcp_relay_socket;
|
||||||
int8_t dhcpv6_socket_service_tasklet;
|
int8_t dhcpv6_socket_service_tasklet;
|
||||||
} dhcp_service_class_t;
|
} dhcp_service_class_t;
|
||||||
|
|
||||||
|
@ -120,9 +133,11 @@ bool dhcp_service_allocate(void)
|
||||||
dhcp_service = ns_dyn_mem_alloc(sizeof(dhcp_service_class_t));
|
dhcp_service = ns_dyn_mem_alloc(sizeof(dhcp_service_class_t));
|
||||||
if (dhcp_service) {
|
if (dhcp_service) {
|
||||||
ns_list_init(&dhcp_service->srv_list);
|
ns_list_init(&dhcp_service->srv_list);
|
||||||
|
ns_list_init(&dhcp_service->relay_list);
|
||||||
ns_list_init(&dhcp_service->tr_list);
|
ns_list_init(&dhcp_service->tr_list);
|
||||||
dhcp_service->dhcp_client_socket = -1;
|
dhcp_service->dhcp_client_socket = -1;
|
||||||
dhcp_service->dhcp_server_socket = -1;
|
dhcp_service->dhcp_server_socket = -1;
|
||||||
|
dhcp_service->dhcp_relay_socket = -1;
|
||||||
dhcp_service->dhcpv6_socket_service_tasklet = eventOS_event_handler_create(DHCPv6_socket_service_tasklet, DHCPV6_SOCKET_SERVICE_TASKLET_INIT);
|
dhcp_service->dhcpv6_socket_service_tasklet = eventOS_event_handler_create(DHCPv6_socket_service_tasklet, DHCPV6_SOCKET_SERVICE_TASKLET_INIT);
|
||||||
if (dhcp_service->dhcpv6_socket_service_tasklet < 0) {
|
if (dhcp_service->dhcpv6_socket_service_tasklet < 0) {
|
||||||
ns_dyn_mem_free(dhcp_service);
|
ns_dyn_mem_free(dhcp_service);
|
||||||
|
@ -229,13 +244,50 @@ server_instance_t *dhcp_service_client_find(uint16_t instance_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint16_t dhcp_service_relay_interface_get(int8_t interface_id)
|
||||||
|
{
|
||||||
|
ns_list_foreach(server_instance_t, cur_ptr, &dhcp_service->srv_list) {
|
||||||
|
if (cur_ptr->interface_id == interface_id && cur_ptr->instance_type == DHCP_INTANCE_RELAY_AGENT) {
|
||||||
|
return cur_ptr->instance_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static relay_instance_t *dhcp_service_relay_find(uint16_t instance_id)
|
||||||
|
{
|
||||||
|
relay_instance_t *result = NULL;
|
||||||
|
ns_list_foreach(relay_instance_t, cur_ptr, &dhcp_service->relay_list) {
|
||||||
|
if (cur_ptr->instance_id == instance_id) {
|
||||||
|
result = cur_ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static relay_instance_t *dhcp_service_relay_interface(int8_t interface_id)
|
||||||
|
{
|
||||||
|
relay_instance_t *result = NULL;
|
||||||
|
ns_list_foreach(relay_instance_t, cur_ptr, &dhcp_service->relay_list) {
|
||||||
|
if (cur_ptr->interface_id == interface_id) {
|
||||||
|
result = cur_ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void recv_dhcp_server_msg(void *cb_res)
|
void recv_dhcp_server_msg(void *cb_res)
|
||||||
{
|
{
|
||||||
socket_callback_t *sckt_data;
|
socket_callback_t *sckt_data;
|
||||||
server_instance_t *srv_ptr = NULL;
|
server_instance_t *srv_ptr = NULL;
|
||||||
msg_tr_t *msg_tr_ptr;
|
msg_tr_t *msg_tr_ptr;
|
||||||
uint8_t *msg_ptr;
|
uint8_t *msg_ptr, *allocated_ptr;
|
||||||
uint16_t msg_len;
|
uint16_t msg_len;
|
||||||
|
dhcpv6_relay_msg_t relay_msg;
|
||||||
|
|
||||||
sckt_data = cb_res;
|
sckt_data = cb_res;
|
||||||
|
|
||||||
|
@ -245,12 +297,33 @@ void recv_dhcp_server_msg(void *cb_res)
|
||||||
tr_debug("dhcp Server recv request");
|
tr_debug("dhcp Server recv request");
|
||||||
msg_tr_ptr = dhcp_tr_create();
|
msg_tr_ptr = dhcp_tr_create();
|
||||||
msg_ptr = ns_dyn_mem_temporary_alloc(sckt_data->d_len);
|
msg_ptr = ns_dyn_mem_temporary_alloc(sckt_data->d_len);
|
||||||
|
allocated_ptr = msg_ptr;
|
||||||
if (msg_ptr == NULL || msg_tr_ptr == NULL) {
|
if (msg_ptr == NULL || msg_tr_ptr == NULL) {
|
||||||
// read actual message
|
// read actual message
|
||||||
tr_error("Out of resources");
|
tr_error("Out of resources");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
msg_len = socket_read(sckt_data->socket_id, &msg_tr_ptr->addr, msg_ptr, sckt_data->d_len);
|
msg_len = socket_read(sckt_data->socket_id, &msg_tr_ptr->addr, msg_ptr, sckt_data->d_len);
|
||||||
|
|
||||||
|
uint8_t msg_type = *msg_ptr;
|
||||||
|
if (msg_type == DHCPV6_RELAY_FORWARD) {
|
||||||
|
if ( !libdhcpv6_relay_msg_read(msg_ptr, msg_len, &relay_msg) ) {
|
||||||
|
tr_error("Relay forward not correct");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
//Update Source and data
|
||||||
|
msg_tr_ptr->relay_start = msg_ptr;
|
||||||
|
memcpy(msg_tr_ptr->addr.address,relay_msg.peer_address , 16);
|
||||||
|
msg_ptr = relay_msg.relay_options.msg_ptr;
|
||||||
|
msg_len = relay_msg.relay_options.len;
|
||||||
|
msg_type = *msg_ptr;
|
||||||
|
|
||||||
|
|
||||||
|
} else if (msg_type == DHCPV6_RELAY_REPLY) {
|
||||||
|
tr_error("Relay reply drop at server");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
//TODO use real function from lib also call validity check
|
//TODO use real function from lib also call validity check
|
||||||
msg_tr_ptr->message_tr_id = common_read_24_bit(&msg_ptr[1]);
|
msg_tr_ptr->message_tr_id = common_read_24_bit(&msg_ptr[1]);
|
||||||
|
|
||||||
|
@ -265,7 +338,7 @@ void recv_dhcp_server_msg(void *cb_res)
|
||||||
msg_tr_ptr->instance_id = cur_ptr->instance_id;
|
msg_tr_ptr->instance_id = cur_ptr->instance_id;
|
||||||
msg_tr_ptr->interface_id = sckt_data->interface_id;
|
msg_tr_ptr->interface_id = sckt_data->interface_id;
|
||||||
if ((RET_MSG_ACCEPTED ==
|
if ((RET_MSG_ACCEPTED ==
|
||||||
cur_ptr->recv_req_cb(cur_ptr->instance_id, msg_tr_ptr->msg_tr_id, *msg_ptr, msg_ptr + 4, msg_len - 4))) {
|
cur_ptr->recv_req_cb(cur_ptr->instance_id, msg_tr_ptr->msg_tr_id, msg_type, msg_ptr + 4, msg_len - 4))) {
|
||||||
// should not modify pointers but library requires.
|
// should not modify pointers but library requires.
|
||||||
msg_tr_ptr = NULL;
|
msg_tr_ptr = NULL;
|
||||||
srv_ptr = cur_ptr;
|
srv_ptr = cur_ptr;
|
||||||
|
@ -276,7 +349,7 @@ void recv_dhcp_server_msg(void *cb_res)
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
dhcp_tr_delete(msg_tr_ptr);
|
dhcp_tr_delete(msg_tr_ptr);
|
||||||
ns_dyn_mem_free(msg_ptr);
|
ns_dyn_mem_free(allocated_ptr);
|
||||||
if (srv_ptr == NULL) {
|
if (srv_ptr == NULL) {
|
||||||
//no owner found
|
//no owner found
|
||||||
tr_warn("No handler for this message found");
|
tr_warn("No handler for this message found");
|
||||||
|
@ -285,6 +358,118 @@ cleanup:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void recv_dhcp_relay_msg(void *cb_res)
|
||||||
|
{
|
||||||
|
socket_callback_t *sckt_data;
|
||||||
|
uint16_t msg_len;
|
||||||
|
|
||||||
|
sckt_data = cb_res;
|
||||||
|
|
||||||
|
if (sckt_data->event_type != SOCKET_DATA || sckt_data->d_len < 4) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol_interface_info_entry_t *interface_ptr = protocol_stack_interface_info_get_by_id(sckt_data->interface_id);
|
||||||
|
|
||||||
|
relay_instance_t *relay_srv =dhcp_service_relay_interface(sckt_data->interface_id);
|
||||||
|
|
||||||
|
if (!interface_ptr || !relay_srv || !relay_srv->relay_activated) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ns_address_t src_address;
|
||||||
|
|
||||||
|
uint8_t relay_frame[DHCPV6_RELAY_LENGTH + 4];
|
||||||
|
ns_iovec_t msg_iov[2];
|
||||||
|
msg_iov[0].iov_base = relay_frame;
|
||||||
|
msg_iov[0].iov_len = 34;
|
||||||
|
msg_iov[1].iov_base = ns_dyn_mem_temporary_alloc(sckt_data->d_len);
|
||||||
|
msg_iov[1].iov_len = sckt_data->d_len;
|
||||||
|
if (msg_iov[1].iov_base == NULL ) {
|
||||||
|
// read actual message
|
||||||
|
tr_error("Out of resources");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ns_msghdr_t msghdr;
|
||||||
|
//Set messages name buffer
|
||||||
|
msghdr.msg_name = &src_address;
|
||||||
|
msghdr.msg_namelen = sizeof(src_address);
|
||||||
|
msghdr.msg_iov = &msg_iov[1];
|
||||||
|
msghdr.msg_iovlen = 1;
|
||||||
|
msghdr.msg_control = NULL;
|
||||||
|
msghdr.msg_controllen = 0;
|
||||||
|
|
||||||
|
msg_len = socket_recvmsg(sckt_data->socket_id, &msghdr, NS_MSG_LEGACY0);
|
||||||
|
|
||||||
|
|
||||||
|
tr_debug("dhcp Relay recv msg");
|
||||||
|
|
||||||
|
//Parse type
|
||||||
|
uint8_t *ptr = msg_iov[1].iov_base;
|
||||||
|
uint8_t msg_type = *ptr;
|
||||||
|
|
||||||
|
|
||||||
|
if (msg_type == DHCPV6_RELAY_FORWARD) {
|
||||||
|
tr_error("Drop not supported DHCPv6 forward at Agent");
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
} else if (msg_type == DHCPV6_RELAY_REPLY) {
|
||||||
|
//Parse and validate Relay
|
||||||
|
dhcpv6_relay_msg_t relay_msg;
|
||||||
|
if (!libdhcpv6_relay_msg_read(ptr, msg_len, &relay_msg) ) {
|
||||||
|
tr_error("Not valid relay");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (0 != libdhcpv6_message_malformed_check(relay_msg.relay_options.msg_ptr, relay_msg.relay_options.len)) {
|
||||||
|
tr_error("Malformed packet");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
//Copy DST address
|
||||||
|
memcpy(src_address.address, relay_msg.peer_address, 16);
|
||||||
|
src_address.type = ADDRESS_IPV6;
|
||||||
|
src_address.identifier = DHCPV6_CLIENT_PORT;
|
||||||
|
msghdr.msg_iov = &msg_iov[0];
|
||||||
|
msghdr.msg_iovlen = 1;
|
||||||
|
msg_iov[0].iov_base = relay_msg.relay_options.msg_ptr;
|
||||||
|
msg_iov[0].iov_len = relay_msg.relay_options.len;
|
||||||
|
tr_debug("Forward Original relay msg to client");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (0 != libdhcpv6_message_malformed_check(ptr, msg_len)) {
|
||||||
|
tr_error("Malformed packet");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
uint8_t gp_address[16];
|
||||||
|
//Get blobal address from interface
|
||||||
|
if (arm_net_address_get(sckt_data->interface_id, ADDR_IPV6_GP, gp_address) != 0) {
|
||||||
|
// No global prefix available
|
||||||
|
tr_error("No GP address");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Build
|
||||||
|
libdhcpv6_dhcp_relay_msg_write(relay_frame, DHCPV6_RELAY_FORWARD, 0, src_address.address, gp_address);
|
||||||
|
libdhcpv6_dhcp_option_header_write(relay_frame + 34, msg_len);
|
||||||
|
|
||||||
|
//Copy DST address
|
||||||
|
memcpy(src_address.address, relay_srv->server_address, 16);
|
||||||
|
src_address.type = ADDRESS_IPV6;
|
||||||
|
src_address.identifier = DHCPV6_SERVER_PORT;
|
||||||
|
//ADD relay frame vector front of original data
|
||||||
|
msghdr.msg_iov = &msg_iov[0];
|
||||||
|
msghdr.msg_iovlen = 2;
|
||||||
|
msg_iov[0].iov_base = relay_frame;
|
||||||
|
msg_iov[0].iov_len = 38;
|
||||||
|
msg_iov[1].iov_len = msg_len;
|
||||||
|
tr_debug("Forward Client msg to server");
|
||||||
|
}
|
||||||
|
socket_sendmsg(sckt_data->socket_id, &msghdr, NS_MSG_LEGACY0);
|
||||||
|
cleanup:
|
||||||
|
ns_dyn_mem_free(msg_iov[1].iov_base);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void recv_dhcp_client_msg(void *cb_res)
|
void recv_dhcp_client_msg(void *cb_res)
|
||||||
{
|
{
|
||||||
ns_address_t address;
|
ns_address_t address;
|
||||||
|
@ -351,8 +536,19 @@ uint16_t dhcp_service_init(int8_t interface_id, dhcp_instance_type_e instance_ty
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (instance_type == DHCP_INSTANCE_SERVER && dhcp_service->dhcp_server_socket < 0) {
|
if (instance_type == DHCP_INSTANCE_SERVER && dhcp_service->dhcp_server_socket < 0) {
|
||||||
|
if (dhcp_service->dhcp_relay_socket >= 0) {
|
||||||
|
tr_error("dhcp Server socket can't open because Agent open already");
|
||||||
|
}
|
||||||
dhcp_service->dhcp_server_socket = socket_open(SOCKET_UDP, DHCPV6_SERVER_PORT, recv_dhcp_server_msg);
|
dhcp_service->dhcp_server_socket = socket_open(SOCKET_UDP, DHCPV6_SERVER_PORT, recv_dhcp_server_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (instance_type == DHCP_INTANCE_RELAY_AGENT && dhcp_service->dhcp_relay_socket < 0) {
|
||||||
|
if (dhcp_service->dhcp_server_socket >= 0) {
|
||||||
|
tr_error("dhcp Relay agent can't open because server open already");
|
||||||
|
}
|
||||||
|
dhcp_service->dhcp_relay_socket = socket_open(SOCKET_UDP, DHCPV6_SERVER_PORT, recv_dhcp_relay_msg);
|
||||||
|
}
|
||||||
|
|
||||||
if (instance_type == DHCP_INSTANCE_CLIENT && dhcp_service->dhcp_client_socket < 0) {
|
if (instance_type == DHCP_INSTANCE_CLIENT && dhcp_service->dhcp_client_socket < 0) {
|
||||||
dhcp_service->dhcp_client_socket = socket_open(SOCKET_UDP, DHCPV6_CLIENT_PORT, recv_dhcp_client_msg);
|
dhcp_service->dhcp_client_socket = socket_open(SOCKET_UDP, DHCPV6_CLIENT_PORT, recv_dhcp_client_msg);
|
||||||
}
|
}
|
||||||
|
@ -364,6 +560,18 @@ uint16_t dhcp_service_init(int8_t interface_id, dhcp_instance_type_e instance_ty
|
||||||
tr_error("No sockets available for DHCP client");
|
tr_error("No sockets available for DHCP client");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (instance_type == DHCP_INTANCE_RELAY_AGENT) {
|
||||||
|
if (dhcp_service->dhcp_relay_socket < 0) {
|
||||||
|
tr_error("No sockets available for DHCP server");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t temp_id = dhcp_service_relay_interface_get(interface_id);
|
||||||
|
if (temp_id) {
|
||||||
|
return temp_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (; id < MAX_SERVERS; id++) {
|
for (; id < MAX_SERVERS; id++) {
|
||||||
if (dhcp_service_client_find(id) == NULL) {
|
if (dhcp_service_client_find(id) == NULL) {
|
||||||
break;
|
break;
|
||||||
|
@ -375,6 +583,22 @@ uint16_t dhcp_service_init(int8_t interface_id, dhcp_instance_type_e instance_ty
|
||||||
ns_dyn_mem_free(srv_ptr);
|
ns_dyn_mem_free(srv_ptr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (instance_type == DHCP_INTANCE_RELAY_AGENT) {
|
||||||
|
//Allocate Realay Agent
|
||||||
|
relay_instance_t *relay_srv = ns_dyn_mem_alloc(sizeof(relay_instance_t));
|
||||||
|
if (!relay_srv) {
|
||||||
|
tr_error("Out of realy instances");
|
||||||
|
ns_dyn_mem_free(srv_ptr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ns_list_add_to_start(&dhcp_service->relay_list, relay_srv);
|
||||||
|
relay_srv->instance_id = id;
|
||||||
|
relay_srv->interface_id = interface_id;
|
||||||
|
relay_srv->relay_activated = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ns_list_add_to_start(&dhcp_service->srv_list, srv_ptr);
|
ns_list_add_to_start(&dhcp_service->srv_list, srv_ptr);
|
||||||
srv_ptr->instance_id = id;
|
srv_ptr->instance_id = id;
|
||||||
srv_ptr->instance_type = instance_type;
|
srv_ptr->instance_type = instance_type;
|
||||||
|
@ -383,6 +607,15 @@ uint16_t dhcp_service_init(int8_t interface_id, dhcp_instance_type_e instance_ty
|
||||||
return srv_ptr->instance_id;
|
return srv_ptr->instance_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dhcp_service_relay_instance_enable(uint16_t instance, uint8_t *server_address)
|
||||||
|
{
|
||||||
|
relay_instance_t * realay_srv = dhcp_service_relay_find(instance);
|
||||||
|
if (realay_srv) {
|
||||||
|
realay_srv->relay_activated = true;
|
||||||
|
memcpy(realay_srv->server_address, server_address, 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void dhcp_service_delete(uint16_t instance)
|
void dhcp_service_delete(uint16_t instance)
|
||||||
{
|
{
|
||||||
server_instance_t *srv_ptr;
|
server_instance_t *srv_ptr;
|
||||||
|
@ -393,7 +626,16 @@ void dhcp_service_delete(uint16_t instance)
|
||||||
//TODO delete all transactions
|
//TODO delete all transactions
|
||||||
if (srv_ptr != NULL) {
|
if (srv_ptr != NULL) {
|
||||||
ns_list_remove(&dhcp_service->srv_list, srv_ptr);
|
ns_list_remove(&dhcp_service->srv_list, srv_ptr);
|
||||||
|
if (srv_ptr->instance_type == DHCP_INTANCE_RELAY_AGENT) {
|
||||||
|
//Free relay service
|
||||||
|
relay_instance_t *relay = dhcp_service_relay_find(instance);
|
||||||
|
if (relay) {
|
||||||
|
ns_list_remove(&dhcp_service->relay_list, relay);
|
||||||
|
ns_dyn_mem_free(relay);
|
||||||
|
}
|
||||||
|
}
|
||||||
ns_dyn_mem_free(srv_ptr);
|
ns_dyn_mem_free(srv_ptr);
|
||||||
|
|
||||||
}
|
}
|
||||||
ns_list_foreach_safe(msg_tr_t, cur_ptr, &dhcp_service->tr_list) {
|
ns_list_foreach_safe(msg_tr_t, cur_ptr, &dhcp_service->tr_list) {
|
||||||
if (cur_ptr->instance_id == instance) {
|
if (cur_ptr->instance_id == instance) {
|
||||||
|
@ -401,17 +643,19 @@ void dhcp_service_delete(uint16_t instance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t server_instances = 0, client_instances = 0;
|
int8_t server_instances = 0, client_instances = 0, relay_instances = 0;
|
||||||
|
|
||||||
ns_list_foreach(server_instance_t, srv, &dhcp_service->srv_list) {
|
ns_list_foreach(server_instance_t, srv, &dhcp_service->srv_list) {
|
||||||
if (srv->instance_type == DHCP_INSTANCE_SERVER) {
|
if (srv->instance_type == DHCP_INSTANCE_SERVER) {
|
||||||
++server_instances;
|
++server_instances;
|
||||||
} else if (srv->instance_type == DHCP_INSTANCE_CLIENT) {
|
} else if (srv->instance_type == DHCP_INSTANCE_CLIENT) {
|
||||||
++client_instances;
|
++client_instances;
|
||||||
|
} else if (srv->instance_type == DHCP_INTANCE_RELAY_AGENT) {
|
||||||
|
++relay_instances;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server_instances == 0 && dhcp_service->dhcp_server_socket > -1) {
|
if ((server_instances == 0 && relay_instances == 0) && dhcp_service->dhcp_server_socket > -1) {
|
||||||
socket_close(dhcp_service->dhcp_server_socket);
|
socket_close(dhcp_service->dhcp_server_socket);
|
||||||
dhcp_service->dhcp_server_socket = -1;
|
dhcp_service->dhcp_server_socket = -1;
|
||||||
}
|
}
|
||||||
|
@ -458,7 +702,7 @@ uint32_t dhcp_service_send_req(uint16_t instance_id, uint8_t options, void *ptr,
|
||||||
msg_tr_ptr = dhcp_tr_create();
|
msg_tr_ptr = dhcp_tr_create();
|
||||||
|
|
||||||
if (msg_tr_ptr == NULL || srv_ptr == NULL || msg_ptr == NULL || receive_resp_cb == NULL || msg_len < 5) {
|
if (msg_tr_ptr == NULL || srv_ptr == NULL || msg_ptr == NULL || receive_resp_cb == NULL || msg_len < 5) {
|
||||||
tr_error("request sending failed");
|
tr_error("Request sending failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,7 +774,38 @@ void dhcp_service_send_message(msg_tr_t *msg_tr_ptr)
|
||||||
}
|
}
|
||||||
socket_setsockopt(msg_tr_ptr->socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_MULTICAST_HOPS, &multicast_hop_limit, sizeof multicast_hop_limit);
|
socket_setsockopt(msg_tr_ptr->socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_MULTICAST_HOPS, &multicast_hop_limit, sizeof multicast_hop_limit);
|
||||||
socket_setsockopt(msg_tr_ptr->socket, SOCKET_IPPROTO_IPV6, SOCKET_INTERFACE_SELECT, &msg_tr_ptr->interface_id, sizeof(int8_t));
|
socket_setsockopt(msg_tr_ptr->socket, SOCKET_IPPROTO_IPV6, SOCKET_INTERFACE_SELECT, &msg_tr_ptr->interface_id, sizeof(int8_t));
|
||||||
retval = socket_sendto(msg_tr_ptr->socket, &msg_tr_ptr->addr, msg_tr_ptr->msg_ptr, msg_tr_ptr->msg_len);
|
|
||||||
|
if (msg_tr_ptr->relay_start) {
|
||||||
|
//Build Relay Reply only server do this
|
||||||
|
ns_iovec_t data_vector[2];
|
||||||
|
ns_msghdr_t msghdr;
|
||||||
|
memcpy(msg_tr_ptr->addr.address, msg_tr_ptr->relay_start + 2, 16);
|
||||||
|
msg_tr_ptr->addr.identifier = DHCPV6_SERVER_PORT;
|
||||||
|
//SET IOV vectors
|
||||||
|
//Relay Reply
|
||||||
|
data_vector[0].iov_base = (void *) msg_tr_ptr->relay_start;
|
||||||
|
data_vector[0].iov_len = DHCPV6_RELAY_LENGTH + 4;
|
||||||
|
//DHCPV normal message vector
|
||||||
|
data_vector[1].iov_base = (void *) msg_tr_ptr->msg_ptr;
|
||||||
|
data_vector[1].iov_len = msg_tr_ptr->msg_len;
|
||||||
|
|
||||||
|
//Set message name
|
||||||
|
msghdr.msg_name = (void *) &msg_tr_ptr->addr;
|
||||||
|
msghdr.msg_namelen = sizeof(ns_address_t);
|
||||||
|
msghdr.msg_iov = &data_vector[0];
|
||||||
|
msghdr.msg_iovlen = 2;
|
||||||
|
//No ancillary data
|
||||||
|
msghdr.msg_control = NULL;
|
||||||
|
msghdr.msg_controllen = 0;
|
||||||
|
|
||||||
|
uint8_t *ptr = msg_tr_ptr->relay_start;
|
||||||
|
*ptr = DHCPV6_RELAY_REPLY;
|
||||||
|
libdhcpv6_dhcp_option_header_write(ptr +34, msg_tr_ptr->msg_len);
|
||||||
|
retval = socket_sendmsg(msg_tr_ptr->socket, &msghdr, NS_MSG_LEGACY0);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
retval = socket_sendto(msg_tr_ptr->socket, &msg_tr_ptr->addr, msg_tr_ptr->msg_ptr, msg_tr_ptr->msg_len);
|
||||||
|
}
|
||||||
if (retval != 0) {
|
if (retval != 0) {
|
||||||
tr_warn("dhcp service socket_sendto fails: %i", retval);
|
tr_warn("dhcp service socket_sendto fails: %i", retval);
|
||||||
}
|
}
|
||||||
|
@ -588,6 +863,12 @@ void dhcp_service_delete(uint16_t instance)
|
||||||
(void)instance;
|
(void)instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dhcp_service_relay_instance_enable(uint16_t instance, uint8_t *server_address)
|
||||||
|
{
|
||||||
|
(void)instance;
|
||||||
|
(void)server_address;
|
||||||
|
}
|
||||||
|
|
||||||
int dhcp_service_send_resp(uint32_t msg_tr_id, uint8_t options, uint8_t *msg_ptr, uint16_t msg_len)
|
int dhcp_service_send_resp(uint32_t msg_tr_id, uint8_t options, uint8_t *msg_ptr, uint16_t msg_len)
|
||||||
{
|
{
|
||||||
(void)msg_tr_id;
|
(void)msg_tr_id;
|
||||||
|
@ -626,4 +907,5 @@ bool dhcp_service_timer_tick(uint16_t ticks)
|
||||||
(void)ticks;
|
(void)ticks;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -795,4 +795,43 @@ uint16_t libdhcpv6_solication_message_length(uint16_t clientLinkType, bool addre
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t *libdhcpv6_dhcp_relay_msg_write(uint8_t *ptr, uint8_t type, uint8_t hop_limit, uint8_t *peer_addres, uint8_t *link_address)
|
||||||
|
{
|
||||||
|
*ptr++ = type;
|
||||||
|
*ptr++ = hop_limit;
|
||||||
|
memcpy(ptr, link_address, 16);
|
||||||
|
ptr += 16;
|
||||||
|
memcpy(ptr, peer_addres, 16);
|
||||||
|
ptr += 16;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *libdhcpv6_dhcp_option_header_write(uint8_t *ptr, uint16_t length)
|
||||||
|
{
|
||||||
|
ptr = common_write_16_bit(DHCPV6_OPTION_RELAY, ptr);
|
||||||
|
ptr = common_write_16_bit(length, ptr);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool libdhcpv6_relay_msg_read(uint8_t *ptr, uint16_t length, dhcpv6_relay_msg_t *relay_msg)
|
||||||
|
{
|
||||||
|
if (length < DHCPV6_RELAY_LENGTH + 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Relay message base first
|
||||||
|
relay_msg->type = *ptr++;
|
||||||
|
relay_msg->hop_limit = *ptr++;
|
||||||
|
relay_msg->link_address = ptr;
|
||||||
|
relay_msg->peer_address = ptr + 16;
|
||||||
|
ptr += 32;
|
||||||
|
//Discover
|
||||||
|
if (libdhcpv6_message_option_discover(ptr, length - 34, DHCPV6_OPTION_RELAY, &relay_msg->relay_options) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -112,6 +112,14 @@ typedef struct dhcpv6_client_server_entry_s {
|
||||||
|
|
||||||
typedef NS_LIST_HEAD(dhcpv6_client_server_data_t, link) dhcpv6_client_server_entry_s;
|
typedef NS_LIST_HEAD(dhcpv6_client_server_data_t, link) dhcpv6_client_server_entry_s;
|
||||||
|
|
||||||
|
typedef struct dhcpv6_relay_msg {
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t hop_limit;
|
||||||
|
uint8_t *link_address;
|
||||||
|
uint8_t *peer_address;
|
||||||
|
dhcp_options_msg_t relay_options;
|
||||||
|
} dhcpv6_relay_msg_t;
|
||||||
|
|
||||||
/** UDP Port Number definition */
|
/** UDP Port Number definition */
|
||||||
#define DHCPV6_SERVER_PORT 547
|
#define DHCPV6_SERVER_PORT 547
|
||||||
#define DHCPV6_CLIENT_PORT 546
|
#define DHCPV6_CLIENT_PORT 546
|
||||||
|
@ -123,6 +131,8 @@ typedef NS_LIST_HEAD(dhcpv6_client_server_data_t, link) dhcpv6_client_server_ent
|
||||||
#define DHCPV6_RENEW_TYPE 5
|
#define DHCPV6_RENEW_TYPE 5
|
||||||
#define DHCPV6_REPLY_TYPE 7
|
#define DHCPV6_REPLY_TYPE 7
|
||||||
#define DHCPV6_RELEASE_TYPE 8
|
#define DHCPV6_RELEASE_TYPE 8
|
||||||
|
#define DHCPV6_RELAY_FORWARD 12
|
||||||
|
#define DHCPV6_RELAY_REPLY 13
|
||||||
#define DHCPV6_LEASEQUERY_TYPE 14
|
#define DHCPV6_LEASEQUERY_TYPE 14
|
||||||
#define DHCPV6_LEASEQUERY_REPLY_TYPE 15
|
#define DHCPV6_LEASEQUERY_REPLY_TYPE 15
|
||||||
|
|
||||||
|
@ -209,6 +219,11 @@ typedef NS_LIST_HEAD(dhcpv6_client_server_data_t, link) dhcpv6_client_server_ent
|
||||||
|
|
||||||
#define DHCPV6_OPTION_CLT_TIME 0x002e
|
#define DHCPV6_OPTION_CLT_TIME 0x002e
|
||||||
|
|
||||||
|
#define DHCPV6_RELAY_LENGTH 34
|
||||||
|
#define DHCPV6_OPTION_RELAY 0x0009
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** DHCPv6 client Nontemporal address and server data allocate, free and search */
|
/** DHCPv6 client Nontemporal address and server data allocate, free and search */
|
||||||
dhcpv6_client_server_data_t *libdhcvp6_nontemporalAddress_server_data_allocate(int8_t interfaceId, uint8_t instanceId, uint8_t *duiId, uint16_t duiLinkType, uint8_t *nonTemporalPrefix, uint8_t *serverIPv6Address);
|
dhcpv6_client_server_data_t *libdhcvp6_nontemporalAddress_server_data_allocate(int8_t interfaceId, uint8_t instanceId, uint8_t *duiId, uint16_t duiLinkType, uint8_t *nonTemporalPrefix, uint8_t *serverIPv6Address);
|
||||||
void libdhcvp6_nontemporalAddress_server_data_free(dhcpv6_client_server_data_t *removedEntry);
|
void libdhcvp6_nontemporalAddress_server_data_free(dhcpv6_client_server_data_t *removedEntry);
|
||||||
|
@ -259,7 +274,8 @@ uint16_t libdhcpv6_address_reply_message_len(uint16_t clientLinkType, uint16_t s
|
||||||
|
|
||||||
uint8_t *libdhcpv6_generic_nontemporal_address_message_write(uint8_t *ptr, dhcpv6_solication_base_packet_s *packet, dhcpv6_ia_non_temporal_address_s *nonTemporalAddress, dhcp_link_options_params_t *serverLink);
|
uint8_t *libdhcpv6_generic_nontemporal_address_message_write(uint8_t *ptr, dhcpv6_solication_base_packet_s *packet, dhcpv6_ia_non_temporal_address_s *nonTemporalAddress, dhcp_link_options_params_t *serverLink);
|
||||||
uint8_t *libdhcpv6_reply_message_write(uint8_t *ptr, dhcpv6_reply_packet_s *replyPacket, dhcpv6_ia_non_temporal_address_s *nonTemporalAddress, dhcpv6_vendor_data_packet_s *vendorData);
|
uint8_t *libdhcpv6_reply_message_write(uint8_t *ptr, dhcpv6_reply_packet_s *replyPacket, dhcpv6_ia_non_temporal_address_s *nonTemporalAddress, dhcpv6_vendor_data_packet_s *vendorData);
|
||||||
|
uint8_t *libdhcpv6_dhcp_relay_msg_write(uint8_t *ptr, uint8_t type, uint8_t hop_limit, uint8_t *peer_addres, uint8_t *link_address);
|
||||||
|
uint8_t *libdhcpv6_dhcp_option_header_write(uint8_t *ptr, uint16_t length);
|
||||||
|
|
||||||
int libdhcpv6_get_IA_address(uint8_t *ptr, uint16_t data_length, dhcp_ia_non_temporal_params_t *params);
|
int libdhcpv6_get_IA_address(uint8_t *ptr, uint16_t data_length, dhcp_ia_non_temporal_params_t *params);
|
||||||
int libdhcpv6_get_duid_by_selected_type_id_opt(uint8_t *ptr, uint16_t data_length, uint16_t type , dhcp_link_options_params_t *params);
|
int libdhcpv6_get_duid_by_selected_type_id_opt(uint8_t *ptr, uint16_t data_length, uint16_t type , dhcp_link_options_params_t *params);
|
||||||
|
@ -347,5 +363,6 @@ int libdhcpv6_solication_message_options_validate(uint8_t *ptr, uint16_t data_le
|
||||||
int libdhcpv6_advertisment_message_option_validate(dhcp_link_options_params_t *clientId, dhcp_link_options_params_t *serverId, dhcp_ia_non_temporal_params_t *dhcp_ia_non_temporal_params, uint8_t *ptr, uint16_t data_length);
|
int libdhcpv6_advertisment_message_option_validate(dhcp_link_options_params_t *clientId, dhcp_link_options_params_t *serverId, dhcp_ia_non_temporal_params_t *dhcp_ia_non_temporal_params, uint8_t *ptr, uint16_t data_length);
|
||||||
bool libdhcpv6_rapid_commit_option_at_packet(uint8_t *ptr, uint16_t length);
|
bool libdhcpv6_rapid_commit_option_at_packet(uint8_t *ptr, uint16_t length);
|
||||||
bool libdhcpv6_time_elapsed_option_at_packet(uint8_t *ptr, uint16_t length);
|
bool libdhcpv6_time_elapsed_option_at_packet(uint8_t *ptr, uint16_t length);
|
||||||
|
bool libdhcpv6_relay_msg_read(uint8_t *ptr, uint16_t length, dhcpv6_relay_msg_t *relay_msg);
|
||||||
|
|
||||||
#endif /* LIBDHCPV6_H_ */
|
#endif /* LIBDHCPV6_H_ */
|
||||||
|
|
|
@ -43,11 +43,12 @@ static dhcpv6_gua_server_entry_s *libdhcpv6_server_entry_allocate(void)
|
||||||
dhcpv6_gua_server_entry_s *entry = ns_dyn_mem_alloc(sizeof(dhcpv6_gua_server_entry_s));
|
dhcpv6_gua_server_entry_s *entry = ns_dyn_mem_alloc(sizeof(dhcpv6_gua_server_entry_s));
|
||||||
if (entry) {
|
if (entry) {
|
||||||
entry->clientIdSequence = 0;
|
entry->clientIdSequence = 0;
|
||||||
entry->enableAddressMapping = false;
|
|
||||||
entry->enableAddressAutonous = true;
|
entry->enableAddressAutonous = true;
|
||||||
entry->clientIdDefaultSuffics = 0x0000000;
|
entry->clientIdDefaultSuffics = 0x0000000;
|
||||||
entry->maxSuppertedClients = 200;
|
entry->maxSuppertedClients = 200;
|
||||||
entry->validLifetime = 7200;
|
entry->validLifetime = 7200;
|
||||||
|
entry->removeCb = NULL;
|
||||||
|
entry->addCb = NULL;
|
||||||
ns_list_init(&entry->allocatedAddressList);
|
ns_list_init(&entry->allocatedAddressList);
|
||||||
}
|
}
|
||||||
return entry;
|
return entry;
|
||||||
|
@ -62,7 +63,7 @@ static void libdhcpv6_address_generate(dhcpv6_gua_server_entry_s *serverInfo, dh
|
||||||
if (entry->linkType == DHCPV6_DUID_HARDWARE_EUI64_TYPE) {
|
if (entry->linkType == DHCPV6_DUID_HARDWARE_EUI64_TYPE) {
|
||||||
memcpy(ptr, entry->linkId, 8);
|
memcpy(ptr, entry->linkId, 8);
|
||||||
*ptr ^= 2;
|
*ptr ^= 2;
|
||||||
} else if (entry->linkType == DHCPV6_DUID_HARDWARE_EUI64_TYPE) {
|
} else if (entry->linkType == DHCPV6_DUID_HARDWARE_EUI48_TYPE) {
|
||||||
*ptr++ = entry->linkId[0] ^ 2;
|
*ptr++ = entry->linkId[0] ^ 2;
|
||||||
*ptr++ = entry->linkId[1];
|
*ptr++ = entry->linkId[1];
|
||||||
*ptr++ = entry->linkId[2];
|
*ptr++ = entry->linkId[2];
|
||||||
|
@ -96,7 +97,9 @@ void libdhcpv6_gua_servers_time_update(uint32_t timeUpdateInSeconds)
|
||||||
//Stop use this address for leasequery and delete Route or address map
|
//Stop use this address for leasequery and delete Route or address map
|
||||||
|
|
||||||
address->preferredLifetime = 0;
|
address->preferredLifetime = 0;
|
||||||
cur->timeoutCb(cur->interfaceId, address->nonTemporalAddress);
|
if (cur->removeCb) {
|
||||||
|
cur->removeCb(cur->interfaceId, address->nonTemporalAddress, cur->guaPrefix);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
address->preferredLifetime -= timeUpdateInSeconds;
|
address->preferredLifetime -= timeUpdateInSeconds;
|
||||||
}
|
}
|
||||||
|
@ -137,17 +140,16 @@ dhcpv6_gua_server_entry_s *libdhcpv6_server_data_get_by_prefix_and_socketinstanc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
dhcpv6_gua_server_entry_s *libdhcpv6_gua_server_allocate(uint8_t *prefix, int8_t interfaceId, uint8_t *serverDUID, uint16_t serverDUIDType, dhcp_address_prefer_timeout_cb *prefered_timeout_cb)
|
dhcpv6_gua_server_entry_s *libdhcpv6_gua_server_allocate(uint8_t *prefix, int8_t interfaceId, uint8_t *serverDUID, uint16_t serverDUIDType)
|
||||||
{
|
{
|
||||||
dhcpv6_gua_server_entry_s *entry = NULL;
|
dhcpv6_gua_server_entry_s *entry = libdhcpv6_server_data_get_by_prefix_and_interfaceid(interfaceId, prefix);
|
||||||
if (libdhcpv6_server_data_get_by_prefix_and_interfaceid(interfaceId, prefix) == NULL) {
|
if (entry == NULL) {
|
||||||
entry = libdhcpv6_server_entry_allocate();
|
entry = libdhcpv6_server_entry_allocate();
|
||||||
if (entry) {
|
if (entry) {
|
||||||
memcpy(entry->guaPrefix, prefix, 8);
|
memcpy(entry->guaPrefix, prefix, 8);
|
||||||
memcpy(entry->serverDUID, serverDUID, 8);
|
memcpy(entry->serverDUID, serverDUID, 8);
|
||||||
entry->serverLinkType = serverDUIDType;
|
entry->serverLinkType = serverDUIDType;
|
||||||
entry->interfaceId = interfaceId;
|
entry->interfaceId = interfaceId;
|
||||||
entry->timeoutCb = prefered_timeout_cb;
|
|
||||||
ns_list_add_to_end(&dhcpv6_gua_server_list, entry);
|
ns_list_add_to_end(&dhcpv6_gua_server_list, entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#ifdef HAVE_DHCPV6_SERVER
|
#ifdef HAVE_DHCPV6_SERVER
|
||||||
#include "ns_list.h"
|
#include "ns_list.h"
|
||||||
|
|
||||||
typedef void (dhcp_address_prefer_timeout_cb)(int8_t interfaceId, uint8_t *targetAddress);
|
typedef void (dhcp_address_prefer_remove_cb)(int8_t interfaceId, uint8_t *targetAddress, void *prefix_info);
|
||||||
|
|
||||||
typedef struct dhcpv6_alloacted_address_entry_s {
|
typedef struct dhcpv6_alloacted_address_entry_s {
|
||||||
uint8_t nonTemporalAddress[16];
|
uint8_t nonTemporalAddress[16];
|
||||||
|
@ -50,10 +50,16 @@ typedef struct thread_dhcpv6_server_data_s {
|
||||||
ns_list_link_t link; /*!< List link entry */
|
ns_list_link_t link; /*!< List link entry */
|
||||||
} dhcpv6_server_data_entry_t;
|
} dhcpv6_server_data_entry_t;
|
||||||
|
|
||||||
|
typedef struct dhcp_address_cache_update{
|
||||||
|
uint8_t *allocatedAddress;
|
||||||
|
bool allocatedNewAddress;
|
||||||
|
uint32_t validLifeTime;
|
||||||
|
} dhcp_address_cache_update_t;
|
||||||
|
|
||||||
|
typedef bool (dhcp_address_add_notify_cb)(int8_t interfaceId, dhcp_address_cache_update_t *address_info, void *route_src);
|
||||||
|
|
||||||
typedef struct dhcpv6_gua_server_entry_s {
|
typedef struct dhcpv6_gua_server_entry_s {
|
||||||
int8_t interfaceId;
|
int8_t interfaceId;
|
||||||
bool enableAddressMapping;
|
|
||||||
uint8_t meshLocalPrefix[8];
|
|
||||||
bool enableAddressAutonous;
|
bool enableAddressAutonous;
|
||||||
uint16_t socketInstance_id;
|
uint16_t socketInstance_id;
|
||||||
uint8_t guaPrefix[8];
|
uint8_t guaPrefix[8];
|
||||||
|
@ -63,13 +69,14 @@ typedef struct dhcpv6_gua_server_entry_s {
|
||||||
uint32_t clientIdDefaultSuffics;
|
uint32_t clientIdDefaultSuffics;
|
||||||
uint32_t clientIdSequence; /*!< Define */
|
uint32_t clientIdSequence; /*!< Define */
|
||||||
uint32_t validLifetime;
|
uint32_t validLifetime;
|
||||||
dhcp_address_prefer_timeout_cb *timeoutCb;
|
dhcp_address_prefer_remove_cb *removeCb;
|
||||||
|
dhcp_address_add_notify_cb *addCb;
|
||||||
dhcpv6_alloacted_address_list_t allocatedAddressList;
|
dhcpv6_alloacted_address_list_t allocatedAddressList;
|
||||||
ns_list_link_t link; /*!< List link entry */
|
ns_list_link_t link; /*!< List link entry */
|
||||||
} dhcpv6_gua_server_entry_s;
|
} dhcpv6_gua_server_entry_s;
|
||||||
|
|
||||||
bool libdhcpv6_gua_server_list_empty(void);
|
bool libdhcpv6_gua_server_list_empty(void);
|
||||||
dhcpv6_gua_server_entry_s *libdhcpv6_gua_server_allocate(uint8_t *prefix, int8_t interfaceId, uint8_t *serverDUID, uint16_t serverDUIDType, dhcp_address_prefer_timeout_cb *prefered_timeout_cb);
|
dhcpv6_gua_server_entry_s *libdhcpv6_gua_server_allocate(uint8_t *prefix, int8_t interfaceId, uint8_t *serverDUID, uint16_t serverDUIDType);
|
||||||
void libdhcpv6_gua_server_free_by_prefix_and_interfaceid(uint8_t *prefix, int8_t interfaceId);
|
void libdhcpv6_gua_server_free_by_prefix_and_interfaceid(uint8_t *prefix, int8_t interfaceId);
|
||||||
void libdhcpv6_gua_servers_time_update(uint32_t timeUpdateInSeconds);
|
void libdhcpv6_gua_servers_time_update(uint32_t timeUpdateInSeconds);
|
||||||
void libdhcpv6_address_rm_from_allocated_list(dhcpv6_gua_server_entry_s *serverInfo, const uint8_t *address);
|
void libdhcpv6_address_rm_from_allocated_list(dhcpv6_gua_server_entry_s *serverInfo, const uint8_t *address);
|
||||||
|
@ -81,7 +88,7 @@ dhcpv6_alloacted_address_entry_t *libdhcpv6_address_allocated_list_scan(dhcpv6_g
|
||||||
#define libdhcpv6_gua_server_list_empty() true
|
#define libdhcpv6_gua_server_list_empty() true
|
||||||
#define libdhcpv6_server_data_get_by_prefix_and_interfaceid(interfaceId, prefixPtr) NULL
|
#define libdhcpv6_server_data_get_by_prefix_and_interfaceid(interfaceId, prefixPtr) NULL
|
||||||
#define libdhcpv6_server_data_get_by_prefix_and_socketinstance(socketInstance, prefixPtr) NULL
|
#define libdhcpv6_server_data_get_by_prefix_and_socketinstance(socketInstance, prefixPtr) NULL
|
||||||
#define libdhcpv6_gua_server_allocate(prefix, interfaceId, serverDUID, serverDUIDType, prefered_timeout_cb) NULL
|
#define libdhcpv6_gua_server_allocate(prefix, interfaceId, serverDUID, serverDUIDType) NULL
|
||||||
#define libdhcpv6_gua_server_free_by_prefix_and_interfaceid(prefix, interfaceId) ((void)0)
|
#define libdhcpv6_gua_server_free_by_prefix_and_interfaceid(prefix, interfaceId) ((void)0)
|
||||||
#define libdhcpv6_gua_servers_time_update(timeUpdateInSeconds) ((void)0)
|
#define libdhcpv6_gua_servers_time_update(timeUpdateInSeconds) ((void)0)
|
||||||
#define libdhcpv6_gua_server_free_by_interfaceid(interfaceId) ((void)0)
|
#define libdhcpv6_gua_server_free_by_interfaceid(interfaceId) ((void)0)
|
||||||
|
|
|
@ -57,6 +57,12 @@
|
||||||
#endif
|
#endif
|
||||||
#endif /* HAVE_THREAD */
|
#endif /* HAVE_THREAD */
|
||||||
|
|
||||||
|
#if defined(HAVE_WS)
|
||||||
|
#ifndef HAVE_DHCPV6
|
||||||
|
#define HAVE_DHCPV6
|
||||||
|
#endif
|
||||||
|
#endif /* HAVE_WS */
|
||||||
|
|
||||||
|
|
||||||
#endif // ifndef _NANOSTACK_SOURCE_CONFIG_H
|
#endif // ifndef _NANOSTACK_SOURCE_CONFIG_H
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue