40
40
#include "6LoWPAN/IPHC_Decode/iphc_decompress.h"
41
41
#include "lowpan_adaptation_interface.h"
42
42
#include "MLE/mle.h"
43
+ #include "Service_Libs/mle_service/mle_service_api.h"
44
+ #include "Common_Protocols/icmpv6.h"
43
45
#ifdef HAVE_RPL
44
46
#include "RPL/rpl_data.h"
45
47
#endif
@@ -787,49 +789,110 @@ static fragmenter_tx_entry_t *lowpan_adaptation_indirect_first_cached_request_ge
787
789
return NULL ;
788
790
}
789
791
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 )
791
824
{
792
825
if (interface_ptr -> max_indirect_small_packets_per_child == 0 ) {
793
- return ;
826
+ return false ;
794
827
}
795
828
796
829
uint_fast16_t count = 0 ;
830
+ fragmenter_tx_entry_t * low_priority_msg_ptr = NULL ;
797
831
798
832
ns_list_foreach_reverse_safe (fragmenter_tx_entry_t , tx_entry , & interface_ptr -> indirect_tx_queue ) {
799
833
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 );
800
834
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
+ }
801
839
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) {
804
850
/* entry could not be purged from mac, try next entry */
805
851
tr_debug_extra ("Purge failed, try next" );
806
852
count -- ;
807
853
}
854
+ low_priority_msg_ptr = NULL ;
808
855
}
809
856
}
810
857
}
858
+ return true;
811
859
}
812
860
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 )
814
862
{
815
863
if (interface_ptr -> max_indirect_big_packets_total == 0 ) {
816
- return ;
864
+ return false ;
817
865
}
818
866
819
867
uint_fast16_t count = 0 ;
868
+ fragmenter_tx_entry_t * low_priority_msg_ptr = NULL ;
820
869
821
870
ns_list_foreach_reverse_safe (fragmenter_tx_entry_t , tx_entry , & interface_ptr -> indirect_tx_queue ) {
822
871
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
+ }
823
876
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" );
827
888
/* entry could not be purged from mac, try next entry */
828
889
count -- ;
829
890
}
891
+ low_priority_msg_ptr = NULL ;
830
892
}
831
893
}
832
894
}
895
+ return true;
833
896
}
834
897
835
898
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
868
931
869
932
int8_t lowpan_adaptation_interface_tx (protocol_interface_info_entry_t * cur , buffer_t * buf )
870
933
{
934
+ bool is_room_for_new_message ;
871
935
if (!buf ) {
872
936
return -1 ;
873
937
}
@@ -940,9 +1004,9 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
940
1004
941
1005
// Make room for new message if needed */
942
1006
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 );
944
1008
} 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 );
946
1010
}
947
1011
948
1012
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
951
1015
tx_ptr -> indirect_data_cached = true;
952
1016
}
953
1017
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
+ }
955
1027
956
1028
// Check if current message can be delivered to MAC or should some cached message be delivered first
957
1029
tx_ptr_cached = lowpan_adaptation_indirect_first_cached_request_get (interface_ptr , tx_ptr );
0 commit comments