Skip to content

Commit d46d7b3

Browse files
Prioritise thread control messages (ARMmbed#1984)
1 parent e59dbd8 commit d46d7b3

File tree

3 files changed

+111
-13
lines changed

3 files changed

+111
-13
lines changed

source/6LoWPAN/Thread/thread_config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@
247247
* value for better performance.
248248
*/
249249
#define THREAD_INDIRECT_BIG_PACKETS_TOTAL 10
250-
#define THREAD_INDIRECT_SMALL_PACKETS_PER_CHILD 2
250+
#define THREAD_INDIRECT_SMALL_PACKETS_PER_CHILD 3
251251

252252
/**
253253
* Maximum number of MTD children, default 16

source/6LoWPAN/adaptation_interface.c

Lines changed: 84 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
#include "6LoWPAN/IPHC_Decode/iphc_decompress.h"
4141
#include "lowpan_adaptation_interface.h"
4242
#include "MLE/mle.h"
43+
#include "Service_Libs/mle_service/mle_service_api.h"
44+
#include "Common_Protocols/icmpv6.h"
4345
#ifdef HAVE_RPL
4446
#include "RPL/rpl_data.h"
4547
#endif
@@ -787,49 +789,110 @@ static fragmenter_tx_entry_t *lowpan_adaptation_indirect_first_cached_request_ge
787789
return NULL;
788790
}
789791

790-
static void lowpan_adaptation_make_room_for_small_packet(protocol_interface_info_entry_t *cur, fragmenter_interface_t *interface_ptr, mac_neighbor_table_entry_t *neighbour_to_count)
792+
static bool lowpan_adaptation_is_priority_message(buffer_t *buf)
793+
{
794+
// Mle messages
795+
if (buf->dst_sa.port == MLE_ALLOCATED_PORT || buf->src_sa.port == MLE_ALLOCATED_PORT) {
796+
return true;
797+
}
798+
799+
// Management messages: address solicit, response, query, notification
800+
if (buf->dst_sa.port == THREAD_MANAGEMENT_PORT || buf->src_sa.port == THREAD_MANAGEMENT_PORT) {
801+
return true;
802+
}
803+
804+
// dhcp messages
805+
if (buf->dst_sa.port == DHCPV6_SERVER_PORT || buf->src_sa.port == DHCPV6_SERVER_PORT) {
806+
return true;
807+
}
808+
809+
if (buf->dst_sa.port == DHCPV6_CLIENT_PORT || buf->src_sa.port == DHCPV6_CLIENT_PORT) {
810+
return true;
811+
}
812+
813+
// ICMPv6 messages
814+
if (buf->options.type == ICMPV6_TYPE_ERROR_DESTINATION_UNREACH ||
815+
buf->options.type == ICMPV6_TYPE_ERROR_PACKET_TOO_BIG ||
816+
buf->options.type == ICMPV6_TYPE_ERROR_TIME_EXCEEDED ||
817+
buf->options.type == ICMPV6_TYPE_ERROR_PARAMETER_PROBLEM) {
818+
return true;
819+
}
820+
return false;
821+
}
822+
823+
static bool lowpan_adaptation_make_room_for_small_packet(protocol_interface_info_entry_t *cur, fragmenter_interface_t *interface_ptr, mac_neighbor_table_entry_t *neighbour_to_count, fragmenter_tx_entry_t *new_entry)
791824
{
792825
if (interface_ptr->max_indirect_small_packets_per_child == 0) {
793-
return;
826+
return false;
794827
}
795828

796829
uint_fast16_t count = 0;
830+
fragmenter_tx_entry_t *low_priority_msg_ptr = NULL;
797831

798832
ns_list_foreach_reverse_safe(fragmenter_tx_entry_t, tx_entry, &interface_ptr->indirect_tx_queue) {
799833
mac_neighbor_table_entry_t *tx_neighbour = mac_neighbor_table_address_discover(mac_neighbor_info(cur), tx_entry->buf->dst_sa.address + 2, tx_entry->buf->dst_sa.addr_type);
800834
if (tx_neighbour == neighbour_to_count && buffer_data_length(tx_entry->buf) <= interface_ptr->indirect_big_packet_threshold) {
835+
if (!lowpan_adaptation_is_priority_message(tx_entry->buf)) {
836+
// if there is sub priorities inside message example age here you could compare
837+
low_priority_msg_ptr = tx_entry;
838+
}
801839
if (++count >= interface_ptr->max_indirect_small_packets_per_child) {
802-
tr_debug_extra("Purge seq: %d", tx_entry->buf->seq);
803-
if (lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, tx_entry) == false) {
840+
if (!low_priority_msg_ptr) {
841+
// take last entry if no low priority entry found
842+
if (lowpan_adaptation_is_priority_message(new_entry->buf)) {
843+
low_priority_msg_ptr = tx_entry;
844+
} else {
845+
return false;
846+
}
847+
}
848+
tr_debug_extra("Purge seq: %d", low_priority_msg_ptr->buf->seq);
849+
if (lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, low_priority_msg_ptr) == false) {
804850
/* entry could not be purged from mac, try next entry */
805851
tr_debug_extra("Purge failed, try next");
806852
count--;
807853
}
854+
low_priority_msg_ptr = NULL;
808855
}
809856
}
810857
}
858+
return true;
811859
}
812860

