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: 35b95da1226ebb070fdaeb3ec47fb82f48ff8fad
pull/14040/head
Arto Kinnunen 2020-12-14 10:31:07 +02:00
parent 04c21e779b
commit dad2952087
34 changed files with 735 additions and 98 deletions

View File

@ -73,6 +73,7 @@ typedef struct nwk_stats_t {
/* MAC */
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. */
uint32_t adapt_layer_tx_congestion_drop; /**< Adaptation layer direct TX randon early detection drop packet. */
} nwk_stats_t;
/**

View File

@ -175,6 +175,25 @@ typedef enum {
MODULATION_INDEX_UNDEFINED ///< Modulation index undefined
} 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
*
@ -192,6 +211,9 @@ typedef struct phy_rf_channel_configuration_s {
uint16_t number_of_channels; ///< Number of channels
phy_modulation_e modulation; ///< Modulation scheme
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;
/** Channel page configuration */

View File

@ -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_BB_WAIT 0x0004 /**< Wait backbone availability before starting Wi-SUN network */
#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 */
/**

View File

@ -799,15 +799,15 @@ bool protocol_6lowpan_latency_estimate_get(int8_t interface_id, uint32_t *latenc
if (cur_interface->eth_mac_api) {
// either PPP or Ethernet interface.
latency_estimate = 100;
latency_estimate = 1000;
} else if (thread_info(cur_interface)) {
// thread network
latency_estimate = 2000;
latency_estimate = 5000;
} else if (ws_info(cur_interface)) {
latency_estimate = ws_common_latency_estimate_get(cur_interface);
} else {
// 6LoWPAN ND
latency_estimate = 8000;
latency_estimate = 20000;
}
if (latency_estimate != 0) {

View File

@ -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? */
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) {
aro_out->present = true;
return true;

View File

@ -42,13 +42,14 @@
#include "MLE/mle.h"
#include "Service_Libs/mle_service/mle_service_api.h"
#include "Common_Protocols/icmpv6.h"
#include "Common_Protocols/ip.h"
#ifdef HAVE_RPL
#include "RPL/rpl_data.h"
#endif
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#include "6LoWPAN/Thread/thread_common.h"
#include "6LoWPAN/ws/ws_common.h"
#include "Service_Libs/random_early_detection/random_early_detection_api.h"
#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);
@ -60,6 +61,8 @@ typedef void (adaptation_etx_update_cb)(protocol_interface_info_entry_t *cur, bu
#define tr_debug_extra(...)
#endif
#define ADAPTION_DIRECT_TX_QUEUE_SIZE_THRESHOLD_TRACE 20
typedef struct {
uint16_t tag; /*!< Fragmentation datagram TAG ID */
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
buffer_list_t directTxQueue; //Waiting free tx process
uint16_t directTxQueue_size;
uint16_t directTxQueue_level;
uint16_t activeTxList_size;
uint16_t indirect_big_packet_threshold;
uint16_t max_indirect_big_packets_total;
uint16_t max_indirect_small_packets_per_child;
@ -103,6 +108,8 @@ typedef struct {
ns_list_link_t link; /*!< List link entry */
} fragmenter_interface_t;
#define LOWPAN_ACTIVE_UNICAST_ONGOING_MAX 10
static NS_LIST_DEFINE(fragmenter_interface_list, fragmenter_interface_t, link);
/* 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)
{
buffer_t *lower_priority_buf = NULL;
ns_list_foreach(buffer_t, cur, &interface_ptr->directTxQueue) {
if (cur->priority < buf->priority) {
lower_priority_buf = cur;
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);
}
interface_ptr->directTxQueue_size++;
lowpan_adaptation_tx_queue_level_update(interface_ptr);
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)) {
ns_list_remove(&interface_ptr->directTxQueue, buf);
interface_ptr->directTxQueue_size--;
lowpan_adaptation_tx_queue_level_update(interface_ptr);
protocol_stats_update(STATS_AL_TX_QUEUE_SIZE, interface_ptr->directTxQueue_size);
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->directTxQueue);
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);
@ -390,13 +413,15 @@ int8_t lowpan_adaptation_interface_free(int8_t interface_id)
ns_list_remove(&fragmenter_interface_list, interface_ptr);
//free active tx process
lowpan_list_free(&interface_ptr->activeUnicastList, false);
interface_ptr->activeTxList_size = 0;
lowpan_active_buffer_state_reset(&interface_ptr->active_broadcast_tx_buf);
//Free Indirect entry
lowpan_list_free(&interface_ptr->indirect_tx_queue, true);
buffer_free_list(&interface_ptr->directTxQueue);
interface_ptr->directTxQueue_size = 0;
interface_ptr->directTxQueue_level = 0;
//Free Dynamic allocated entries
ns_dyn_mem_free(interface_ptr->fragment_indirect_tx_buffer);
ns_dyn_mem_free(interface_ptr);
@ -415,6 +440,7 @@ int8_t lowpan_adaptation_interface_reset(int8_t interface_id)
//free active tx process
lowpan_list_free(&interface_ptr->activeUnicastList, false);
interface_ptr->activeTxList_size = 0;
lowpan_active_buffer_state_reset(&interface_ptr->active_broadcast_tx_buf);
//Clean fragmented message flag
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);
buffer_free_list(&interface_ptr->directTxQueue);
interface_ptr->directTxQueue_size = 0;
interface_ptr->directTxQueue_level = 0;
return 0;
}
@ -597,6 +625,7 @@ static fragmenter_tx_entry_t *lowpan_adaptation_tx_process_init(fragmenter_inter
return NULL;
}
ns_list_add_to_end(&interface_ptr->activeUnicastList, tx_entry);
interface_ptr->activeTxList_size++;
} else {
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) {
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
if (is_unicast && lowpan_adaptation_is_destination_tx_active(&interface_ptr->activeUnicastList, buf)) {
return false;
@ -992,6 +1028,18 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
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
bool fragmented_needed = lowpan_adaptation_request_longer_than_mtu(cur, buf, interface_ptr);
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;
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);
random_early_detetction_aq_calc(cur->random_early_detection, interface_ptr->directTxQueue_size);
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) {
ns_list_remove(&interface_ptr->activeUnicastList, tx_ptr);
ns_dyn_mem_free(tx_ptr);
interface_ptr->activeTxList_size--;
}
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);
return -1;
}
//Check status for
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;
}
switch (confirm->status) {
case MLME_BUSY_CHAN:
lowpan_data_request_to_mac(cur, buf, tx_ptr, interface_ptr);
break;
case MLME_SUCCESS:
if (confirm->status == MLME_SUCCESS) {
//Check is there more packets
if (lowpan_adaptation_tx_process_ready(tx_ptr)) {
bool triggered_from_indirect_cache = false;
if (tx_ptr->fragmented_data && active_direct_confirm) {
//Clean
interface_ptr->fragmenter_active = false;
}
@ -1256,12 +1308,15 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c
} else {
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);
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));
@ -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));
break;
}
// When confirmation is for direct transmission, push all allowed buffers to MAC
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);
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;
}
@ -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;
}

View File

@ -712,11 +712,13 @@ void ws_bbr_pan_version_increase(protocol_interface_info_entry_t *cur)
return;
}
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
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++;
// 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);
if (protocol_6lowpan_rpl_root_dodag &&
options != configuration) {
//Configuration changed delete previous setup
ws_bbr_routing_stop(cur);
if (options == configuration) {
return 0;
}
//Configuration changed
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;
#else
(void)interface_id;

View File

@ -20,6 +20,7 @@
#ifdef HAVE_WS
#include "ns_types.h"
#include "ns_trace.h"
#include "nsdynmemLIB.h"
#include "net_interface.h"
#include "eventOS_event.h"
#include "randLIB.h"
@ -43,6 +44,7 @@
#include "Common_Protocols/icmpv6.h"
#include "Common_Protocols/icmpv6_radv.h"
#include "Common_Protocols/ipv6_constants.h"
#include "Common_Protocols/ip.h"
#include "Service_Libs/Trickle/trickle.h"
#include "Service_Libs/fhss/channel_list.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_relay.h"
#include "libNET/src/net_dns_internal.h"
#include "Service_Libs/random_early_detection/random_early_detection_api.h"
#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 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_packet_congestion_init(protocol_interface_info_entry_t *cur);
typedef enum {
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);
if (neighbor && neighbor->link_lifetime != WS_NEIGHBOR_LINK_TIMEOUT) {
if (neighbor && neighbor->link_lifetime <= valid_time) {
//mlme_device_descriptor_t device_desc;
neighbor->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);
}
}
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)
{
//Send NS
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);
if (nud_process) {
tr_info("NUD generate NS %u", neighbor->index);
} else {
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) {
buffer->options.traffic_class = IP_DSCP_CS6 << IP_TCLASS_DSCP_SHIFT;
protocol_push(buffer);
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
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);
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;
ws_bootstrap_event_discovery_start(cur);
}
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)
{
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_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);
@ -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) {
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
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) {
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;
}
//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

View File

@ -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
*/
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->link_lifetime != WS_NEIGHBOR_LINK_TIMEOUT) {
if (mac_neighbor->link_lifetime < link_lifetime) {
//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);
}
mac_neighbor->link_lifetime = WS_NEIGHBOR_LINK_TIMEOUT;
}
//Refresh
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 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
if (test_max_child_count_override != 0xffff) {
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
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");
return ARO_SUCCESS;
}
@ -431,20 +444,21 @@ uint8_t ws_common_allow_child_registration(protocol_interface_info_entry_t *inte
return ARO_TOPOLOGICALLY_INCORRECT;
}
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)) {
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);
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);
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) {
// handles also NETWORK_SIZE_CERTIFICATE
latency = 4000;
latency = 5000;
} else if (network_size <= NETWORK_SIZE_MEDIUM) {
latency = 8000;
latency = 10000;
} else if (network_size <= NETWORK_SIZE_LARGE) {
latency = 16000;
latency = 20000;
} else {
latency = 24000;
latency = 30000;
}
return latency;

