mirror of https://github.com/ARMmbed/mbed-os.git
Squashed 'features/nanostack/sal-stack-nanostack/' changes from 715ae9a693..35b95da122
35b95da122 Remove unnecessary files from release 0717432619 Merge remote-tracking branch 'origin/release_internal' into release_external f68126b85a Adaptation layer MCPS confirmation handle update e483a0748d Added OFDM configurations and FEC in RF config structure (#2513) b88abfa1c2 BUG fix: Fixed broken Brodcast MAC overflow handling 9cad47826a Random early detection congestion API update 00aed73abc Modified the Wi-SUN stack Latency estimates a bit slower 6b83d821ea Remove periodic PAN version increase from Wi-SUN border router ef670e21f3 Integrated ReD congestion packet drop to Wi-SUN bootstrap interface. b956d9e983 Revert "Improved transmission in high traffic (#2511)" (#2512) 01749c2116 Improved transmission in high traffic (#2511) 3158e966e0 Adaption layer queue trace update 5a32f4a7bb Update changelog, random_early_detection_congestion_check nameupdate and minor comment fix. b818f12c6d Extented network status for support dropped tx congestion packet. 11c0763f4d Added new service Random early detection f2c358dc2b Optimized medium NWK MPL parameters to 40 second multicast interval (#2508) c013bc7790 Added traces to EAPOL TX failure c29ee94a20 Changed TLS return value to int32_t 501a2c8578 Added trace for mbed TLS errors 9d7cd22aa6 Updated change log 1290225b95 Corrected radius message memory allocation 7b1c59695b Removed trace print's efb83934f6 Adaptation layer MCPS confirmation handle update ac1025e7e9 Bug Fix: Accept only next possible BSI for detect BR reboot and drop unkown's. 58f0e56fe4 Updated change log 102e525b9a Nanostack now indicates connection down on RPL local repair start 395791d535 FHSS WS: Do not allow broadcast TX on unicast channel (#2501) 72f8ecb8d2 Updated changelog.md 237620827c Activated higher priority by traffic class CS6 for NS/NA and RPL, EAPOL/ DHCP Relay messages. afbe9061b5 Adaptation layer update 13fb2bfdbb Update CHANGELOG.md af81c48993 DIO init TX filter update 13a872c6b9 Fix typos in github template (#2498) 1af20e1aee Initial version of CHANGELOG (#2497) d9874ede96 Feature update: Improved MAC TX queue purge 69264429f9 Wi-SUN Aro registration temporary address registation bug fix. d3170ed50a Removed generic event and wrong trace info. 0db3486a7a Removed trace from place which is normal and not needed a080f18d83 Added debug tarce for dropped unsecured and MPL packets. 51cd5646ed Wi-SUN NS probe update: 579f75684e Adaptation layer: Do not push CCA failed packet back to MAC (Wi-SUN) (#2487) git-subtree-dir: features/nanostack/sal-stack-nanostack git-subtree-split: 35b95da1226ebb070fdaeb3ec47fb82f48ff8fadpull/14040/head
parent
04c21e779b
commit
dad2952087
|
@ -73,6 +73,7 @@ typedef struct nwk_stats_t {
|
||||||
/* MAC */
|
/* MAC */
|
||||||
uint16_t adapt_layer_tx_queue_size; /**< Adaptation layer direct TX queue size. */
|
uint16_t adapt_layer_tx_queue_size; /**< Adaptation layer direct TX queue size. */
|
||||||
uint16_t adapt_layer_tx_queue_peak; /**< Adaptation layer direct TX queue size peak. */
|
uint16_t adapt_layer_tx_queue_peak; /**< Adaptation layer direct TX queue size peak. */
|
||||||
|
uint32_t adapt_layer_tx_congestion_drop; /**< Adaptation layer direct TX randon early detection drop packet. */
|
||||||
} nwk_stats_t;
|
} nwk_stats_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -175,6 +175,25 @@ typedef enum {
|
||||||
MODULATION_INDEX_UNDEFINED ///< Modulation index undefined
|
MODULATION_INDEX_UNDEFINED ///< Modulation index undefined
|
||||||
} phy_modulation_index_e;
|
} phy_modulation_index_e;
|
||||||
|
|
||||||
|
/** OFDM option */
|
||||||
|
typedef enum {
|
||||||
|
OFDM_OPTION_1 = 1, ///< OFDM option 1
|
||||||
|
OFDM_OPTION_2 = 2, ///< OFDM option 2
|
||||||
|
OFDM_OPTION_3 = 3, ///< OFDM option 3
|
||||||
|
OFDM_OPTION_4 = 4 ///< OFDM option 4
|
||||||
|
} phy_ofdm_option_e;
|
||||||
|
|
||||||
|
/** Modulation and coding scheme (OFDM) */
|
||||||
|
typedef enum {
|
||||||
|
OFDM_MCS_0 = 0, ///< OFDM MCS 0
|
||||||
|
OFDM_MCS_1 = 1, ///< OFDM MCS 1
|
||||||
|
OFDM_MCS_2 = 2, ///< OFDM MCS 2
|
||||||
|
OFDM_MCS_3 = 3, ///< OFDM MCS 3
|
||||||
|
OFDM_MCS_4 = 4, ///< OFDM MCS 4
|
||||||
|
OFDM_MCS_5 = 5, ///< OFDM MCS 5
|
||||||
|
OFDM_MCS_6 = 6 ///< OFDM MCS 6
|
||||||
|
} phy_ofdm_mcs_e;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief enum phy_802_15_4_mode_t IEEE 802.15.4 mode
|
* @brief enum phy_802_15_4_mode_t IEEE 802.15.4 mode
|
||||||
*
|
*
|
||||||
|
@ -192,6 +211,9 @@ typedef struct phy_rf_channel_configuration_s {
|
||||||
uint16_t number_of_channels; ///< Number of channels
|
uint16_t number_of_channels; ///< Number of channels
|
||||||
phy_modulation_e modulation; ///< Modulation scheme
|
phy_modulation_e modulation; ///< Modulation scheme
|
||||||
phy_modulation_index_e modulation_index; ///< Modulation index
|
phy_modulation_index_e modulation_index; ///< Modulation index
|
||||||
|
bool fec; ///< Forward error correction, true - enabled, false - disabled
|
||||||
|
phy_ofdm_option_e ofdm_option; ///< OFDM option
|
||||||
|
phy_ofdm_mcs_e ofdm_mcs; ///< OFDM modulation and coding scheme
|
||||||
} phy_rf_channel_configuration_s;
|
} phy_rf_channel_configuration_s;
|
||||||
|
|
||||||
/** Channel page configuration */
|
/** Channel page configuration */
|
||||||
|
|
|
@ -96,7 +96,8 @@ int ws_bbr_start(int8_t interface_id, int8_t backbone_interface_id);
|
||||||
#define BBR_GUA_ROUTE 0x0002 /**< More specific route is added for GUA prefix */
|
#define BBR_GUA_ROUTE 0x0002 /**< More specific route is added for GUA prefix */
|
||||||
#define BBR_BB_WAIT 0x0004 /**< Wait backbone availability before starting Wi-SUN network */
|
#define BBR_BB_WAIT 0x0004 /**< Wait backbone availability before starting Wi-SUN network */
|
||||||
#define BBR_DEFAULT_ROUTE 0x0008 /**< Add default route parameter to DIO */
|
#define BBR_DEFAULT_ROUTE 0x0008 /**< Add default route parameter to DIO */
|
||||||
#define BBR_REQUIRE_DAO_REFRESH 0x0010 /**< Do not increment PAN version number when active forces DAO update from nodes*/
|
#define BBR_REQUIRE_DAO_REFRESH 0x0000 /**< Deprecated DAO Refresh is now the default functionality*/
|
||||||
|
#define BBR_PERIODIC_VERSION_INC 0x0010 /**< Increment PAN version number Periodically*/
|
||||||
#define BBR_GUA_SLAAC 0x0020 /**< in Global prefix use SLAAC address generation to reduce traffic during bootstrap */
|
#define BBR_GUA_SLAAC 0x0020 /**< in Global prefix use SLAAC address generation to reduce traffic during bootstrap */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -799,15 +799,15 @@ bool protocol_6lowpan_latency_estimate_get(int8_t interface_id, uint32_t *latenc
|
||||||
|
|
||||||
if (cur_interface->eth_mac_api) {
|
if (cur_interface->eth_mac_api) {
|
||||||
// either PPP or Ethernet interface.
|
// either PPP or Ethernet interface.
|
||||||
latency_estimate = 100;
|
latency_estimate = 1000;
|
||||||
} else if (thread_info(cur_interface)) {
|
} else if (thread_info(cur_interface)) {
|
||||||
// thread network
|
// thread network
|
||||||
latency_estimate = 2000;
|
latency_estimate = 5000;
|
||||||
} else if (ws_info(cur_interface)) {
|
} else if (ws_info(cur_interface)) {
|
||||||
latency_estimate = ws_common_latency_estimate_get(cur_interface);
|
latency_estimate = ws_common_latency_estimate_get(cur_interface);
|
||||||
} else {
|
} else {
|
||||||
// 6LoWPAN ND
|
// 6LoWPAN ND
|
||||||
latency_estimate = 8000;
|
latency_estimate = 20000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (latency_estimate != 0) {
|
if (latency_estimate != 0) {
|
||||||
|
|
|
@ -930,7 +930,7 @@ bool nd_ns_aro_handler(protocol_interface_info_entry_t *cur_interface, const uin
|
||||||
/* TODO - check hard upper limit on registrations? */
|
/* TODO - check hard upper limit on registrations? */
|
||||||
if (ws_info(cur_interface)) {
|
if (ws_info(cur_interface)) {
|
||||||
|
|
||||||
aro_out->status = ws_common_allow_child_registration(cur_interface, aro_out->eui64);
|
aro_out->status = ws_common_allow_child_registration(cur_interface, aro_out->eui64, aro_out->lifetime);
|
||||||
if (aro_out->status != ARO_SUCCESS) {
|
if (aro_out->status != ARO_SUCCESS) {
|
||||||
aro_out->present = true;
|
aro_out->present = true;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -42,13 +42,14 @@
|
||||||
#include "MLE/mle.h"
|
#include "MLE/mle.h"
|
||||||
#include "Service_Libs/mle_service/mle_service_api.h"
|
#include "Service_Libs/mle_service/mle_service_api.h"
|
||||||
#include "Common_Protocols/icmpv6.h"
|
#include "Common_Protocols/icmpv6.h"
|
||||||
|
#include "Common_Protocols/ip.h"
|
||||||
#ifdef HAVE_RPL
|
#ifdef HAVE_RPL
|
||||||
#include "RPL/rpl_data.h"
|
#include "RPL/rpl_data.h"
|
||||||
#endif
|
#endif
|
||||||
#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"
|
||||||
|
#include "Service_Libs/random_early_detection/random_early_detection_api.h"
|
||||||
#define TRACE_GROUP "6lAd"
|
#define TRACE_GROUP "6lAd"
|
||||||
|
|
||||||
typedef void (adaptation_etx_update_cb)(protocol_interface_info_entry_t *cur, buffer_t *buf, const mcps_data_conf_t *confirm);
|
typedef void (adaptation_etx_update_cb)(protocol_interface_info_entry_t *cur, buffer_t *buf, const mcps_data_conf_t *confirm);
|
||||||
|
@ -60,6 +61,8 @@ typedef void (adaptation_etx_update_cb)(protocol_interface_info_entry_t *cur, bu
|
||||||
#define tr_debug_extra(...)
|
#define tr_debug_extra(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ADAPTION_DIRECT_TX_QUEUE_SIZE_THRESHOLD_TRACE 20
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t tag; /*!< Fragmentation datagram TAG ID */
|
uint16_t tag; /*!< Fragmentation datagram TAG ID */
|
||||||
uint16_t size; /*!< Datagram Total Size (uncompressed) */
|
uint16_t size; /*!< Datagram Total Size (uncompressed) */
|
||||||
|
@ -93,6 +96,8 @@ typedef struct {
|
||||||
fragmenter_tx_list_t activeUnicastList; //Unicast packets waiting data confirmation from MAC
|
fragmenter_tx_list_t activeUnicastList; //Unicast packets waiting data confirmation from MAC
|
||||||
buffer_list_t directTxQueue; //Waiting free tx process
|
buffer_list_t directTxQueue; //Waiting free tx process
|
||||||
uint16_t directTxQueue_size;
|
uint16_t directTxQueue_size;
|
||||||
|
uint16_t directTxQueue_level;
|
||||||
|
uint16_t activeTxList_size;
|
||||||
uint16_t indirect_big_packet_threshold;
|
uint16_t indirect_big_packet_threshold;
|
||||||
uint16_t max_indirect_big_packets_total;
|
uint16_t max_indirect_big_packets_total;
|
||||||
uint16_t max_indirect_small_packets_per_child;
|
uint16_t max_indirect_small_packets_per_child;
|
||||||
|
@ -103,6 +108,8 @@ typedef struct {
|
||||||
ns_list_link_t link; /*!< List link entry */
|
ns_list_link_t link; /*!< List link entry */
|
||||||
} fragmenter_interface_t;
|
} fragmenter_interface_t;
|
||||||
|
|
||||||
|
#define LOWPAN_ACTIVE_UNICAST_ONGOING_MAX 10
|
||||||
|
|
||||||
static NS_LIST_DEFINE(fragmenter_interface_list, fragmenter_interface_t, link);
|
static NS_LIST_DEFINE(fragmenter_interface_list, fragmenter_interface_t, link);
|
||||||
|
|
||||||
/* Adaptation interface local functions */
|
/* Adaptation interface local functions */
|
||||||
|
@ -203,11 +210,22 @@ static struct protocol_interface_info_entry *lowpan_adaptation_network_interface
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void lowpan_adaptation_tx_queue_level_update(fragmenter_interface_t *interface_ptr)
|
||||||
|
{
|
||||||
|
if (interface_ptr->directTxQueue_size == interface_ptr->directTxQueue_level + ADAPTION_DIRECT_TX_QUEUE_SIZE_THRESHOLD_TRACE ||
|
||||||
|
interface_ptr->directTxQueue_size == interface_ptr->directTxQueue_level - ADAPTION_DIRECT_TX_QUEUE_SIZE_THRESHOLD_TRACE) {
|
||||||
|
interface_ptr->directTxQueue_level = interface_ptr->directTxQueue_size;
|
||||||
|
tr_info("Adaptation layer TX queue size %u Active MAC tx request %u", interface_ptr->directTxQueue_level, interface_ptr->activeTxList_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void lowpan_adaptation_tx_queue_write(fragmenter_interface_t *interface_ptr, buffer_t *buf)
|
static void lowpan_adaptation_tx_queue_write(fragmenter_interface_t *interface_ptr, buffer_t *buf)
|
||||||
{
|
{
|
||||||
buffer_t *lower_priority_buf = NULL;
|
buffer_t *lower_priority_buf = NULL;
|
||||||
|
|
||||||
ns_list_foreach(buffer_t, cur, &interface_ptr->directTxQueue) {
|
ns_list_foreach(buffer_t, cur, &interface_ptr->directTxQueue) {
|
||||||
|
|
||||||
if (cur->priority < buf->priority) {
|
if (cur->priority < buf->priority) {
|
||||||
lower_priority_buf = cur;
|
lower_priority_buf = cur;
|
||||||
break;
|
break;
|
||||||
|
@ -220,6 +238,7 @@ static void lowpan_adaptation_tx_queue_write(fragmenter_interface_t *interface_p
|
||||||
ns_list_add_to_end(&interface_ptr->directTxQueue, buf);
|
ns_list_add_to_end(&interface_ptr->directTxQueue, buf);
|
||||||
}
|
}
|
||||||
interface_ptr->directTxQueue_size++;
|
interface_ptr->directTxQueue_size++;
|
||||||
|
lowpan_adaptation_tx_queue_level_update(interface_ptr);
|
||||||
protocol_stats_update(STATS_AL_TX_QUEUE_SIZE, interface_ptr->directTxQueue_size);
|
protocol_stats_update(STATS_AL_TX_QUEUE_SIZE, interface_ptr->directTxQueue_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,6 +252,7 @@ static buffer_t *lowpan_adaptation_tx_queue_read(fragmenter_interface_t *interfa
|
||||||
if (lowpan_buffer_tx_allowed(interface_ptr, buf)) {
|
if (lowpan_buffer_tx_allowed(interface_ptr, buf)) {
|
||||||
ns_list_remove(&interface_ptr->directTxQueue, buf);
|
ns_list_remove(&interface_ptr->directTxQueue, buf);
|
||||||
interface_ptr->directTxQueue_size--;
|
interface_ptr->directTxQueue_size--;
|
||||||
|
lowpan_adaptation_tx_queue_level_update(interface_ptr);
|
||||||
protocol_stats_update(STATS_AL_TX_QUEUE_SIZE, interface_ptr->directTxQueue_size);
|
protocol_stats_update(STATS_AL_TX_QUEUE_SIZE, interface_ptr->directTxQueue_size);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
@ -365,6 +385,9 @@ int8_t lowpan_adaptation_interface_init(int8_t interface_id, uint16_t mac_mtu_si
|
||||||
ns_list_init(&interface_ptr->indirect_tx_queue);
|
ns_list_init(&interface_ptr->indirect_tx_queue);
|
||||||
ns_list_init(&interface_ptr->directTxQueue);
|
ns_list_init(&interface_ptr->directTxQueue);
|
||||||
ns_list_init(&interface_ptr->activeUnicastList);
|
ns_list_init(&interface_ptr->activeUnicastList);
|
||||||
|
interface_ptr->activeTxList_size = 0;
|
||||||
|
interface_ptr->directTxQueue_size = 0;
|
||||||
|
interface_ptr->directTxQueue_level = 0;
|
||||||
|
|
||||||
ns_list_add_to_end(&fragmenter_interface_list, interface_ptr);
|
ns_list_add_to_end(&fragmenter_interface_list, interface_ptr);
|
||||||
|
|
||||||
|
@ -390,13 +413,15 @@ int8_t lowpan_adaptation_interface_free(int8_t interface_id)
|
||||||
ns_list_remove(&fragmenter_interface_list, interface_ptr);
|
ns_list_remove(&fragmenter_interface_list, interface_ptr);
|
||||||
//free active tx process
|
//free active tx process
|
||||||
lowpan_list_free(&interface_ptr->activeUnicastList, false);
|
lowpan_list_free(&interface_ptr->activeUnicastList, false);
|
||||||
|
interface_ptr->activeTxList_size = 0;
|
||||||
lowpan_active_buffer_state_reset(&interface_ptr->active_broadcast_tx_buf);
|
lowpan_active_buffer_state_reset(&interface_ptr->active_broadcast_tx_buf);
|
||||||
|
|
||||||
//Free Indirect entry
|
//Free Indirect entry
|
||||||
lowpan_list_free(&interface_ptr->indirect_tx_queue, true);
|
lowpan_list_free(&interface_ptr->indirect_tx_queue, true);
|
||||||
|
|
||||||
buffer_free_list(&interface_ptr->directTxQueue);
|
buffer_free_list(&interface_ptr->directTxQueue);
|
||||||
|
interface_ptr->directTxQueue_size = 0;
|
||||||
|
interface_ptr->directTxQueue_level = 0;
|
||||||
//Free Dynamic allocated entries
|
//Free Dynamic allocated entries
|
||||||
ns_dyn_mem_free(interface_ptr->fragment_indirect_tx_buffer);
|
ns_dyn_mem_free(interface_ptr->fragment_indirect_tx_buffer);
|
||||||
ns_dyn_mem_free(interface_ptr);
|
ns_dyn_mem_free(interface_ptr);
|
||||||
|
@ -415,6 +440,7 @@ int8_t lowpan_adaptation_interface_reset(int8_t interface_id)
|
||||||
|
|
||||||
//free active tx process
|
//free active tx process
|
||||||
lowpan_list_free(&interface_ptr->activeUnicastList, false);
|
lowpan_list_free(&interface_ptr->activeUnicastList, false);
|
||||||
|
interface_ptr->activeTxList_size = 0;
|
||||||
lowpan_active_buffer_state_reset(&interface_ptr->active_broadcast_tx_buf);
|
lowpan_active_buffer_state_reset(&interface_ptr->active_broadcast_tx_buf);
|
||||||
//Clean fragmented message flag
|
//Clean fragmented message flag
|
||||||
interface_ptr->fragmenter_active = false;
|
interface_ptr->fragmenter_active = false;
|
||||||
|
@ -423,6 +449,8 @@ int8_t lowpan_adaptation_interface_reset(int8_t interface_id)
|
||||||
lowpan_list_free(&interface_ptr->indirect_tx_queue, true);
|
lowpan_list_free(&interface_ptr->indirect_tx_queue, true);
|
||||||
|
|
||||||
buffer_free_list(&interface_ptr->directTxQueue);
|
buffer_free_list(&interface_ptr->directTxQueue);
|
||||||
|
interface_ptr->directTxQueue_size = 0;
|
||||||
|
interface_ptr->directTxQueue_level = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -597,6 +625,7 @@ static fragmenter_tx_entry_t *lowpan_adaptation_tx_process_init(fragmenter_inter
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
ns_list_add_to_end(&interface_ptr->activeUnicastList, tx_entry);
|
ns_list_add_to_end(&interface_ptr->activeUnicastList, tx_entry);
|
||||||
|
interface_ptr->activeTxList_size++;
|
||||||
} else {
|
} else {
|
||||||
tx_entry = &interface_ptr->active_broadcast_tx_buf;
|
tx_entry = &interface_ptr->active_broadcast_tx_buf;
|
||||||
}
|
}
|
||||||
|
@ -969,6 +998,13 @@ static bool lowpan_buffer_tx_allowed(fragmenter_interface_t *interface_ptr, buff
|
||||||
if (!is_unicast && interface_ptr->active_broadcast_tx_buf.buf) {
|
if (!is_unicast && interface_ptr->active_broadcast_tx_buf.buf) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_unicast && interface_ptr->activeTxList_size >= LOWPAN_ACTIVE_UNICAST_ONGOING_MAX) {
|
||||||
|
//New TX is not possible there is already too manyactive connecting
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Do not accept more than one active unicast TX per destination
|
// Do not accept more than one active unicast TX per destination
|
||||||
if (is_unicast && lowpan_adaptation_is_destination_tx_active(&interface_ptr->activeUnicastList, buf)) {
|
if (is_unicast && lowpan_adaptation_is_destination_tx_active(&interface_ptr->activeUnicastList, buf)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -992,6 +1028,18 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
|
||||||
goto tx_error_handler;
|
goto tx_error_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t traffic_class = buf->options.traffic_class >> IP_TCLASS_DSCP_SHIFT;
|
||||||
|
|
||||||
|
if (traffic_class == IP_DSCP_EF) {
|
||||||
|
buffer_priority_set(buf, QOS_EXPEDITE_FORWARD);
|
||||||
|
} else if (traffic_class == IP_DSCP_CS6) {
|
||||||
|
//Network Control
|
||||||
|
buffer_priority_set(buf, QOS_NETWORK_CTRL);
|
||||||
|
} else if (traffic_class) {
|
||||||
|
buffer_priority_set(buf, QOS_HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Check packet size
|
//Check packet size
|
||||||
bool fragmented_needed = lowpan_adaptation_request_longer_than_mtu(cur, buf, interface_ptr);
|
bool fragmented_needed = lowpan_adaptation_request_longer_than_mtu(cur, buf, interface_ptr);
|
||||||
if (fragmented_needed) {
|
if (fragmented_needed) {
|
||||||
|
@ -1010,7 +1058,18 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
|
||||||
bool indirect = buf->link_specific.ieee802_15_4.indirectTxProcess;
|
bool indirect = buf->link_specific.ieee802_15_4.indirectTxProcess;
|
||||||
|
|
||||||
if (!lowpan_buffer_tx_allowed(interface_ptr, buf)) {
|
if (!lowpan_buffer_tx_allowed(interface_ptr, buf)) {
|
||||||
|
|
||||||
|
if (buf->priority == QOS_NORMAL) {
|
||||||
|
|
||||||
|
if (random_early_detection_congestion_check(cur->random_early_detection)) {
|
||||||
|
random_early_detetction_aq_calc(cur->random_early_detection, interface_ptr->directTxQueue_size);
|
||||||
|
protocol_stats_update(STATS_AL_TX_CONGESTION_DROP, 1);
|
||||||
|
goto tx_error_handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lowpan_adaptation_tx_queue_write(interface_ptr, buf);
|
lowpan_adaptation_tx_queue_write(interface_ptr, buf);
|
||||||
|
random_early_detetction_aq_calc(cur->random_early_detection, interface_ptr->directTxQueue_size);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1166,6 +1225,7 @@ static void lowpan_adaptation_data_process_clean(fragmenter_interface_t *interfa
|
||||||
} else if (buf->link_specific.ieee802_15_4.requestAck) {
|
} else if (buf->link_specific.ieee802_15_4.requestAck) {
|
||||||
ns_list_remove(&interface_ptr->activeUnicastList, tx_ptr);
|
ns_list_remove(&interface_ptr->activeUnicastList, tx_ptr);
|
||||||
ns_dyn_mem_free(tx_ptr);
|
ns_dyn_mem_free(tx_ptr);
|
||||||
|
interface_ptr->activeTxList_size--;
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_tx_buffer_event_and_free(buf, socket_event);
|
socket_tx_buffer_event_and_free(buf, socket_event);
|
||||||
|
@ -1205,7 +1265,6 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c
|
||||||
tr_error("No data request for this confirmation %u", confirm->msduHandle);
|
tr_error("No data request for this confirmation %u", confirm->msduHandle);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check status for
|
//Check status for
|
||||||
buffer_t *buf = tx_ptr->buf;
|
buffer_t *buf = tx_ptr->buf;
|
||||||
|
|
||||||
|
@ -1229,18 +1288,11 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c
|
||||||
buf->link_specific.ieee802_15_4.rf_channel_switch = false;
|
buf->link_specific.ieee802_15_4.rf_channel_switch = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (confirm->status) {
|
if (confirm->status == MLME_SUCCESS) {
|
||||||
|
|
||||||
case MLME_BUSY_CHAN:
|
|
||||||
lowpan_data_request_to_mac(cur, buf, tx_ptr, interface_ptr);
|
|
||||||
break;
|
|
||||||
case MLME_SUCCESS:
|
|
||||||
|
|
||||||
//Check is there more packets
|
//Check is there more packets
|
||||||
if (lowpan_adaptation_tx_process_ready(tx_ptr)) {
|
if (lowpan_adaptation_tx_process_ready(tx_ptr)) {
|
||||||
bool triggered_from_indirect_cache = false;
|
bool triggered_from_indirect_cache = false;
|
||||||
if (tx_ptr->fragmented_data && active_direct_confirm) {
|
if (tx_ptr->fragmented_data && active_direct_confirm) {
|
||||||
//Clean
|
|
||||||
interface_ptr->fragmenter_active = false;
|
interface_ptr->fragmenter_active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1256,12 +1308,15 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c
|
||||||
} else {
|
} else {
|
||||||
lowpan_data_request_to_mac(cur, buf, tx_ptr, interface_ptr);
|
lowpan_data_request_to_mac(cur, buf, tx_ptr, interface_ptr);
|
||||||
}
|
}
|
||||||
|
} else if ((confirm->status == MLME_BUSY_CHAN) && !ws_info(cur)) {
|
||||||
|
lowpan_data_request_to_mac(cur, buf, tx_ptr, interface_ptr);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
|
||||||
|
if (confirm->status == MLME_TRANSACTION_OVERFLOW) {
|
||||||
|
tr_error("MCPS Data fail by MLME_TRANSACTION_OVERFLOW");
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
case MLME_TX_NO_ACK:
|
|
||||||
case MLME_SECURITY_FAIL:
|
|
||||||
case MLME_TRANSACTION_EXPIRED:
|
|
||||||
default:
|
|
||||||
tr_error("MCPS Data fail by status %u", confirm->status);
|
tr_error("MCPS Data fail by status %u", confirm->status);
|
||||||
if (buf->dst_sa.addr_type == ADDR_802_15_4_SHORT) {
|
if (buf->dst_sa.addr_type == ADDR_802_15_4_SHORT) {
|
||||||
tr_info("Dest addr: %x", common_read_16_bit(buf->dst_sa.address + 2));
|
tr_info("Dest addr: %x", common_read_16_bit(buf->dst_sa.address + 2));
|
||||||
|
@ -1285,8 +1340,6 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c
|
||||||
}
|
}
|
||||||
|
|
||||||
lowpan_adaptation_data_process_clean(interface_ptr, tx_ptr, map_mlme_status_to_socket_event(confirm->status));
|
lowpan_adaptation_data_process_clean(interface_ptr, tx_ptr, map_mlme_status_to_socket_event(confirm->status));
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// When confirmation is for direct transmission, push all allowed buffers to MAC
|
// When confirmation is for direct transmission, push all allowed buffers to MAC
|
||||||
if (active_direct_confirm == true) {
|
if (active_direct_confirm == true) {
|
||||||
|
@ -1295,6 +1348,8 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c
|
||||||
lowpan_adaptation_interface_tx(cur, buf_from_queue);
|
lowpan_adaptation_interface_tx(cur, buf_from_queue);
|
||||||
buf_from_queue = lowpan_adaptation_tx_queue_read(interface_ptr);
|
buf_from_queue = lowpan_adaptation_tx_queue_read(interface_ptr);
|
||||||
}
|
}
|
||||||
|
//Update Average QUEUE
|
||||||
|
random_early_detetction_aq_calc(cur->random_early_detection, interface_ptr->directTxQueue_size);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1492,6 +1547,18 @@ int8_t lowpan_adaptation_free_messages_from_queues_by_address(struct protocol_in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Check next directTxQueue there may be pending packets also
|
||||||
|
ns_list_foreach_safe(buffer_t, entry, &interface_ptr->directTxQueue) {
|
||||||
|
if (lowpan_tx_buffer_address_compare(&entry->dst_sa, address_ptr, adr_type)) {
|
||||||
|
ns_list_remove(&interface_ptr->directTxQueue, entry);
|
||||||
|
interface_ptr->directTxQueue_size--;
|
||||||
|
//Update Average QUEUE
|
||||||
|
random_early_detetction_aq_calc(cur->random_early_detection, interface_ptr->directTxQueue_size);
|
||||||
|
lowpan_adaptation_tx_queue_level_update(interface_ptr);
|
||||||
|
socket_tx_buffer_event_and_free(entry, SOCKET_TX_FAIL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -712,11 +712,13 @@ void ws_bbr_pan_version_increase(protocol_interface_info_entry_t *cur)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tr_debug("Border router version number update");
|
tr_debug("Border router version number update");
|
||||||
if (configuration & BBR_REQUIRE_DAO_REFRESH) {
|
if (configuration & BBR_PERIODIC_VERSION_INC) {
|
||||||
|
// Periodically increase the version number.
|
||||||
|
// This removes need for DAO, but causes slowness in recovery
|
||||||
|
pan_version_timer = cur->ws_info->cfg->timing.pan_timeout / PAN_VERSION_CHANGE_INTERVAL;
|
||||||
|
} else {
|
||||||
// Version number is not periodically increased forcing nodes to check Border router availability using DAO
|
// Version number is not periodically increased forcing nodes to check Border router availability using DAO
|
||||||
pan_version_timer = 0;
|
pan_version_timer = 0;
|
||||||
} else {
|
|
||||||
pan_version_timer = cur->ws_info->cfg->timing.pan_timeout / PAN_VERSION_CHANGE_INTERVAL;
|
|
||||||
}
|
}
|
||||||
cur->ws_info->pan_information.pan_version++;
|
cur->ws_info->pan_information.pan_version++;
|
||||||
// Inconsistent for border router to make information distribute faster
|
// Inconsistent for border router to make information distribute faster
|
||||||
|
@ -923,12 +925,16 @@ int ws_bbr_configure(int8_t interface_id, uint16_t options)
|
||||||
|
|
||||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||||
|
|
||||||
if (protocol_6lowpan_rpl_root_dodag &&
|
if (options == configuration) {
|
||||||
options != configuration) {
|
return 0;
|
||||||
//Configuration changed delete previous setup
|
|
||||||
ws_bbr_routing_stop(cur);
|
|
||||||
}
|
}
|
||||||
|
//Configuration changed
|
||||||
configuration = options;
|
configuration = options;
|
||||||
|
if (protocol_6lowpan_rpl_root_dodag) {
|
||||||
|
// Already active needs to restart
|
||||||
|
ws_bbr_routing_stop(cur);
|
||||||
|
ws_bbr_pan_version_increase(cur);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
(void)interface_id;
|
(void)interface_id;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#ifdef HAVE_WS
|
#ifdef HAVE_WS
|
||||||
#include "ns_types.h"
|
#include "ns_types.h"
|
||||||
#include "ns_trace.h"
|
#include "ns_trace.h"
|
||||||
|
#include "nsdynmemLIB.h"
|
||||||
#include "net_interface.h"
|
#include "net_interface.h"
|
||||||
#include "eventOS_event.h"
|
#include "eventOS_event.h"
|
||||||
#include "randLIB.h"
|
#include "randLIB.h"
|
||||||
|
@ -43,6 +44,7 @@
|
||||||
#include "Common_Protocols/icmpv6.h"
|
#include "Common_Protocols/icmpv6.h"
|
||||||
#include "Common_Protocols/icmpv6_radv.h"
|
#include "Common_Protocols/icmpv6_radv.h"
|
||||||
#include "Common_Protocols/ipv6_constants.h"
|
#include "Common_Protocols/ipv6_constants.h"
|
||||||
|
#include "Common_Protocols/ip.h"
|
||||||
#include "Service_Libs/Trickle/trickle.h"
|
#include "Service_Libs/Trickle/trickle.h"
|
||||||
#include "Service_Libs/fhss/channel_list.h"
|
#include "Service_Libs/fhss/channel_list.h"
|
||||||
#include "6LoWPAN/ws/ws_common_defines.h"
|
#include "6LoWPAN/ws/ws_common_defines.h"
|
||||||
|
@ -75,6 +77,7 @@
|
||||||
#include "6LoWPAN/ws/ws_eapol_auth_relay.h"
|
#include "6LoWPAN/ws/ws_eapol_auth_relay.h"
|
||||||
#include "6LoWPAN/ws/ws_eapol_relay.h"
|
#include "6LoWPAN/ws/ws_eapol_relay.h"
|
||||||
#include "libNET/src/net_dns_internal.h"
|
#include "libNET/src/net_dns_internal.h"
|
||||||
|
#include "Service_Libs/random_early_detection/random_early_detection_api.h"
|
||||||
|
|
||||||
#define TRACE_GROUP "wsbs"
|
#define TRACE_GROUP "wsbs"
|
||||||
|
|
||||||
|
@ -111,6 +114,7 @@ static int8_t ws_bootstrap_neighbor_set(protocol_interface_info_entry_t *cur, pa
|
||||||
static void ws_bootstrap_candidate_table_reset(protocol_interface_info_entry_t *cur);
|
static void ws_bootstrap_candidate_table_reset(protocol_interface_info_entry_t *cur);
|
||||||
static parent_info_t *ws_bootstrap_candidate_parent_get(struct protocol_interface_info_entry *cur, const uint8_t *addr, bool create);
|
static parent_info_t *ws_bootstrap_candidate_parent_get(struct protocol_interface_info_entry *cur, const uint8_t *addr, bool create);
|
||||||
static void ws_bootstrap_candidate_parent_sort(struct protocol_interface_info_entry *cur, parent_info_t *new_entry);
|
static void ws_bootstrap_candidate_parent_sort(struct protocol_interface_info_entry *cur, parent_info_t *new_entry);
|
||||||
|
static void ws_bootstrap_packet_congestion_init(protocol_interface_info_entry_t *cur);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
WS_PARENT_SOFT_SYNCH = 0, /**< let FHSS make decision if synchronization is needed*/
|
WS_PARENT_SOFT_SYNCH = 0, /**< let FHSS make decision if synchronization is needed*/
|
||||||
|
@ -163,7 +167,7 @@ void ws_bootstrap_mac_neighbor_short_time_set(struct protocol_interface_info_ent
|
||||||
{
|
{
|
||||||
mac_neighbor_table_entry_t *neighbor = mac_neighbor_table_address_discover(mac_neighbor_info(interface), src64, MAC_ADDR_MODE_64_BIT);
|
mac_neighbor_table_entry_t *neighbor = mac_neighbor_table_address_discover(mac_neighbor_info(interface), src64, MAC_ADDR_MODE_64_BIT);
|
||||||
|
|
||||||
if (neighbor && neighbor->link_lifetime != WS_NEIGHBOR_LINK_TIMEOUT) {
|
if (neighbor && neighbor->link_lifetime <= valid_time) {
|
||||||
//mlme_device_descriptor_t device_desc;
|
//mlme_device_descriptor_t device_desc;
|
||||||
neighbor->lifetime = valid_time;
|
neighbor->lifetime = valid_time;
|
||||||
neighbor->link_lifetime = valid_time;
|
neighbor->link_lifetime = valid_time;
|
||||||
|
@ -426,19 +430,47 @@ static void ws_nud_entry_remove(protocol_interface_info_entry_t *cur, mac_neighb
|
||||||
ws_nud_state_clean(cur, nud_entry);
|
ws_nud_state_clean(cur, nud_entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if_address_entry_t *ws_probe_aro_address(protocol_interface_info_entry_t *interface)
|
||||||
|
{
|
||||||
|
if (interface->global_address_available) {
|
||||||
|
ns_list_foreach(if_address_entry_t, address, &interface->ip_addresses) {
|
||||||
|
if (addr_ipv6_scope(address->address, interface) > IPV6_SCOPE_LINK_LOCAL) {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool ws_nud_message_build(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *neighbor, bool nud_process)
|
static bool ws_nud_message_build(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *neighbor, bool nud_process)
|
||||||
{
|
{
|
||||||
//Send NS
|
//Send NS
|
||||||
uint8_t ll_target[16];
|
uint8_t ll_target[16];
|
||||||
|
aro_t aro_temp;
|
||||||
|
//SET ARO and src address pointer to NULL by default
|
||||||
|
aro_t *aro_ptr = NULL;
|
||||||
|
uint8_t *src_address_ptr = NULL;
|
||||||
|
|
||||||
ws_bootsrap_create_ll_address(ll_target, neighbor->mac64);
|
ws_bootsrap_create_ll_address(ll_target, neighbor->mac64);
|
||||||
if (nud_process) {
|
if (nud_process) {
|
||||||
tr_info("NUD generate NS %u", neighbor->index);
|
tr_info("NUD generate NS %u", neighbor->index);
|
||||||
} else {
|
} else {
|
||||||
tr_info("Probe generate NS %u", neighbor->index);
|
tr_info("Probe generate NS %u", neighbor->index);
|
||||||
|
if_address_entry_t *gp_address = ws_probe_aro_address(cur);
|
||||||
|
if (gp_address) {
|
||||||
|
src_address_ptr = gp_address->address;
|
||||||
|
aro_temp.status = ARO_SUCCESS;
|
||||||
|
aro_temp.present = true;
|
||||||
|
memcpy(aro_temp.eui64, cur->mac, 8);
|
||||||
|
//Just Short Test
|
||||||
|
aro_temp.lifetime = 1;
|
||||||
|
aro_ptr = &aro_temp;
|
||||||
}
|
}
|
||||||
buffer_t *buffer = icmpv6_build_ns(cur, ll_target, NULL, true, false, NULL);
|
}
|
||||||
|
buffer_t *buffer = icmpv6_build_ns(cur, ll_target, src_address_ptr, true, false, aro_ptr);
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
|
buffer->options.traffic_class = IP_DSCP_CS6 << IP_TCLASS_DSCP_SHIFT;
|
||||||
protocol_push(buffer);
|
protocol_push(buffer);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1595,10 +1627,15 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
|
||||||
|
|
||||||
//When Config is learned and USE Parent BS is enabled compare is this new BSI
|
//When Config is learned and USE Parent BS is enabled compare is this new BSI
|
||||||
if (cur->ws_info->configuration_learned && cur->ws_info->pan_information.use_parent_bs && ws_bs_ie.broadcast_schedule_identifier != cur->ws_info->hopping_schdule.fhss_bsi) {
|
if (cur->ws_info->configuration_learned && cur->ws_info->pan_information.use_parent_bs && ws_bs_ie.broadcast_schedule_identifier != cur->ws_info->hopping_schdule.fhss_bsi) {
|
||||||
|
//Accept only next possible BSI number
|
||||||
|
if ((cur->ws_info->hopping_schdule.fhss_bsi + 1) != ws_bs_ie.broadcast_schedule_identifier) {
|
||||||
|
tr_debug("Do not accept a unknown BSI: %u", ws_bs_ie.broadcast_schedule_identifier);
|
||||||
|
} else {
|
||||||
tr_debug("NEW Brodcast Schedule %u...BR rebooted", ws_bs_ie.broadcast_schedule_identifier);
|
tr_debug("NEW Brodcast Schedule %u...BR rebooted", ws_bs_ie.broadcast_schedule_identifier);
|
||||||
cur->ws_info->ws_bsi_block.block_time = cur->ws_info->cfg->timing.pan_timeout;
|
cur->ws_info->ws_bsi_block.block_time = cur->ws_info->cfg->timing.pan_timeout;
|
||||||
cur->ws_info->ws_bsi_block.old_bsi = cur->ws_info->hopping_schdule.fhss_bsi;
|
cur->ws_info->ws_bsi_block.old_bsi = cur->ws_info->hopping_schdule.fhss_bsi;
|
||||||
ws_bootstrap_event_discovery_start(cur);
|
ws_bootstrap_event_discovery_start(cur);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2359,6 +2396,7 @@ int ws_bootstrap_aro_failure(protocol_interface_info_entry_t *cur, const uint8_t
|
||||||
static int ws_bootstrap_set_domain_rf_config(protocol_interface_info_entry_t *cur)
|
static int ws_bootstrap_set_domain_rf_config(protocol_interface_info_entry_t *cur)
|
||||||
{
|
{
|
||||||
phy_rf_channel_configuration_s rf_configs;
|
phy_rf_channel_configuration_s rf_configs;
|
||||||
|
memset(&rf_configs, 0, sizeof(phy_rf_channel_configuration_s));
|
||||||
rf_configs.channel_0_center_frequency = (uint32_t)cur->ws_info->hopping_schdule.ch0_freq * 100000;
|
rf_configs.channel_0_center_frequency = (uint32_t)cur->ws_info->hopping_schdule.ch0_freq * 100000;
|
||||||
rf_configs.channel_spacing = ws_decode_channel_spacing(cur->ws_info->hopping_schdule.channel_spacing);
|
rf_configs.channel_spacing = ws_decode_channel_spacing(cur->ws_info->hopping_schdule.channel_spacing);
|
||||||
rf_configs.datarate = ws_get_datarate_using_operating_mode(cur->ws_info->hopping_schdule.operating_mode);
|
rf_configs.datarate = ws_get_datarate_using_operating_mode(cur->ws_info->hopping_schdule.operating_mode);
|
||||||
|
@ -2536,6 +2574,10 @@ static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
} else if (event == RPL_EVENT_LOCAL_REPAIR_START) {
|
||||||
|
tr_debug("RPL local repair start");
|
||||||
|
ws_nwk_event_post(cur, ARM_NWK_NWK_CONNECTION_DOWN);
|
||||||
|
|
||||||
} else if (event == RPL_EVENT_DAO_PARENT_ADD) {
|
} else if (event == RPL_EVENT_DAO_PARENT_ADD) {
|
||||||
ws_address_parent_update(cur);
|
ws_address_parent_update(cur);
|
||||||
}
|
}
|
||||||
|
@ -3272,6 +3314,8 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
|
||||||
|
|
||||||
// All trickle timers stopped to allow entry from any state
|
// All trickle timers stopped to allow entry from any state
|
||||||
ws_bootstrap_asynch_trickle_stop(cur);
|
ws_bootstrap_asynch_trickle_stop(cur);
|
||||||
|
//Init Packet congestion
|
||||||
|
ws_bootstrap_packet_congestion_init(cur);
|
||||||
|
|
||||||
if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
|
if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
|
||||||
tr_info("Border router start network");
|
tr_info("Border router start network");
|
||||||
|
@ -3761,4 +3805,78 @@ int ws_bootstrap_get_info(protocol_interface_info_entry_t *cur, struct ws_stack_
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Calculate max_packet queue size
|
||||||
|
static uint16_t ws_bootstrap_define_congestin_max_threshold(uint32_t heap_total_size, uint16_t packet_size, uint16_t packet_per_seconds, uint32_t max_delay, uint16_t min_packet_queue_size, uint16_t max_packet_queue_size)
|
||||||
|
{
|
||||||
|
uint32_t max_packet_count = 0;
|
||||||
|
if (heap_total_size) {
|
||||||
|
//Claculate how many packet can be max queue to half of heap
|
||||||
|
max_packet_count = (heap_total_size / 2) / packet_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Calculate how many packet is possible to queue for guarantee given max delay
|
||||||
|
uint32_t max_delayded_queue_size = max_delay * packet_per_seconds;
|
||||||
|
|
||||||
|
if (max_packet_count > max_delayded_queue_size) {
|
||||||
|
//Limit queue size by MAX delay
|
||||||
|
max_packet_count = max_delayded_queue_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max_packet_count > max_packet_queue_size) {
|
||||||
|
//Limit queue size by Max
|
||||||
|
max_packet_count = max_packet_queue_size;
|
||||||
|
} else if (max_packet_count < min_packet_queue_size) {
|
||||||
|
//Limit queue size by Min
|
||||||
|
max_packet_count = min_packet_queue_size;
|
||||||
|
}
|
||||||
|
return (uint16_t)max_packet_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t ws_bootstrap_packet_per_seconds(protocol_interface_info_entry_t *cur, uint16_t packet_size)
|
||||||
|
{
|
||||||
|
uint32_t data_rate = ws_common_datarate_get(cur);
|
||||||
|
|
||||||
|
//calculate how many packet is possible send in paper
|
||||||
|
data_rate /= 8 * packet_size;
|
||||||
|
|
||||||
|
//Divide optimal by / 5 because we split TX / RX slots and BC schedule
|
||||||
|
//With Packet size 500 it should return
|
||||||
|
//Return 15 for 300kBits
|
||||||
|
//Return 7 for 150kBits
|
||||||
|
//Return 2 for 50kBits
|
||||||
|
return data_rate / 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void ws_bootstrap_packet_congestion_init(protocol_interface_info_entry_t *cur)
|
||||||
|
{
|
||||||
|
random_early_detection_free(cur->random_early_detection);
|
||||||
|
cur->random_early_detection = NULL;
|
||||||
|
|
||||||
|
//TODO implement API for HEAP info request
|
||||||
|
uint32_t heap_size;
|
||||||
|
const mem_stat_t *mem_stats = ns_dyn_mem_get_mem_stat();
|
||||||
|
if (mem_stats) {
|
||||||
|
heap_size = mem_stats->heap_sector_size;
|
||||||
|
} else {
|
||||||
|
heap_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t packet_per_seconds = ws_bootstrap_packet_per_seconds(cur, WS_CONGESTION_PACKET_SIZE);
|
||||||
|
|
||||||
|
uint16_t min_th, max_th;
|
||||||
|
|
||||||
|
if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
|
||||||
|
max_th = ws_bootstrap_define_congestin_max_threshold(heap_size, WS_CONGESTION_PACKET_SIZE, packet_per_seconds, WS_CONGESTION_QUEUE_DELAY, WS_CONGESTION_BR_MIN_QUEUE_SIZE, WS_CONGESTION_BR_MAX_QUEUE_SIZE);
|
||||||
|
} else {
|
||||||
|
max_th = ws_bootstrap_define_congestin_max_threshold(heap_size, WS_CONGESTION_PACKET_SIZE, packet_per_seconds, WS_CONGESTION_QUEUE_DELAY, WS_CONGESTION_NODE_MIN_QUEUE_SIZE, WS_CONGESTION_NODE_MAX_QUEUE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
min_th = max_th / 2;
|
||||||
|
tr_info("Wi-SUN packet congestion minTh %u, maxTh %u, drop probability %u weight %u, Packet/Seconds %u", min_th, max_th, WS_CONGESTION_RED_DROP_PROBABILITY, RED_AVERAGE_WEIGHT_EIGHTH, packet_per_seconds);
|
||||||
|
cur->random_early_detection = random_early_detection_create(min_th, max_th, WS_CONGESTION_RED_DROP_PROBABILITY, RED_AVERAGE_WEIGHT_EIGHTH);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endif //HAVE_WS
|
#endif //HAVE_WS
|
||||||
|
|
|
@ -390,29 +390,41 @@ uint8_t ws_common_temporary_entry_size(uint8_t mac_table_size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ws_common_neighbour_address_reg_link_update(protocol_interface_info_entry_t *interface, const uint8_t *eui64)
|
static void ws_common_neighbour_address_reg_link_update(protocol_interface_info_entry_t *interface, const uint8_t *eui64, uint32_t link_lifetime)
|
||||||
{
|
{
|
||||||
|
if (link_lifetime > WS_NEIGHBOR_LINK_TIMEOUT) {
|
||||||
|
link_lifetime = WS_NEIGHBOR_LINK_TIMEOUT;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* ARO registration from child can update the link timeout so we don't need to send extra NUD if ARO received
|
* ARO registration from child can update the link timeout so we don't need to send extra NUD if ARO received
|
||||||
*/
|
*/
|
||||||
mac_neighbor_table_entry_t *mac_neighbor = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(interface), eui64, false, false);
|
mac_neighbor_table_entry_t *mac_neighbor = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(interface), eui64, false, false);
|
||||||
|
|
||||||
if (mac_neighbor) {
|
if (mac_neighbor) {
|
||||||
if (mac_neighbor->link_lifetime != WS_NEIGHBOR_LINK_TIMEOUT) {
|
if (mac_neighbor->link_lifetime < link_lifetime) {
|
||||||
//Set Stable timeout for temporary entry here
|
//Set Stable timeout for temporary entry here
|
||||||
mac_neighbor->link_lifetime = WS_NEIGHBOR_LINK_TIMEOUT;
|
if (link_lifetime > WS_NEIGHBOUR_TEMPORARY_NEIGH_MAX_LIFETIME && mac_neighbor->link_lifetime < WS_NEIGHBOUR_TEMPORARY_NEIGH_MAX_LIFETIME) {
|
||||||
tr_info("Added new neighbor %s : index:%u", trace_array(eui64, 8), mac_neighbor->index);
|
tr_info("Added new neighbor %s : index:%u", trace_array(eui64, 8), mac_neighbor->index);
|
||||||
}
|
}
|
||||||
|
mac_neighbor->link_lifetime = WS_NEIGHBOR_LINK_TIMEOUT;
|
||||||
|
|
||||||
|
}
|
||||||
//Refresh
|
//Refresh
|
||||||
mac_neighbor->lifetime = mac_neighbor->link_lifetime;
|
mac_neighbor->lifetime = mac_neighbor->link_lifetime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t ws_common_allow_child_registration(protocol_interface_info_entry_t *interface, const uint8_t *eui64)
|
uint8_t ws_common_allow_child_registration(protocol_interface_info_entry_t *interface, const uint8_t *eui64, uint16_t aro_timeout)
|
||||||
{
|
{
|
||||||
uint8_t child_count = 0;
|
uint8_t child_count = 0;
|
||||||
uint8_t max_child_count = mac_neighbor_info(interface)->list_total_size - ws_common_temporary_entry_size(mac_neighbor_info(interface)->list_total_size);
|
uint8_t max_child_count = mac_neighbor_info(interface)->list_total_size - ws_common_temporary_entry_size(mac_neighbor_info(interface)->list_total_size);
|
||||||
|
|
||||||
|
if (aro_timeout == 0) {
|
||||||
|
//DeRegister Address Reg
|
||||||
|
return ARO_SUCCESS;
|
||||||
|
}
|
||||||
|
uint32_t link_lifetime = (aro_timeout * 60) + 1;
|
||||||
|
|
||||||
// Test API to limit child count
|
// Test API to limit child count
|
||||||
if (test_max_child_count_override != 0xffff) {
|
if (test_max_child_count_override != 0xffff) {
|
||||||
max_child_count = test_max_child_count_override;
|
max_child_count = test_max_child_count_override;
|
||||||
|
@ -420,8 +432,9 @@ uint8_t ws_common_allow_child_registration(protocol_interface_info_entry_t *inte
|
||||||
|
|
||||||
//Validate Is EUI64 already allocated for any address
|
//Validate Is EUI64 already allocated for any address
|
||||||
if (ipv6_neighbour_has_registered_by_eui64(&interface->ipv6_neighbour_cache, eui64)) {
|
if (ipv6_neighbour_has_registered_by_eui64(&interface->ipv6_neighbour_cache, eui64)) {
|
||||||
ws_common_neighbour_address_reg_link_update(interface, eui64);
|
ws_common_neighbour_address_reg_link_update(interface, eui64, link_lifetime);
|
||||||
tr_info("Child registration from old child");
|
tr_info("Child registration from old child");
|
||||||
|
|
||||||
return ARO_SUCCESS;
|
return ARO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,20 +444,21 @@ uint8_t ws_common_allow_child_registration(protocol_interface_info_entry_t *inte
|
||||||
return ARO_TOPOLOGICALLY_INCORRECT;
|
return ARO_TOPOLOGICALLY_INCORRECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ns_list_foreach_safe(mac_neighbor_table_entry_t, cur, &mac_neighbor_info(interface)->neighbour_list) {
|
ns_list_foreach_safe(mac_neighbor_table_entry_t, cur, &mac_neighbor_info(interface)->neighbour_list) {
|
||||||
|
|
||||||
if (ipv6_neighbour_has_registered_by_eui64(&interface->ipv6_neighbour_cache, cur->mac64)) {
|
if (ipv6_neighbour_has_registered_by_eui64(&interface->ipv6_neighbour_cache, cur->mac64)) {
|
||||||
child_count++;
|
child_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (child_count >= max_child_count) {
|
if (child_count >= max_child_count) {
|
||||||
tr_warn("Child registration not allowed %d/%d, max:%d", child_count, max_child_count, mac_neighbor_info(interface)->list_total_size);
|
tr_warn("Child registration not allowed %d/%d, max:%d", child_count, max_child_count, mac_neighbor_info(interface)->list_total_size);
|
||||||
return ARO_FULL;
|
return ARO_FULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ws_common_neighbour_address_reg_link_update(interface, eui64);
|
ws_common_neighbour_address_reg_link_update(interface, eui64, link_lifetime);
|
||||||
tr_info("Child registration allowed %d/%d, max:%d", child_count, max_child_count, mac_neighbor_info(interface)->list_total_size);
|
tr_info("Child registration allowed %d/%d, max:%d", child_count, max_child_count, mac_neighbor_info(interface)->list_total_size);
|
||||||
|
|
||||||
return ARO_SUCCESS;
|
return ARO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,13 +486,13 @@ uint32_t ws_common_latency_estimate_get(protocol_interface_info_entry_t *cur)
|
||||||
|
|
||||||
if (network_size <= NETWORK_SIZE_SMALL) {
|
if (network_size <= NETWORK_SIZE_SMALL) {
|
||||||
// handles also NETWORK_SIZE_CERTIFICATE
|
// handles also NETWORK_SIZE_CERTIFICATE
|
||||||
latency = 4000;
|
latency = 5000;
|
||||||
} else if (network_size <= NETWORK_SIZE_MEDIUM) {
|
} else if (network_size <= NETWORK_SIZE_MEDIUM) {
|
||||||
latency = 8000;
|
latency = 10000;
|
||||||
} else if (network_size <= NETWORK_SIZE_LARGE) {
|
} else if (network_size <= NETWORK_SIZE_LARGE) {
|
||||||
latency = 16000;
|
latency = 20000;
|
||||||
} else {
|
} else {
|
||||||
latency = 24000;
|
latency = 30000;
|
||||||
}
|
}
|
||||||
|
|
||||||
return latency;
|
return latency;
|
||||||
|
|
|
@ -148,7 +148,7 @@ void ws_common_aro_failure(protocol_interface_info_entry_t *cur, const uint8_t *
|
||||||
|
|
||||||
void ws_common_neighbor_remove(protocol_interface_info_entry_t *cur, const uint8_t *ll_address);
|
void ws_common_neighbor_remove(protocol_interface_info_entry_t *cur, const uint8_t *ll_address);
|
||||||
|
|
||||||
uint8_t ws_common_allow_child_registration(protocol_interface_info_entry_t *cur, const uint8_t *eui64);
|
uint8_t ws_common_allow_child_registration(protocol_interface_info_entry_t *cur, const uint8_t *eui64, uint16_t aro_timeout);
|
||||||
|
|
||||||
bool ws_common_negative_aro_mark(protocol_interface_info_entry_t *interface, const uint8_t *eui64);
|
bool ws_common_negative_aro_mark(protocol_interface_info_entry_t *interface, const uint8_t *eui64);
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ uint8_t ws_common_temporary_entry_size(uint8_t mac_table_size);
|
||||||
#define ws_common_aro_failure(cur, ll_address)
|
#define ws_common_aro_failure(cur, ll_address)
|
||||||
#define ws_common_neighbor_remove(cur, ll_address)
|
#define ws_common_neighbor_remove(cur, ll_address)
|
||||||
#define ws_common_fast_timer(cur, ticks) ((void) 0)
|
#define ws_common_fast_timer(cur, ticks) ((void) 0)
|
||||||
#define ws_common_allow_child_registration(cur, eui64) (2)
|
#define ws_common_allow_child_registration(cur, eui64, aro_timeout) (2)
|
||||||
#define ws_common_negative_aro_mark(interface, eui64)(false)
|
#define ws_common_negative_aro_mark(interface, eui64)(false)
|
||||||
#define ws_common_latency_estimate_get(cur) 0
|
#define ws_common_latency_estimate_get(cur) 0
|
||||||
#define ws_common_datarate_get(cur) 0
|
#define ws_common_datarate_get(cur) 0
|
||||||
|
|
|
@ -144,9 +144,9 @@ extern uint8_t DEVICE_MIN_SENS;
|
||||||
#define MPL_SMALL_K 8
|
#define MPL_SMALL_K 8
|
||||||
#define MPL_SMALL_SEED_LIFETIME (MPL_SMALL_IMAX * MPL_SAFE_HOP_COUNT * (MPL_SMALL_EXPIRATIONS + 1)) // time that packet should get to safe distance
|
#define MPL_SMALL_SEED_LIFETIME (MPL_SMALL_IMAX * MPL_SAFE_HOP_COUNT * (MPL_SMALL_EXPIRATIONS + 1)) // time that packet should get to safe distance
|
||||||
/*Medium network size*/
|
/*Medium network size*/
|
||||||
#define MPL_MEDIUM_IMIN 5
|
#define MPL_MEDIUM_IMIN 1
|
||||||
#define MPL_MEDIUM_IMAX 20
|
#define MPL_MEDIUM_IMAX 32
|
||||||
#define MPL_MEDIUM_EXPIRATIONS 2
|
#define MPL_MEDIUM_EXPIRATIONS 1
|
||||||
#define MPL_MEDIUM_K 8
|
#define MPL_MEDIUM_K 8
|
||||||
#define MPL_MEDIUM_SEED_LIFETIME (MPL_MEDIUM_IMAX * MPL_SAFE_HOP_COUNT * (MPL_MEDIUM_EXPIRATIONS + 1)) // time that packet should get to safe distance
|
#define MPL_MEDIUM_SEED_LIFETIME (MPL_MEDIUM_IMAX * MPL_SAFE_HOP_COUNT * (MPL_MEDIUM_EXPIRATIONS + 1)) // time that packet should get to safe distance
|
||||||
/*Large network size*/
|
/*Large network size*/
|
||||||
|
@ -221,6 +221,13 @@ extern uint8_t DEVICE_MIN_SENS;
|
||||||
#define WS_PARENT_LIST_MAX_PAN_IN_DISCOVERY 5 // During discovery state how many neighbours per pan
|
#define WS_PARENT_LIST_MAX_PAN_IN_DISCOVERY 5 // During discovery state how many neighbours per pan
|
||||||
#define WS_PARENT_LIST_MAX_PAN_IN_ACTIVE 2 // During active state two nodes per pan is allowed
|
#define WS_PARENT_LIST_MAX_PAN_IN_ACTIVE 2 // During active state two nodes per pan is allowed
|
||||||
|
|
||||||
|
#define WS_CONGESTION_PACKET_SIZE 500 // Packet length for calculate how much heap message queue can fit
|
||||||
|
#define WS_CONGESTION_QUEUE_DELAY 60 // Define message queue max length for given delay. This value is multiple by packet/seconds
|
||||||
|
#define WS_CONGESTION_RED_DROP_PROBABILITY 10 //10.0%
|
||||||
|
#define WS_CONGESTION_BR_MIN_QUEUE_SIZE 85000 / WS_CONGESTION_PACKET_SIZE
|
||||||
|
#define WS_CONGESTION_BR_MAX_QUEUE_SIZE 600000 / WS_CONGESTION_PACKET_SIZE
|
||||||
|
#define WS_CONGESTION_NODE_MIN_QUEUE_SIZE 10000 / WS_CONGESTION_PACKET_SIZE
|
||||||
|
#define WS_CONGESTION_NODE_MAX_QUEUE_SIZE 85000 / WS_CONGESTION_PACKET_SIZE
|
||||||
/*
|
/*
|
||||||
* Modifications for base specification.
|
* Modifications for base specification.
|
||||||
*
|
*
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "mac_api.h"
|
#include "mac_api.h"
|
||||||
#include "mac_mcps.h"
|
#include "mac_mcps.h"
|
||||||
#include "Common_Protocols/ipv6_constants.h"
|
#include "Common_Protocols/ipv6_constants.h"
|
||||||
|
#include "Common_Protocols/ip.h"
|
||||||
#include "socket_api.h"
|
#include "socket_api.h"
|
||||||
#include "6LoWPAN/MAC/mac_helper.h"
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
#include "6LoWPAN/MAC/mpx_api.h"
|
#include "6LoWPAN/MAC/mpx_api.h"
|
||||||
|
@ -80,6 +81,8 @@ int8_t ws_eapol_auth_relay_start(protocol_interface_info_entry_t *interface_ptr,
|
||||||
ns_dyn_mem_free(eapol_auth_relay);
|
ns_dyn_mem_free(eapol_auth_relay);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
int16_t tc = IP_DSCP_CS6 << IP_TCLASS_DSCP_SHIFT;
|
||||||
|
socket_setsockopt(eapol_auth_relay->socket_id, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_TCLASS, &tc, sizeof(tc));
|
||||||
|
|
||||||
ns_list_add_to_end(&eapol_auth_relay_list, eapol_auth_relay);
|
ns_list_add_to_end(&eapol_auth_relay_list, eapol_auth_relay);
|
||||||
|
|
||||||
|
|
|
@ -278,6 +278,9 @@ static void ws_eapol_pdu_mpx_data_confirm(const mpx_api_t *api, const struct mcp
|
||||||
status = EAPOL_PDU_TX_OK;
|
status = EAPOL_PDU_TX_OK;
|
||||||
} else if (data->status == MLME_TX_NO_ACK) {
|
} else if (data->status == MLME_TX_NO_ACK) {
|
||||||
status = EAPOL_PDU_TX_ERR_TX_NO_ACK;
|
status = EAPOL_PDU_TX_ERR_TX_NO_ACK;
|
||||||
|
tr_error("EAPOL TX err no ack");
|
||||||
|
} else {
|
||||||
|
tr_error("EAPOL TX err");
|
||||||
}
|
}
|
||||||
msdu->tx_status(eapol_pdu_data->interface_ptr, status, msdu->tx_identifier);
|
msdu->tx_status(eapol_pdu_data->interface_ptr, status, msdu->tx_identifier);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "mac_api.h"
|
#include "mac_api.h"
|
||||||
#include "mac_mcps.h"
|
#include "mac_mcps.h"
|
||||||
#include "Common_Protocols/ipv6_constants.h"
|
#include "Common_Protocols/ipv6_constants.h"
|
||||||
|
#include "Common_Protocols/ip.h"
|
||||||
#include "socket_api.h"
|
#include "socket_api.h"
|
||||||
#include "6LoWPAN/MAC/mac_helper.h"
|
#include "6LoWPAN/MAC/mac_helper.h"
|
||||||
#include "6LoWPAN/MAC/mpx_api.h"
|
#include "6LoWPAN/MAC/mpx_api.h"
|
||||||
|
@ -89,6 +90,8 @@ int8_t ws_eapol_relay_start(protocol_interface_info_entry_t *interface_ptr, uint
|
||||||
ns_dyn_mem_free(eapol_relay);
|
ns_dyn_mem_free(eapol_relay);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
int16_t tc = IP_DSCP_CS6 << IP_TCLASS_DSCP_SHIFT;
|
||||||
|
socket_setsockopt(eapol_relay->socket_id, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_TCLASS, &tc, sizeof(tc));
|
||||||
|
|
||||||
if (ws_eapol_pdu_cb_register(interface_ptr, &eapol_pdu_recv_cb_data) < 0) {
|
if (ws_eapol_pdu_cb_register(interface_ptr, &eapol_pdu_recv_cb_data) < 0) {
|
||||||
ns_dyn_mem_free(eapol_relay);
|
ns_dyn_mem_free(eapol_relay);
|
||||||
|
|
|
@ -537,7 +537,7 @@ static void ws_llc_mac_confirm_cb(const mac_api_t *api, const mcps_data_conf_t *
|
||||||
ws_llc_mpx_eapol_send(base, message);
|
ws_llc_mpx_eapol_send(base, message);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (neighbor_info.ws_neighbor && neighbor_info.neighbor && neighbor_info.neighbor->link_lifetime < WS_NEIGHBOUR_TEMPORARY_NEIGH_MAX_LIFETIME) {
|
if (neighbor_info.ws_neighbor && neighbor_info.neighbor && neighbor_info.neighbor->link_lifetime <= WS_NEIGHBOUR_DHCP_ENTRY_LIFETIME) {
|
||||||
//Remove temp neighbour
|
//Remove temp neighbour
|
||||||
tr_debug("Remove Temp Entry by TX confirm");
|
tr_debug("Remove Temp Entry by TX confirm");
|
||||||
mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), neighbor_info.neighbor);
|
mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), neighbor_info.neighbor);
|
||||||
|
|
|
@ -1110,6 +1110,7 @@ buffer_t *icmpv6_up(buffer_t *buf)
|
||||||
|| (buf->options.type == ICMPV6_TYPE_INFO_RPL_CONTROL
|
|| (buf->options.type == ICMPV6_TYPE_INFO_RPL_CONTROL
|
||||||
&& (buf->options.code != ICMPV6_CODE_RPL_DIO
|
&& (buf->options.code != ICMPV6_CODE_RPL_DIO
|
||||||
&& buf->options.code != ICMPV6_CODE_RPL_DIS))) {
|
&& buf->options.code != ICMPV6_CODE_RPL_DIS))) {
|
||||||
|
tr_warn("Drop: ICMP EP unsecured packet");
|
||||||
goto drop;
|
goto drop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1526,7 +1527,11 @@ buffer_t *icmpv6_build_ns(protocol_interface_info_entry_t *cur, const uint8_t ta
|
||||||
/* If ARO Success sending is omitted, MAC ACK is used instead */
|
/* If ARO Success sending is omitted, MAC ACK is used instead */
|
||||||
/* Setting callback for receiving ACK from adaptation layer */
|
/* Setting callback for receiving ACK from adaptation layer */
|
||||||
if (aro && cur->ipv6_neighbour_cache.omit_na_aro_success) {
|
if (aro && cur->ipv6_neighbour_cache.omit_na_aro_success) {
|
||||||
|
if (aro->lifetime > 1) {
|
||||||
buf->ack_receive_cb = icmpv6_aro_cb;
|
buf->ack_receive_cb = icmpv6_aro_cb;
|
||||||
|
} else {
|
||||||
|
buf->ack_receive_cb = ack_receive_cb;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (unicast && (!aro && cur->ipv6_neighbour_cache.omit_na)) {
|
if (unicast && (!aro && cur->ipv6_neighbour_cache.omit_na)) {
|
||||||
|
@ -1761,6 +1766,7 @@ buffer_t *icmpv6_build_na(protocol_interface_info_entry_t *cur, bool solicited,
|
||||||
tr_debug("Neighbour removed for negative response send");
|
tr_debug("Neighbour removed for negative response send");
|
||||||
return buffer_free(buf);
|
return buffer_free(buf);
|
||||||
}
|
}
|
||||||
|
buf->options.traffic_class = IP_DSCP_CS6 << IP_TCLASS_DSCP_SHIFT;
|
||||||
buf->ack_receive_cb = ack_remove_neighbour_cb;
|
buf->ack_receive_cb = ack_remove_neighbour_cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1416,6 +1416,7 @@ buffer_t *ipv6_forwarding_up(buffer_t *buf)
|
||||||
#endif
|
#endif
|
||||||
default: {
|
default: {
|
||||||
if (buf->options.ll_security_bypass_rx) {
|
if (buf->options.ll_security_bypass_rx) {
|
||||||
|
tr_warn("Drop: unsecured by BAD Next header %u", *nh_ptr);
|
||||||
goto bad_nh;
|
goto bad_nh;
|
||||||
}
|
}
|
||||||
buffer_socket_set(buf, socket_lookup_ipv6(*nh_ptr, &buf->dst_sa, &buf->src_sa, true));
|
buffer_socket_set(buf, socket_lookup_ipv6(*nh_ptr, &buf->dst_sa, &buf->src_sa, true));
|
||||||
|
|
|
@ -180,7 +180,9 @@ typedef enum {
|
||||||
typedef enum {
|
typedef enum {
|
||||||
QOS_NORMAL = 0,
|
QOS_NORMAL = 0,
|
||||||
QOS_HIGH = 1,
|
QOS_HIGH = 1,
|
||||||
QOS_MAC_BEACON = 2
|
QOS_NETWORK_CTRL = 2,
|
||||||
|
QOS_EXPEDITE_FORWARD = 3,
|
||||||
|
QOS_MAC_BEACON = 4
|
||||||
} buffer_priority_t;
|
} buffer_priority_t;
|
||||||
|
|
||||||
#define B_TO_MAC_MLME_MASK (B_DIR_MASK + B_FROM_MASK + B_TO_MASK )
|
#define B_TO_MAC_MLME_MASK (B_DIR_MASK + B_FROM_MASK + B_TO_MASK )
|
||||||
|
|
|
@ -828,6 +828,9 @@ int8_t mac_mlme_set_req(protocol_interface_rf_mac_setup_s *rf_mac_setup, const m
|
||||||
tr_info("Number of channels: %u", config_params->number_of_channels);
|
tr_info("Number of channels: %u", config_params->number_of_channels);
|
||||||
tr_info("Modulation: %u", config_params->modulation);
|
tr_info("Modulation: %u", config_params->modulation);
|
||||||
tr_info("Modulation index: %u", config_params->modulation_index);
|
tr_info("Modulation index: %u", config_params->modulation_index);
|
||||||
|
tr_info("FEC: %u", config_params->fec);
|
||||||
|
tr_info("OFDM MCS: %u", config_params->ofdm_mcs);
|
||||||
|
tr_info("OFDM option: %u", config_params->ofdm_option);
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
return mac_mlme_handle_set_values(rf_mac_setup, set_req);
|
return mac_mlme_handle_set_values(rf_mac_setup, set_req);
|
||||||
|
|
|
@ -406,6 +406,7 @@ static mpl_buffered_message_t *mpl_buffer_create(buffer_t *buf, mpl_domain_t *do
|
||||||
uint16_t ip_len = buffer_data_length(buf);
|
uint16_t ip_len = buffer_data_length(buf);
|
||||||
|
|
||||||
while (mpl_total_buffered + ip_len > MAX_BUFFERED_MESSAGES_SIZE) {
|
while (mpl_total_buffered + ip_len > MAX_BUFFERED_MESSAGES_SIZE) {
|
||||||
|
tr_debug("MPL MAX buffered message size limit...free space");
|
||||||
mpl_free_space();
|
mpl_free_space();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,6 +428,7 @@ static mpl_buffered_message_t *mpl_buffer_create(buffer_t *buf, mpl_domain_t *do
|
||||||
|
|
||||||
mpl_buffered_message_t *message = ns_dyn_mem_alloc(sizeof(mpl_buffered_message_t) + ip_len);
|
mpl_buffered_message_t *message = ns_dyn_mem_alloc(sizeof(mpl_buffered_message_t) + ip_len);
|
||||||
if (!message) {
|
if (!message) {
|
||||||
|
tr_debug("No heap for new MPL message");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memcpy(message->message, buffer_data_pointer(buf), ip_len);
|
memcpy(message->message, buffer_data_pointer(buf), ip_len);
|
||||||
|
@ -475,6 +477,7 @@ static void mpl_buffer_transmit(mpl_domain_t *domain, mpl_buffered_message_t *me
|
||||||
uint16_t ip_len = mpl_buffer_size(message);
|
uint16_t ip_len = mpl_buffer_size(message);
|
||||||
buffer_t *buf = buffer_get(ip_len);
|
buffer_t *buf = buffer_get(ip_len);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
|
tr_debug("No heap for MPL transmit");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -939,6 +942,9 @@ bool mpl_forwarder_process_message(buffer_t *buf, mpl_domain_t *domain, bool see
|
||||||
}
|
}
|
||||||
|
|
||||||
message = mpl_buffer_create(buf, domain, seed, sequence, hop_limit);
|
message = mpl_buffer_create(buf, domain, seed, sequence, hop_limit);
|
||||||
|
if (!message) {
|
||||||
|
tr_debug("MPL Buffer Craete fail");
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,7 @@ struct arm_device_driver_list;
|
||||||
struct mlme_security_s;
|
struct mlme_security_s;
|
||||||
struct load_balance_api;
|
struct load_balance_api;
|
||||||
struct nwk_wpan_nvm_api;
|
struct nwk_wpan_nvm_api;
|
||||||
|
struct red_info_s;
|
||||||
|
|
||||||
#define SLEEP_MODE_REQ 0x80
|
#define SLEEP_MODE_REQ 0x80
|
||||||
#define SLEEP_PERIOD_ACTIVE 0x40
|
#define SLEEP_PERIOD_ACTIVE 0x40
|
||||||
|
@ -445,6 +446,7 @@ struct protocol_interface_info_entry {
|
||||||
struct auth_info *pana_sec_info_temp;
|
struct auth_info *pana_sec_info_temp;
|
||||||
br_info_t *border_router_setup;
|
br_info_t *border_router_setup;
|
||||||
struct load_balance_api *lb_api;
|
struct load_balance_api *lb_api;
|
||||||
|
struct red_info_s *random_early_detection;
|
||||||
neigh_cache_s neigh_cache;
|
neigh_cache_s neigh_cache;
|
||||||
pan_blaclist_cache_s pan_blaclist_cache;
|
pan_blaclist_cache_s pan_blaclist_cache;
|
||||||
pan_coordinator_blaclist_cache_s pan_cordinator_black_list;
|
pan_coordinator_blaclist_cache_s pan_cordinator_black_list;
|
||||||
|
|
|
@ -44,7 +44,8 @@ typedef enum {
|
||||||
STATS_BUFFER_HEADROOM_FAIL,
|
STATS_BUFFER_HEADROOM_FAIL,
|
||||||
STATS_ETX_1ST_PARENT,
|
STATS_ETX_1ST_PARENT,
|
||||||
STATS_ETX_2ND_PARENT,
|
STATS_ETX_2ND_PARENT,
|
||||||
STATS_AL_TX_QUEUE_SIZE
|
STATS_AL_TX_QUEUE_SIZE,
|
||||||
|
STATS_AL_TX_CONGESTION_DROP
|
||||||
|
|
||||||
} nwk_stats_type_t;
|
} nwk_stats_type_t;
|
||||||
|
|
||||||
|
|
|
@ -152,6 +152,9 @@ void protocol_stats_update(nwk_stats_type_t type, uint16_t update_val)
|
||||||
nwk_stats_ptr->adapt_layer_tx_queue_peak = nwk_stats_ptr->adapt_layer_tx_queue_size;
|
nwk_stats_ptr->adapt_layer_tx_queue_peak = nwk_stats_ptr->adapt_layer_tx_queue_size;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case STATS_AL_TX_CONGESTION_DROP:
|
||||||
|
nwk_stats_ptr->adapt_layer_tx_congestion_drop++;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "NWK_INTERFACE/Include/protocol_stats.h"
|
#include "NWK_INTERFACE/Include/protocol_stats.h"
|
||||||
#include "Common_Protocols/ipv6_constants.h"
|
#include "Common_Protocols/ipv6_constants.h"
|
||||||
#include "Common_Protocols/icmpv6.h"
|
#include "Common_Protocols/icmpv6.h"
|
||||||
|
#include "Common_Protocols/ip.h"
|
||||||
#include "ipv6_stack/protocol_ipv6.h"
|
#include "ipv6_stack/protocol_ipv6.h"
|
||||||
#include "Service_Libs/etx/etx.h" /* slight ick */
|
#include "Service_Libs/etx/etx.h" /* slight ick */
|
||||||
|
|
||||||
|
@ -1292,6 +1293,10 @@ void rpl_control_transmit(rpl_domain_t *domain, protocol_interface_info_entry_t
|
||||||
/* Others set "0", which means use interface default */
|
/* Others set "0", which means use interface default */
|
||||||
buf->options.hop_limit = addr_ipv6_scope(buf->dst_sa.address, cur) <= IPV6_SCOPE_LINK_LOCAL ? 255 : 0;
|
buf->options.hop_limit = addr_ipv6_scope(buf->dst_sa.address, cur) <= IPV6_SCOPE_LINK_LOCAL ? 255 : 0;
|
||||||
|
|
||||||
|
if (code == ICMPV6_CODE_RPL_DAO || code == ICMPV6_CODE_RPL_DAO_ACK || buf->dst_sa.address[0] != 0xff) {
|
||||||
|
//DAO and DAO ACK and unicast traffic with Higher priority
|
||||||
|
buf->options.traffic_class = IP_DSCP_CS6 << IP_TCLASS_DSCP_SHIFT;
|
||||||
|
}
|
||||||
|
|
||||||
if (dst == NULL && cur == NULL) {
|
if (dst == NULL && cur == NULL) {
|
||||||
rpl_control_transmit_all_interfaces(domain, buf);
|
rpl_control_transmit_all_interfaces(domain, buf);
|
||||||
|
|
|
@ -91,6 +91,7 @@
|
||||||
#include "Common_Protocols/icmpv6.h"
|
#include "Common_Protocols/icmpv6.h"
|
||||||
#include "NWK_INTERFACE/Include/protocol.h"
|
#include "NWK_INTERFACE/Include/protocol.h"
|
||||||
#include "ipv6_stack/ipv6_routing_table.h"
|
#include "ipv6_stack/ipv6_routing_table.h"
|
||||||
|
#include "Common_Protocols/ip.h"
|
||||||
|
|
||||||
#include "net_rpl.h"
|
#include "net_rpl.h"
|
||||||
#include "RPL/rpl_protocol.h"
|
#include "RPL/rpl_protocol.h"
|
||||||
|
@ -1874,6 +1875,7 @@ static bool rpl_instance_push_address_registration(protocol_interface_info_entry
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
buf->options.traffic_class = IP_DSCP_CS6 << IP_TCLASS_DSCP_SHIFT;
|
||||||
tr_info("Send ARO %s to %s", trace_ipv6(addr->address), trace_ipv6(neighbour->ll_address));
|
tr_info("Send ARO %s to %s", trace_ipv6(addr->address), trace_ipv6(neighbour->ll_address));
|
||||||
protocol_push(buf);
|
protocol_push(buf);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1840,7 +1840,13 @@ void rpl_upward_dio_timer(rpl_instance_t *instance, uint16_t ticks)
|
||||||
/* Delay sending first DIO if we are still potentially gathering info */
|
/* Delay sending first DIO if we are still potentially gathering info */
|
||||||
/* Important to always send DIOs if we ever have sent any, so we can indicate problems to others */
|
/* Important to always send DIOs if we ever have sent any, so we can indicate problems to others */
|
||||||
if (!rpl_instance_am_root(instance) && !instance->last_advertised_dodag_version && rpl_policy_parent_confirmation_requested()) {
|
if (!rpl_instance_am_root(instance) && !instance->last_advertised_dodag_version && rpl_policy_parent_confirmation_requested()) {
|
||||||
// We dont have any valid parent selected
|
|
||||||
|
// We don't have DAO target generated
|
||||||
|
if (ns_list_count(&instance->dao_targets) == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't have any valid parent selected
|
||||||
if (!rpl_instance_parent_selection_ready(instance)) {
|
if (!rpl_instance_parent_selection_ready(instance)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -652,6 +652,14 @@ static void radius_client_sec_prot_allocate_and_create_radius_message(sec_prot_t
|
||||||
radius_msg_length += AVP_TYPE_NAS_IPV6_ADDRESS_LEN;
|
radius_msg_length += AVP_TYPE_NAS_IPV6_ADDRESS_LEN;
|
||||||
|
|
||||||
uint8_t *radius_msg_ptr = ns_dyn_mem_temporary_alloc(radius_msg_length);
|
uint8_t *radius_msg_ptr = ns_dyn_mem_temporary_alloc(radius_msg_length);
|
||||||
|
if (radius_msg_ptr == NULL) {
|
||||||
|
if (data->send_radius_msg != NULL) {
|
||||||
|
ns_dyn_mem_free(data->send_radius_msg);
|
||||||
|
}
|
||||||
|
data->send_radius_msg = NULL;
|
||||||
|
data->send_radius_msg_len = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
uint8_t *radius_msg_start_ptr = radius_msg_ptr;
|
uint8_t *radius_msg_start_ptr = radius_msg_ptr;
|
||||||
|
|
||||||
*radius_msg_ptr++ = RADIUS_ACCESS_REQUEST; // code
|
*radius_msg_ptr++ = RADIUS_ACCESS_REQUEST; // code
|
||||||
|
|
|
@ -416,7 +416,7 @@ static void tls_sec_prot_lib_debug(void *ctx, int level, const char *file, int l
|
||||||
|
|
||||||
int8_t tls_sec_prot_lib_process(tls_security_t *sec)
|
int8_t tls_sec_prot_lib_process(tls_security_t *sec)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int32_t ret = -1;
|
||||||
|
|
||||||
while (ret != MBEDTLS_ERR_SSL_WANT_READ) {
|
while (ret != MBEDTLS_ERR_SSL_WANT_READ) {
|
||||||
ret = mbedtls_ssl_handshake_step(&sec->ssl);
|
ret = mbedtls_ssl_handshake_step(&sec->ssl);
|
||||||
|
@ -428,6 +428,7 @@ int8_t tls_sec_prot_lib_process(tls_security_t *sec)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ret && (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)) {
|
if (ret && (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)) {
|
||||||
|
tr_error("TLS error: %" PRId32, ret);
|
||||||
return TLS_SEC_PROT_LIB_ERROR;
|
return TLS_SEC_PROT_LIB_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -604,9 +604,14 @@ static int fhss_ws_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_a
|
||||||
if (!fhss_structure) {
|
if (!fhss_structure) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (is_broadcast_addr) {
|
// Allow broadcast destination on broadcast channel
|
||||||
|
if (is_broadcast_addr && (fhss_structure->ws->is_on_bc_channel == true)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
// Do not allow broadcast destination on unicast channel
|
||||||
|
if (is_broadcast_addr && (fhss_structure->ws->is_on_bc_channel == false)) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
// Do not allow unicast destination on broadcast channel
|
// Do not allow unicast destination on broadcast channel
|
||||||
if (!is_broadcast_addr && (fhss_structure->ws->is_on_bc_channel == true)) {
|
if (!is_broadcast_addr && (fhss_structure->ws->is_on_bc_channel == true)) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Arm Limited and affiliates.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nsconfig.h"
|
||||||
|
#include "ns_types.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "ns_trace.h"
|
||||||
|
#include "nsdynmemLIB.h"
|
||||||
|
#include "randLIB.h"
|
||||||
|
#include "Service_Libs/random_early_detection/random_early_detection.h"
|
||||||
|
#include "Service_Libs/random_early_detection/random_early_detection_api.h"
|
||||||
|
|
||||||
|
|
||||||
|
red_info_t *random_early_detection_create(uint16_t threshold_min, uint16_t threshold_max, uint8_t drop_max_p, uint16_t weight)
|
||||||
|
{
|
||||||
|
//Weight must be between 1-256
|
||||||
|
if (weight == 0 || weight > 256) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Probability must be between 1-100
|
||||||
|
if (drop_max_p == 0 || drop_max_p > 100) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Max Threshold can't smaller or similar than min
|
||||||
|
if (threshold_max <= threshold_min) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
red_info_t *red_info = ns_dyn_mem_alloc(sizeof(red_info_t));
|
||||||
|
if (red_info) {
|
||||||
|
red_info->count = 0;
|
||||||
|
red_info->averageQ = 0;
|
||||||
|
red_info->parameters.drop_maX_P = drop_max_p;
|
||||||
|
red_info->parameters.threshold_max = threshold_max;
|
||||||
|
red_info->parameters.threshold_min = threshold_min;
|
||||||
|
red_info->parameters.weight = weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
return red_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void random_early_detection_free(struct red_info_s *red_info)
|
||||||
|
{
|
||||||
|
ns_dyn_mem_free(red_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
//calculate average and return averaged value back
|
||||||
|
uint16_t random_early_detetction_aq_calc(red_info_t *red_info, uint16_t sampleLen)
|
||||||
|
{
|
||||||
|
if (!red_info) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (red_info->parameters.weight == RED_AVERAGE_WEIGHT_DISABLED || red_info->averageQ == 0) {
|
||||||
|
red_info->averageQ = sampleLen * 256;
|
||||||
|
return sampleLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
// AQ = (1-weight) * average_queue + weight*sampleLen
|
||||||
|
// Now Sample is scaled by 256 which is not loosing so much tail at average
|
||||||
|
|
||||||
|
//Weight Last Average part (1-weight) * average_queue with scaled 256
|
||||||
|
uint32_t averageSum = ((256 - red_info->parameters.weight) * red_info->averageQ) / 256;
|
||||||
|
//Add new weighted sample lenght (weight*sampleLen)
|
||||||
|
averageSum += (red_info->parameters.weight * sampleLen);
|
||||||
|
|
||||||
|
if (averageSum & 1) {
|
||||||
|
//If sum is ODD add 1 this will help to not stuck like 1,99 average to -> 2
|
||||||
|
averageSum++;
|
||||||
|
}
|
||||||
|
//Store new average
|
||||||
|
red_info->averageQ = averageSum;
|
||||||
|
//Return always same format scaled than inn
|
||||||
|
return red_info->averageQ / 256;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t random_early_detetction_aq_read(red_info_t *red_info)
|
||||||
|
{
|
||||||
|
if (!red_info) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return red_info->averageQ / 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool random_early_detection_congestion_check(red_info_t *red_info)
|
||||||
|
{
|
||||||
|
if (!red_info) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Calulate Average queue size
|
||||||
|
uint16_t sampleLen = red_info->averageQ / 256;;
|
||||||
|
|
||||||
|
if (sampleLen <= red_info->parameters.threshold_min) {
|
||||||
|
//Can be added to queue without any RED operation
|
||||||
|
red_info->count = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sampleLen > red_info->parameters.threshold_max) {
|
||||||
|
//Always drop over threshold_max
|
||||||
|
red_info->count = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate probability for packet drop
|
||||||
|
// tempP = drop_maX_P *(AQ - threshold_min) / (threshold_max - threshold_min);
|
||||||
|
uint32_t tempP = (uint32_t) red_info->parameters.drop_maX_P * PROB_SCALE
|
||||||
|
* (sampleLen - red_info->parameters.threshold_min)
|
||||||
|
/ (red_info->parameters.threshold_max - red_info->parameters.threshold_min);
|
||||||
|
|
||||||
|
// Next Prob = tempP / (1 - count*tempP)
|
||||||
|
// This will increase probability and
|
||||||
|
|
||||||
|
//Calculate first divider part
|
||||||
|
uint32_t Prob = red_info->count * tempP;
|
||||||
|
|
||||||
|
//Check that divider it is not >= 0
|
||||||
|
if (Prob >= PROB_SCALE_MAX) {
|
||||||
|
|
||||||
|
red_info->count = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Calculate only when count * tempP is smaller than scaler
|
||||||
|
Prob = (tempP * PROB_SCALE_MAX) / (PROB_SCALE_MAX - Prob);
|
||||||
|
if (Prob > randLIB_get_random_in_range(0, PROX_MAX_RANDOM)) {
|
||||||
|
//Drop packet
|
||||||
|
red_info->count = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Increment count next round check
|
||||||
|
red_info->count++;
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, 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 SERVICE_LIBS_RANDOM_EARLY_DETECTION_RANDOM_EARLY_DETECTION_H_
|
||||||
|
#define SERVICE_LIBS_RANDOM_EARLY_DETECTION_RANDOM_EARLY_DETECTION_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//This value cant be bigger than 655
|
||||||
|
#define PROB_SCALE 512
|
||||||
|
#define PROB_SCALE_MAX PROB_SCALE * 100
|
||||||
|
#define PROX_MAX_RANDOM PROB_SCALE_MAX-1
|
||||||
|
|
||||||
|
typedef struct red_config_s {
|
||||||
|
uint16_t weight; /*< Weight for new sample len, 256 disabled average */
|
||||||
|
uint16_t threshold_min; /*< Threshold Min value which start possibility start drop a packet */
|
||||||
|
uint16_t threshold_max; /*< Threshold Max this value give max Probability for configured value over that every new packet will be dropped*/
|
||||||
|
uint8_t drop_maX_P; /*< Max probability for drop packet between threshold_min and threshold_max threshold */
|
||||||
|
} red_config_t;
|
||||||
|
|
||||||
|
typedef struct red_info_s {
|
||||||
|
red_config_t parameters; /*< Random Early detetction parameters for queue avarge and packet drop */
|
||||||
|
uint32_t averageQ; /*< Average queue size Scaled by 256 1.0 is 256 */
|
||||||
|
uint16_t count; /*< Missed Packet drop's. This value is incremented when average queue is over min threshoild and packet is noot dropped */
|
||||||
|
} red_info_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SERVICE_LIBS_RANDOM_EARLY_DETECTION_RANDOM_EARLY_DETECTION_H_ */
|
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, 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 SERVICE_LIBS_RANDOM_EARLY_DETECTION_RANDOM_EARLY_DETECTION_API_H_
|
||||||
|
#define SERVICE_LIBS_RANDOM_EARLY_DETECTION_RANDOM_EARLY_DETECTION_API_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct red_info_s;
|
||||||
|
|
||||||
|
#define RED_AVERAGE_WEIGHT_DISABLED 256 /*< Average is disabled */
|
||||||
|
#define RED_AVERAGE_WEIGHT_HALF 128 /*< Average weight for new sample is 0.5*new + 0.5 to last one */
|
||||||
|
#define RED_AVERAGE_WEIGHT_QUARTER 64 /*< Average weight for new sample is 1/4 + 3/4 to last one */
|
||||||
|
#define RED_AVERAGE_WEIGHT_EIGHTH 32 /*< Average weight for new sample is 1/8 + 7/8 to last one */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Create Random early detection data
|
||||||
|
*
|
||||||
|
* Function will config parameters how wide are Random Early detection drop will work.
|
||||||
|
*
|
||||||
|
* How to use parameters:
|
||||||
|
*
|
||||||
|
* Weight is definition how message queue Average (AQ) is calculated. Smaller weight will give smoother AQ update.
|
||||||
|
*
|
||||||
|
* AQ = (1-weight) * average_queue + weight*sampleLen;
|
||||||
|
*
|
||||||
|
* * RED_AVERAGE_WEIGHT_DISABLED disable Average by max weight to new sample length
|
||||||
|
* * RED_AVERAGE_WEIGHT_HALF last average*0.5 + 0.5*new sample: Smooth Average light packet filter
|
||||||
|
* * RED_AVERAGE_WEIGHT_QUARTER last average*0.75 + 0.25*new sample: Medium packet burst filtering
|
||||||
|
* * RED_AVERAGE_WEIGHT_EIGHTH last average*7/8 + 1/8*new sample: Good for filtering packet burst and big networks
|
||||||
|
*
|
||||||
|
* How to configure packet drop possibility:
|
||||||
|
*
|
||||||
|
* Define base Probability based current AQ, average length
|
||||||
|
*
|
||||||
|
* tempP = drop_maX_P *(AQ - threshold_min) / (threshold_max - threshold_min);
|
||||||
|
*
|
||||||
|
* Prob = tempP / (1 - count*tempP)
|
||||||
|
*
|
||||||
|
* threshold_min and threshold_max threshold define area for random early detection drop. When Average queue size go over Min threshold packet may drop by given maxProbability.
|
||||||
|
* System will work smoother if min -max threshold range is wide. Then random drop is may cover small data burst until Max threshold Avarage is reached.
|
||||||
|
* After Max every new packet will be dropped.
|
||||||
|
*
|
||||||
|
* Config Examples.
|
||||||
|
*
|
||||||
|
* Threshold values must be set how much device can buffer data.
|
||||||
|
*
|
||||||
|
* Small size data buffering:
|
||||||
|
* random_early_detection_create(32, 96, 10, RED_AVERAGE_WEIGHT_QUARTER)
|
||||||
|
*
|
||||||
|
* Medium size data buffering:
|
||||||
|
* random_early_detection_create(96, 256, 10, RED_AVERAGE_WEIGHT_EIGHTH)
|
||||||
|
*
|
||||||
|
* High size buffering:
|
||||||
|
* random_early_detection_create(256, 600, 10, RED_AVERAGE_WEIGHT_EIGHTH)
|
||||||
|
*
|
||||||
|
* \param threshold_min min average queue size which enable packet drop
|
||||||
|
* \param threshold_max average queue size when all new packets start drop
|
||||||
|
* \param drop_maX_P is percent probability to drop packet 100-1 are possible values
|
||||||
|
* \param weight accepted values 256-1, 256 is 1.0 weight which mean that new queue size overwrite old. 128 is 0.5 which gives 0.5 from old + 0.5 from new.
|
||||||
|
* \return Pointer for allocated structure, NULL if memory allocation fail
|
||||||
|
*/
|
||||||
|
struct red_info_s *random_early_detection_create(uint16_t threshold_min, uint16_t threshold_max, uint8_t drop_maX_P, uint16_t weight);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Free Random early detection data
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \param red_info pointer to data
|
||||||
|
*/
|
||||||
|
void random_early_detection_free(struct red_info_s *red_info);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Random early detection drop function
|
||||||
|
*
|
||||||
|
* \param red_info pointer, which is created user include all configurations
|
||||||
|
* \param sampleLen Current queue length
|
||||||
|
* \return true Drop packet
|
||||||
|
* \return false Packet can be added to queue
|
||||||
|
*/
|
||||||
|
bool random_early_detection_congestion_check(struct red_info_s *red_info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Random early detection Average queue calculate
|
||||||
|
*
|
||||||
|
* Call this when add or remove from queue
|
||||||
|
*
|
||||||
|
* \param red_info pointer, which is created user include all configurations
|
||||||
|
* \param sampleLen Current queue length
|
||||||
|
*
|
||||||
|
* \return New average
|
||||||
|
*/
|
||||||
|
uint16_t random_early_detetction_aq_calc(struct red_info_s *red_info, uint16_t sampleLen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Read Random early detection Average queue size
|
||||||
|
*
|
||||||
|
* Call this when add or remove from queue
|
||||||
|
*
|
||||||
|
* \param red_info pointer, which is created user include all configurations
|
||||||
|
*
|
||||||
|
* \return Current average
|
||||||
|
*/
|
||||||
|
uint16_t random_early_detetction_aq_read(struct red_info_s *red_info);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SERVICE_LIBS_RANDOM_EARLY_DETECTION_RANDOM_EARLY_DETECTION_API_H_ */
|
|
@ -29,9 +29,10 @@
|
||||||
#include "socket_api.h"
|
#include "socket_api.h"
|
||||||
#include "net_interface.h"
|
#include "net_interface.h"
|
||||||
#include "common_functions.h"
|
#include "common_functions.h"
|
||||||
|
|
||||||
#include "libDHCPv6/libDHCPv6.h"
|
#include "libDHCPv6/libDHCPv6.h"
|
||||||
#include "NWK_INTERFACE/Include/protocol.h" // just for protocol_core_monotonic_time
|
#include "NWK_INTERFACE/Include/protocol.h" // just for protocol_core_monotonic_time
|
||||||
|
#include "Common_Protocols/ip.h"
|
||||||
#include "dhcp_service_api.h"
|
#include "dhcp_service_api.h"
|
||||||
#ifdef HAVE_DHCPV6
|
#ifdef HAVE_DHCPV6
|
||||||
#define TRACE_GROUP "dhcp"
|
#define TRACE_GROUP "dhcp"
|
||||||
|
@ -437,7 +438,7 @@ void recv_dhcp_relay_msg(void *cb_res)
|
||||||
uint8_t *ptr = msg_iov[1].iov_base;
|
uint8_t *ptr = msg_iov[1].iov_base;
|
||||||
uint8_t msg_type = *ptr;
|
uint8_t msg_type = *ptr;
|
||||||
|
|
||||||
|
int16_t tc = 0;
|
||||||
if (msg_type == DHCPV6_RELAY_FORWARD) {
|
if (msg_type == DHCPV6_RELAY_FORWARD) {
|
||||||
tr_error("Drop not supported DHCPv6 forward at Agent");
|
tr_error("Drop not supported DHCPv6 forward at Agent");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -497,7 +498,10 @@ void recv_dhcp_relay_msg(void *cb_res)
|
||||||
msg_iov[0].iov_len = 38;
|
msg_iov[0].iov_len = 38;
|
||||||
msg_iov[1].iov_len = msg_len;
|
msg_iov[1].iov_len = msg_len;
|
||||||
tr_debug("Forward Client msg to server");
|
tr_debug("Forward Client msg to server");
|
||||||
|
tc = IP_DSCP_CS6 << IP_TCLASS_DSCP_SHIFT;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
socket_setsockopt(sckt_data->socket_id, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_TCLASS, &tc, sizeof(tc));
|
||||||
socket_sendmsg(sckt_data->socket_id, &msghdr, NS_MSG_LEGACY0);
|
socket_sendmsg(sckt_data->socket_id, &msghdr, NS_MSG_LEGACY0);
|
||||||
cleanup:
|
cleanup:
|
||||||
ns_dyn_mem_free(msg_iov[1].iov_base);
|
ns_dyn_mem_free(msg_iov[1].iov_base);
|
||||||
|
@ -845,6 +849,8 @@ void dhcp_service_send_message(msg_tr_t *msg_tr_ptr)
|
||||||
|
|
||||||
if (msg_tr_ptr->relay_start) {
|
if (msg_tr_ptr->relay_start) {
|
||||||
//Build Relay Reply only server do this
|
//Build Relay Reply only server do this
|
||||||
|
int16_t tc = IP_DSCP_CS6 << IP_TCLASS_DSCP_SHIFT;
|
||||||
|
socket_setsockopt(msg_tr_ptr->socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_TCLASS, &tc, sizeof(tc));
|
||||||
ns_iovec_t data_vector[2];
|
ns_iovec_t data_vector[2];
|
||||||
ns_msghdr_t msghdr;
|
ns_msghdr_t msghdr;
|
||||||
memcpy(msg_tr_ptr->addr.address, msg_tr_ptr->relay_start + 2, 16);
|
memcpy(msg_tr_ptr->addr.address, msg_tr_ptr->relay_start + 2, 16);
|
||||||
|
@ -872,6 +878,8 @@ void dhcp_service_send_message(msg_tr_t *msg_tr_ptr)
|
||||||
retval = socket_sendmsg(msg_tr_ptr->socket, &msghdr, NS_MSG_LEGACY0);
|
retval = socket_sendmsg(msg_tr_ptr->socket, &msghdr, NS_MSG_LEGACY0);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
int16_t tc = 0;
|
||||||
|
socket_setsockopt(msg_tr_ptr->socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_TCLASS, &tc, sizeof(tc));
|
||||||
retval = socket_sendto(msg_tr_ptr->socket, &msg_tr_ptr->addr, msg_tr_ptr->msg_ptr, msg_tr_ptr->msg_len);
|
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) {
|
||||||
|
|
|
@ -165,6 +165,7 @@ SRCS += \
|
||||||
source/Service_Libs/Trickle/trickle.c \
|
source/Service_Libs/Trickle/trickle.c \
|
||||||
source/Service_Libs/whiteboard/whiteboard.c \
|
source/Service_Libs/whiteboard/whiteboard.c \
|
||||||
source/Service_Libs/pan_blacklist/pan_blacklist.c \
|
source/Service_Libs/pan_blacklist/pan_blacklist.c \
|
||||||
|
source/Service_Libs/random_early_detection/random_early_detection.c \
|
||||||
source/6LoWPAN/Thread/thread_management_if.c \
|
source/6LoWPAN/Thread/thread_management_if.c \
|
||||||
source/6LoWPAN/Thread/thread_management_api.c \
|
source/6LoWPAN/Thread/thread_management_api.c \
|
||||||
source/6LoWPAN/Thread/thread_commissioning_api.c \
|
source/6LoWPAN/Thread/thread_commissioning_api.c \
|
||||||
|
|
Loading…
Reference in New Issue