813-
static void lowpan_adaptation_make_room_for_big_packet(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr)
861+
static bool lowpan_adaptation_make_room_for_big_packet(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *new_entry)
814862
{
815863
if (interface_ptr->max_indirect_big_packets_total == 0) {
816-
return;
864+
return false;
817865
}
818866

819867
uint_fast16_t count = 0;
868+
fragmenter_tx_entry_t *low_priority_msg_ptr = NULL;
820869

821870
ns_list_foreach_reverse_safe(fragmenter_tx_entry_t, tx_entry, &interface_ptr->indirect_tx_queue) {
822871
if (buffer_data_length(tx_entry->buf) > interface_ptr->indirect_big_packet_threshold) {
872+
if (!lowpan_adaptation_is_priority_message(tx_entry->buf)) {
873+
// if there is sub priorities inside message example age here you could compare
874+
low_priority_msg_ptr = tx_entry;
875+
}
823876
if (++count >= interface_ptr->max_indirect_big_packets_total) {
824-
tr_debug_extra("Purge seq: %d", tx_entry->buf->seq);
825-
if (lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, tx_entry) == false) {
826-
tr_debug("Purge failed, try next entry");
877+
if (!low_priority_msg_ptr) {
878+
// take last entry if no low priority entry found
879+
if (lowpan_adaptation_is_priority_message(new_entry->buf)) {
880+
low_priority_msg_ptr = tx_entry;
881+
} else {
882+
return false;
883+
}
884+
}
885+
tr_debug_extra("Purge seq: %d", low_priority_msg_ptr->buf->seq);
886+
if (lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, low_priority_msg_ptr) == false) {
887+
tr_debug_extra("Purge failed, try next entry");
827888
/* entry could not be purged from mac, try next entry */
828889
count--;
829890
}
891+
low_priority_msg_ptr = NULL;
830892
}
831893
}
832894
}
895+
return true;
833896
}
834897

835898
static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_tx_entry_t *tx_ptr, fragmenter_interface_t *interface_ptr)
@@ -868,6 +931,7 @@ static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buf
868931