View File

@ -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);
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);
@ -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_neighbor_remove(cur, ll_address)
#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_latency_estimate_get(cur) 0
#define ws_common_datarate_get(cur) 0

View File

@ -144,9 +144,9 @@ extern uint8_t DEVICE_MIN_SENS;
#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
/*Medium network size*/
#define MPL_MEDIUM_IMIN 5
#define MPL_MEDIUM_IMAX 20
#define MPL_MEDIUM_EXPIRATIONS 2
#define MPL_MEDIUM_IMIN 1
#define MPL_MEDIUM_IMAX 32
#define MPL_MEDIUM_EXPIRATIONS 1
#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
/*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_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.
*

View File

@ -26,6 +26,7 @@
#include "mac_api.h"
#include "mac_mcps.h"
#include "Common_Protocols/ipv6_constants.h"
#include "Common_Protocols/ip.h"
#include "socket_api.h"
#include "6LoWPAN/MAC/mac_helper.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);
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);

View File

@ -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;
} else if (data->status == MLME_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);
}

View File

@ -26,6 +26,7 @@
#include "mac_api.h"
#include "mac_mcps.h"
#include "Common_Protocols/ipv6_constants.h"
#include "Common_Protocols/ip.h"
#include "socket_api.h"
#include "6LoWPAN/MAC/mac_helper.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);
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) {
ns_dyn_mem_free(eapol_relay);

View File

@ -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);
}
} 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
tr_debug("Remove Temp Entry by TX confirm");
mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), neighbor_info.neighbor);

View File

@ -1110,6 +1110,7 @@ buffer_t *icmpv6_up(buffer_t *buf)
|| (buf->options.type == ICMPV6_TYPE_INFO_RPL_CONTROL
&& (buf->options.code != ICMPV6_CODE_RPL_DIO
&& buf->options.code != ICMPV6_CODE_RPL_DIS))) {
tr_warn("Drop: ICMP EP unsecured packet");
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 */
/* Setting callback for receiving ACK from adaptation layer */
if (aro && cur->ipv6_neighbour_cache.omit_na_aro_success) {
if (aro->lifetime > 1) {
buf->ack_receive_cb = icmpv6_aro_cb;
} else {
buf->ack_receive_cb = ack_receive_cb;
}
}
}
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");
return buffer_free(buf);
}
buf->options.traffic_class = IP_DSCP_CS6 << IP_TCLASS_DSCP_SHIFT;
buf->ack_receive_cb = ack_remove_neighbour_cb;
}

