|
20 | 20 | #ifdef HAVE_WS
|
21 | 21 | #include "ns_types.h"
|
22 | 22 | #include "ns_trace.h"
|
| 23 | +#include "nsdynmemLIB.h" |
23 | 24 | #include "net_interface.h"
|
24 | 25 | #include "eventOS_event.h"
|
25 | 26 | #include "randLIB.h"
|
|
76 | 77 | #include "6LoWPAN/ws/ws_eapol_auth_relay.h"
|
77 | 78 | #include "6LoWPAN/ws/ws_eapol_relay.h"
|
78 | 79 | #include "libNET/src/net_dns_internal.h"
|
| 80 | +#include "Service_Libs/random_early_detection/random_early_detection_api.h" |
79 | 81 |
|
80 | 82 | #define TRACE_GROUP "wsbs"
|
81 | 83 |
|
@@ -112,6 +114,7 @@ static int8_t ws_bootstrap_neighbor_set(protocol_interface_info_entry_t *cur, pa
|
112 | 114 | static void ws_bootstrap_candidate_table_reset(protocol_interface_info_entry_t *cur);
|
113 | 115 | static parent_info_t *ws_bootstrap_candidate_parent_get(struct protocol_interface_info_entry *cur, const uint8_t *addr, bool create);
|
114 | 116 | static void ws_bootstrap_candidate_parent_sort(struct protocol_interface_info_entry *cur, parent_info_t *new_entry);
|
| 117 | +static void ws_bootstrap_packet_congestion_init(protocol_interface_info_entry_t *cur); |
115 | 118 |
|
116 | 119 | typedef enum {
|
117 | 120 | WS_PARENT_SOFT_SYNCH = 0, /**< let FHSS make decision if synchronization is needed*/
|
@@ -3310,6 +3313,8 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
|
3310 | 3313 |
|
3311 | 3314 | // All trickle timers stopped to allow entry from any state
|
3312 | 3315 | ws_bootstrap_asynch_trickle_stop(cur);
|
| 3316 | + //Init Packet congestion |
| 3317 | + ws_bootstrap_packet_congestion_init(cur); |
3313 | 3318 |
|
3314 | 3319 | if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
|
3315 | 3320 | tr_info("Border router start network");
|
@@ -3799,4 +3804,78 @@ int ws_bootstrap_get_info(protocol_interface_info_entry_t *cur, struct ws_stack_
|
3799 | 3804 | return 0;
|
3800 | 3805 | }
|
3801 | 3806 |
|
| 3807 | +//Calculate max_packet queue size |
| 3808 | +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) |
| 3809 | +{ |
| 3810 | + uint32_t max_packet_count = 0; |
| 3811 | + if (heap_total_size) { |
| 3812 | + //Claculate how many packet can be max queue to half of heap |
| 3813 | + max_packet_count = (heap_total_size / 2) / packet_size; |
| 3814 | + } |
| 3815 | + |
| 3816 | + //Calculate how many packet is possible to queue for guarantee given max delay |
| 3817 | + uint32_t max_delayded_queue_size = max_delay * packet_per_seconds; |
| 3818 | + |
| 3819 | + if (max_packet_count > max_delayded_queue_size) { |
| 3820 | + //Limit queue size by MAX delay |
| 3821 | + max_packet_count = max_delayded_queue_size; |
| 3822 | + } |
| 3823 | + |
| 3824 | + if (max_packet_count > max_packet_queue_size) { |
| 3825 | + //Limit queue size by Max |
| 3826 | + max_packet_count = max_packet_queue_size; |
| 3827 | + } else if (max_packet_count < min_packet_queue_size) { |
| 3828 | + //Limit queue size by Min |
| 3829 | + max_packet_count = min_packet_queue_size; |
| 3830 | + } |
| 3831 | + return (uint16_t)max_packet_count; |
| 3832 | +} |
| 3833 | + |
| 3834 | +static uint16_t ws_bootstrap_packet_per_seconds(protocol_interface_info_entry_t *cur, uint16_t packet_size) |
| 3835 | +{ |
| 3836 | + uint32_t data_rate = ws_common_datarate_get(cur); |
| 3837 | + |
| 3838 | + //calculate how many packet is possible send in paper |
| 3839 | + data_rate /= 8 * packet_size; |
| 3840 | + |
| 3841 | + //Divide optimal by / 5 because we split TX / RX slots and BC schedule |
| 3842 | + //With Packet size 500 it should return |
| 3843 | + //Return 15 for 300kBits |
| 3844 | + //Return 7 for 150kBits |
| 3845 | + //Return 2 for 50kBits |
| 3846 | + return data_rate / 5; |
| 3847 | +} |
| 3848 | + |
| 3849 | + |
| 3850 | + |
| 3851 | +static void ws_bootstrap_packet_congestion_init(protocol_interface_info_entry_t *cur) |
| 3852 | +{ |
| 3853 | + random_early_detection_free(cur->random_early_detection); |
| 3854 | + cur->random_early_detection = NULL; |
| 3855 | + |
| 3856 | + //TODO implement API for HEAP info request |
| 3857 | + uint32_t heap_size; |
| 3858 | + const mem_stat_t *mem_stats = ns_dyn_mem_get_mem_stat(); |
| 3859 | + if (mem_stats) { |
| 3860 | + heap_size = mem_stats->heap_sector_size; |
| 3861 | + } else { |
| 3862 | + heap_size = 0; |
| 3863 | + } |
| 3864 | + |
| 3865 | + uint16_t packet_per_seconds = ws_bootstrap_packet_per_seconds(cur, WS_CONGESTION_PACKET_SIZE); |
| 3866 | + |
| 3867 | + uint16_t min_th, max_th; |
| 3868 | + |
| 3869 | + if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { |
| 3870 | + 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); |
| 3871 | + } else { |
| 3872 | + 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); |
| 3873 | + } |
| 3874 | + |
| 3875 | + min_th = max_th / 2; |
| 3876 | + 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); |
| 3877 | + cur->random_early_detection = random_early_detection_create(min_th, max_th, WS_CONGESTION_RED_DROP_PROBABILITY, RED_AVERAGE_WEIGHT_EIGHTH); |
| 3878 | + |
| 3879 | +} |
| 3880 | + |
3802 | 3881 | #endif //HAVE_WS
|
0 commit comments