869932
int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buffer_t *buf)
870933
{
934+
bool is_room_for_new_message;
871935
if (!buf) {
872936
return -1;
873937
}
@@ -940,9 +1004,9 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
9401004

9411005
// Make room for new message if needed */
9421006
if (buffer_data_length(buf) <= interface_ptr->indirect_big_packet_threshold) {
943-
lowpan_adaptation_make_room_for_small_packet(cur, interface_ptr, neigh_entry_ptr);
1007+
is_room_for_new_message = lowpan_adaptation_make_room_for_small_packet(cur, interface_ptr, neigh_entry_ptr, tx_ptr);
9441008
} else {
945-
lowpan_adaptation_make_room_for_big_packet(cur, interface_ptr);
1009+
is_room_for_new_message = lowpan_adaptation_make_room_for_big_packet(cur, interface_ptr, tx_ptr);
9461010
}
9471011

9481012
if (lowpan_adaptation_indirect_mac_data_request_active(interface_ptr, tx_ptr)) {
@@ -951,7 +1015,15 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
9511015
tx_ptr->indirect_data_cached = true;
9521016
}
9531017

954-
ns_list_add_to_end(&interface_ptr->indirect_tx_queue, tx_ptr);
1018+
if (is_room_for_new_message) {
1019+
ns_list_add_to_end(&interface_ptr->indirect_tx_queue, tx_ptr);
1020+
} else {
1021+
if (tx_ptr->fragmenter_buf) {
1022+
ns_dyn_mem_free(tx_ptr->fragmenter_buf);
1023+
}
1024+
ns_dyn_mem_free(tx_ptr);
1025+
goto tx_error_handler;
1026+
}
9551027

9561028
// Check if current message can be delivered to MAC or should some cached message be delivered first
9571029
tx_ptr_cached = lowpan_adaptation_indirect_first_cached_request_get(interface_ptr, tx_ptr);

test/nanostack/unittest/6LoWPAN/adaptation_interface/test_adaptation_interface.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,19 @@ bool test_lowpan_adaptation_interface_reset()
134134
buf.buf_ptr = 10;
135135
buf.buf_end = 80;
136136

137+
137138
if (-1 != lowpan_adaptation_interface_reset(0)) {
138139
return false;
139140
}
140141

141142
nsdynmemlib_stub.returnCounter = 2;
142143
lowpan_adaptation_interface_init(0, 127);
143144

145+
// Set small and big buffer size to 2
146+
if (0 != lowpan_adaptation_indirect_queue_params_set(&entry, 106, 2, 2)) {
147+
return false;
148+
}
149+
144150
//Set 2 direct and 2 indirect buffer
145151
buf.link_specific.ieee802_15_4.indirectTxProcess = false;
146152
lowpan_adaptation_interface_tx(&entry, &buf);
@@ -297,10 +303,17 @@ bool test_lowpan_adaptation_indirect_purge()
297303
entry.id = 0;
298304
api.mcps_data_req = &mcps_data_req_cb;
299305

306+
307+
300308
//Test Indirect data allocation fail
301309
nsdynmemlib_stub.returnCounter = 2;
302310
lowpan_adaptation_interface_init(0, 127);
303311

312+
// Set small and big buffer size to 2
313+
if (0 != lowpan_adaptation_indirect_queue_params_set(&entry, 106, 2, 2)) {
314+
return false;
315+
}
316+
304317
test_buf->link_specific.ieee802_15_4.indirectTxProcess = true;
305318
nsdynmemlib_stub.returnCounter = 2;
306319
if (0 != lowpan_adaptation_interface_tx(&entry, test_buf)) {
@@ -784,6 +797,7 @@ bool test_lowpan_adaptation_interface_tx_confirm()
784797
buffer_t *test_buf = malloc(sizeof(buffer_t) + 2100);
785798
memset(test_buf, 0, sizeof(buffer_t) + 2100);
786799

800+
787801
entry.mac_parameters->mac_in_direct_entry_timeout = 14000;
788802
test_buf->link_specific.ieee802_15_4.useDefaultPanId = true;
789803
test_buf->dst_sa.addr_type = ADDR_802_15_4_SHORT;
@@ -819,6 +833,7 @@ bool test_lowpan_adaptation_interface_tx_confirm()
819833
entry.id = 0;
820834
api.mcps_data_req = &mcps_data_req_cb;
821835

836+
822837
if (-1 != lowpan_adaptation_interface_tx_confirm(NULL, &data_confirm)) {
823838
lowpan_adaptation_interface_free(0);
824839
free(test_buf);
@@ -853,6 +868,10 @@ bool test_lowpan_adaptation_interface_tx_confirm()
853868
return false;
854869
}
855870
test_buf2->ip_routed_up = true;
871+
// Set small and big buffer size to 2
872+
if (0 != lowpan_adaptation_indirect_queue_params_set(&entry, 106, 2, 2)) {
873+
return false;
874+
}
856875

857876
lowpan_adaptation_interface_tx(&entry, test_buf);
858877
lowpan_adaptation_interface_tx(&entry, test_buf2);
@@ -868,6 +887,7 @@ bool test_lowpan_adaptation_interface_tx_confirm()
868887
return false;
869888
}
870889

890+
871891
data_confirm.msduHandle = test_buf->seq;
872892
data_confirm.status = MLME_SUCCESS;
873893
if (0 != lowpan_adaptation_interface_tx_confirm(&entry, &data_confirm)) {
@@ -898,6 +918,7 @@ bool test_lowpan_adaptation_interface_tx_confirm()
898918
return false;
899919
}
900920

921+
901922
data_confirm.msduHandle = test_buf3->seq;
902923
data_confirm.status = MLME_TRANSACTION_EXPIRED;
903924
if (0 != lowpan_adaptation_interface_tx_confirm(&entry, &data_confirm)) {
@@ -1324,6 +1345,11 @@ bool test_lowpan_adaptation_interface_mpx_register()
13241345
entry.id = 0;
13251346
api.mcps_data_req = &mcps_data_req_cb;
13261347

1348+
// Set small and big buffer size to 2
1349+
if (0 != lowpan_adaptation_indirect_queue_params_set(&entry, 106, 2, 2)) {
1350+
return false;
1351+
}
1352+
13271353
test_buf2->ip_routed_up = true;
13281354
protocol_core_stub.entry_ptr = &entry;
13291355
lowpan_adaptation_interface_tx(&entry, test_buf);

0 commit comments

Comments
 (0)