View File

@ -1416,6 +1416,7 @@ buffer_t *ipv6_forwarding_up(buffer_t *buf)
#endif
default: {
if (buf->options.ll_security_bypass_rx) {
tr_warn("Drop: unsecured by BAD Next header %u", *nh_ptr);
goto bad_nh;
}
buffer_socket_set(buf, socket_lookup_ipv6(*nh_ptr, &buf->dst_sa, &buf->src_sa, true));

View File

@ -180,7 +180,9 @@ typedef enum {
typedef enum {
QOS_NORMAL = 0,
QOS_HIGH = 1,
QOS_MAC_BEACON = 2
QOS_NETWORK_CTRL = 2,
QOS_EXPEDITE_FORWARD = 3,
QOS_MAC_BEACON = 4
} buffer_priority_t;
#define B_TO_MAC_MLME_MASK (B_DIR_MASK + B_FROM_MASK + B_TO_MASK )

View File

@ -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("Modulation: %u", config_params->modulation);
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;
default:
return mac_mlme_handle_set_values(rf_mac_setup, set_req);

View File

@ -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);
while (mpl_total_buffered + ip_len > MAX_BUFFERED_MESSAGES_SIZE) {
tr_debug("MPL MAX buffered message size limit...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);
if (!message) {
tr_debug("No heap for new MPL message");
return NULL;
}
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);
buffer_t *buf = buffer_get(ip_len);
if (!buf) {
tr_debug("No heap for MPL transmit");
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);
if (!message) {
tr_debug("MPL Buffer Craete fail");
}
return true;
}

View File

@ -57,6 +57,7 @@ struct arm_device_driver_list;
struct mlme_security_s;
struct load_balance_api;
struct nwk_wpan_nvm_api;
struct red_info_s;
#define SLEEP_MODE_REQ 0x80
#define SLEEP_PERIOD_ACTIVE 0x40
@ -445,6 +446,7 @@ struct protocol_interface_info_entry {
struct auth_info *pana_sec_info_temp;
br_info_t *border_router_setup;
struct load_balance_api *lb_api;
struct red_info_s *random_early_detection;
neigh_cache_s neigh_cache;
pan_blaclist_cache_s pan_blaclist_cache;
pan_coordinator_blaclist_cache_s pan_cordinator_black_list;

View File

@ -44,7 +44,8 @@ typedef enum {
STATS_BUFFER_HEADROOM_FAIL,
STATS_ETX_1ST_PARENT,
STATS_ETX_2ND_PARENT,
STATS_AL_TX_QUEUE_SIZE
STATS_AL_TX_QUEUE_SIZE,
STATS_AL_TX_CONGESTION_DROP
} nwk_stats_type_t;

View File

@ -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;
}
break;
case STATS_AL_TX_CONGESTION_DROP:
nwk_stats_ptr->adapt_layer_tx_congestion_drop++;
break;
}
}
}

View File

@ -45,6 +45,7 @@
#include "NWK_INTERFACE/Include/protocol_stats.h"
#include "Common_Protocols/ipv6_constants.h"
#include "Common_Protocols/icmpv6.h"
#include "Common_Protocols/ip.h"
#include "ipv6_stack/protocol_ipv6.h"
#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 */
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) {
rpl_control_transmit_all_interfaces(domain, buf);

View File

@ -91,6 +91,7 @@
#include "Common_Protocols/icmpv6.h"
#include "NWK_INTERFACE/Include/protocol.h"
#include "ipv6_stack/ipv6_routing_table.h"
#include "Common_Protocols/ip.h"
#include "net_rpl.h"
#include "RPL/rpl_protocol.h"
@ -1874,6 +1875,7 @@ static bool rpl_instance_push_address_registration(protocol_interface_info_entry
if (!buf) {
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));
protocol_push(buf);
return true;

View File

@ -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 */
/* 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()) {
// 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)) {
return;
}

View File

@ -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;
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;
*radius_msg_ptr++ = RADIUS_ACCESS_REQUEST; // code

View File

@ -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)
{
int ret = -1;
int32_t ret = -1;
while (ret != MBEDTLS_ERR_SSL_WANT_READ) {
ret = mbedtls_ssl_handshake_step(&sec->ssl);
@ -428,6 +428,7 @@ int8_t tls_sec_prot_lib_process(tls_security_t *sec)
#endif
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;
}

View File

@ -604,9 +604,14 @@ static int fhss_ws_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_a
if (!fhss_structure) {
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;
}
// 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
if (!is_broadcast_addr && (fhss_structure->ws->is_on_bc_channel == true)) {
return -1;

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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_ */

View File

@ -29,9 +29,10 @@
#include "socket_api.h"
#include "net_interface.h"
#include "common_functions.h"
#include "libDHCPv6/libDHCPv6.h"
#include "NWK_INTERFACE/Include/protocol.h" // just for protocol_core_monotonic_time
#include "Common_Protocols/ip.h"
#include "dhcp_service_api.h"
#ifdef HAVE_DHCPV6
#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 msg_type = *ptr;
int16_t tc = 0;
if (msg_type == DHCPV6_RELAY_FORWARD) {
tr_error("Drop not supported DHCPv6 forward at Agent");
goto cleanup;
@ -497,7 +498,10 @@ void recv_dhcp_relay_msg(void *cb_res)
msg_iov[0].iov_len = 38;
msg_iov[1].iov_len = msg_len;
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);
cleanup:
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) {
//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_msghdr_t msghdr;
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);
} 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);
}
if (retval != 0) {

View File

@ -165,6 +165,7 @@ SRCS += \
source/Service_Libs/Trickle/trickle.c \
source/Service_Libs/whiteboard/whiteboard.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_api.c \
source/6LoWPAN/Thread/thread_commissioning_api.c \