@@ -128,8 +128,8 @@ static NS_LIST_DEFINE(fragmenter_interface_list, fragmenter_interface_t, link);
128
128
static fragmenter_interface_t * lowpan_adaptation_interface_discover (int8_t interfaceId );
129
129
130
130
/* Interface direct message pending queue functions */
131
- static void lowpan_adaptation_tx_queue_write (fragmenter_interface_t * interface_ptr , buffer_t * buf );
132
- static buffer_t * lowpan_adaptation_tx_queue_read (fragmenter_interface_t * interface_ptr );
131
+ static void lowpan_adaptation_tx_queue_write (protocol_interface_info_entry_t * cur , fragmenter_interface_t * interface_ptr , buffer_t * buf );
132
+ static buffer_t * lowpan_adaptation_tx_queue_read (protocol_interface_info_entry_t * cur , fragmenter_interface_t * interface_ptr );
133
133
134
134
/* Data direction and message length validation */
135
135
static bool lowpan_adaptation_indirect_data_request (mac_neighbor_table_entry_t * mle_entry );
@@ -223,8 +223,11 @@ static struct protocol_interface_info_entry *lowpan_adaptation_network_interface
223
223
}
224
224
225
225
226
- static void lowpan_adaptation_tx_queue_level_update (fragmenter_interface_t * interface_ptr )
226
+ static void lowpan_adaptation_tx_queue_level_update (protocol_interface_info_entry_t * cur , fragmenter_interface_t * interface_ptr )
227
227
{
228
+ random_early_detetction_aq_calc (cur -> random_early_detection , interface_ptr -> directTxQueue_size );
229
+ protocol_stats_update (STATS_AL_TX_QUEUE_SIZE , interface_ptr -> directTxQueue_size );
230
+
228
231
if (interface_ptr -> directTxQueue_size == interface_ptr -> directTxQueue_level + ADAPTION_DIRECT_TX_QUEUE_SIZE_THRESHOLD_TRACE ||
229
232
interface_ptr -> directTxQueue_size == interface_ptr -> directTxQueue_level - ADAPTION_DIRECT_TX_QUEUE_SIZE_THRESHOLD_TRACE ) {
230
233
interface_ptr -> directTxQueue_level = interface_ptr -> directTxQueue_size ;
@@ -233,14 +236,14 @@ static void lowpan_adaptation_tx_queue_level_update(fragmenter_interface_t *inte
233
236
}
234
237
235
238
236
- static void lowpan_adaptation_tx_queue_write (fragmenter_interface_t * interface_ptr , buffer_t * buf )
239
+ static void lowpan_adaptation_tx_queue_write (protocol_interface_info_entry_t * cur , fragmenter_interface_t * interface_ptr , buffer_t * buf )
237
240
{
238
241
buffer_t * lower_priority_buf = NULL ;
239
242
240
- ns_list_foreach (buffer_t , cur , & interface_ptr -> directTxQueue ) {
243
+ ns_list_foreach (buffer_t , entry , & interface_ptr -> directTxQueue ) {
241
244
242
- if (cur -> priority < buf -> priority ) {
243
- lower_priority_buf = cur ;
245
+ if (entry -> priority < buf -> priority ) {
246
+ lower_priority_buf = entry ;
244
247
break ;
245
248
}
246
249
}
@@ -251,18 +254,17 @@ static void lowpan_adaptation_tx_queue_write(fragmenter_interface_t *interface_p
251
254
ns_list_add_to_end (& interface_ptr -> directTxQueue , buf );
252
255
}
253
256
interface_ptr -> directTxQueue_size ++ ;
254
- lowpan_adaptation_tx_queue_level_update (interface_ptr );
255
- protocol_stats_update (STATS_AL_TX_QUEUE_SIZE , interface_ptr -> directTxQueue_size );
257
+ lowpan_adaptation_tx_queue_level_update (cur , interface_ptr );
256
258
}
257
259
258
- static void lowpan_adaptation_tx_queue_write_to_front (fragmenter_interface_t * interface_ptr , buffer_t * buf )
260
+ static void lowpan_adaptation_tx_queue_write_to_front (protocol_interface_info_entry_t * cur , fragmenter_interface_t * interface_ptr , buffer_t * buf )
259
261
{
260
262
buffer_t * lower_priority_buf = NULL ;
261
263
262
- ns_list_foreach (buffer_t , cur , & interface_ptr -> directTxQueue ) {
264
+ ns_list_foreach (buffer_t , entry , & interface_ptr -> directTxQueue ) {
263
265
264
- if (cur -> priority <= buf -> priority ) {
265
- lower_priority_buf = cur ;
266
+ if (entry -> priority <= buf -> priority ) {
267
+ lower_priority_buf = entry ;
266
268
break ;
267
269
}
268
270
}
@@ -273,11 +275,10 @@ static void lowpan_adaptation_tx_queue_write_to_front(fragmenter_interface_t *in
273
275
ns_list_add_to_end (& interface_ptr -> directTxQueue , buf );
274
276
}
275
277
interface_ptr -> directTxQueue_size ++ ;
276
- lowpan_adaptation_tx_queue_level_update (interface_ptr );
277
- protocol_stats_update (STATS_AL_TX_QUEUE_SIZE , interface_ptr -> directTxQueue_size );
278
+ lowpan_adaptation_tx_queue_level_update (cur , interface_ptr );
278
279
}
279
280
280
- static buffer_t * lowpan_adaptation_tx_queue_read (fragmenter_interface_t * interface_ptr )
281
+ static buffer_t * lowpan_adaptation_tx_queue_read (protocol_interface_info_entry_t * cur , fragmenter_interface_t * interface_ptr )
281
282
{
282
283
// Currently this function is called only when data confirm is received for previously sent packet.
283
284
if (!interface_ptr -> directTxQueue_size ) {
@@ -293,8 +294,7 @@ static buffer_t *lowpan_adaptation_tx_queue_read(fragmenter_interface_t *interfa
293
294
if (lowpan_buffer_tx_allowed (interface_ptr , buf )) {
294
295
ns_list_remove (& interface_ptr -> directTxQueue , buf );
295
296
interface_ptr -> directTxQueue_size -- ;
296
- lowpan_adaptation_tx_queue_level_update (interface_ptr );
297
- protocol_stats_update (STATS_AL_TX_QUEUE_SIZE , interface_ptr -> directTxQueue_size );
297
+ lowpan_adaptation_tx_queue_level_update (cur , interface_ptr );
298
298
return buf ;
299
299
}
300
300
}
@@ -561,12 +561,24 @@ void lowpan_adaptation_free_heap(bool full_gc)
561
561
lowpan_adaptation_free_low_priority_packets (interface_ptr -> interface_id , priority , amount );
562
562
}
563
563
}
564
+ buffer_t * lowpan_adaptation_get_oldest_packet (fragmenter_interface_t * interface_ptr , buffer_priority_t priority )
565
+ {
566
+ ns_list_foreach (buffer_t , entry , & interface_ptr -> directTxQueue ) {
567
+ if (entry -> priority == priority ) {
568
+ // Only Higher priority packets left no need to go through list anymore
569
+ return entry ;
570
+ }
571
+ }
572
+ return NULL ;
573
+
574
+ }
564
575
565
576
int8_t lowpan_adaptation_free_low_priority_packets (int8_t interface_id , buffer_priority_t max_priority , uint32_t requested_amount )
566
577
{
567
578
fragmenter_interface_t * interface_ptr = lowpan_adaptation_interface_discover (interface_id );
579
+ protocol_interface_info_entry_t * cur = protocol_stack_interface_info_get_by_id (interface_id );
568
580
569
- if (!interface_ptr ) {
581
+ if (!interface_ptr || ! cur ) {
570
582
return -1 ;
571
583
}
572
584
uint32_t adaptation_memory = 0 ;
@@ -592,21 +604,36 @@ int8_t lowpan_adaptation_free_low_priority_packets(int8_t interface_id, buffer_p
592
604
requested_amount = adaptation_memory - LOWPAN_MEM_LIMIT_MIN_MEMORY ;
593
605
}
594
606
595
- //Only remove last entries from TX queue with low priority
596
- ns_list_foreach_reverse_safe (buffer_t , entry , & interface_ptr -> directTxQueue ) {
597
- if (entry -> priority <= max_priority ) {
598
- memory_freed += sizeof (buffer_t ) + entry -> size ;
599
- packets_freed ++ ;
600
- ns_list_remove (& interface_ptr -> directTxQueue , entry );
601
- interface_ptr -> directTxQueue_size -- ;
602
- lowpan_adaptation_tx_queue_level_update (interface_ptr );
603
- socket_tx_buffer_event_and_free (entry , SOCKET_TX_FAIL );
604
- }
605
- if (memory_freed > requested_amount ) {
606
- // Enough memory freed
607
+ /* Order of packets is
608
+ * priority 4 oldest to newest
609
+ * priority 3 oldest to newest
610
+ * priority 2 oldest to newest
611
+ * priority 1 oldest to newest
612
+ * priority 0 oldest to newest
613
+ * So we search oldest for lowest priority and delete that until that priority is empty
614
+ * and then start deleting one higher priority packets from oldest first
615
+ */
616
+
617
+ buffer_priority_t priority = QOS_NORMAL ;
618
+ do {
619
+ buffer_t * entry = lowpan_adaptation_get_oldest_packet (interface_ptr , priority );
620
+ if (!entry ) {
621
+ if (priority < max_priority ) {
622
+ priority ++ ;
623
+ continue ;
624
+ }
625
+ // No more packets available
607
626
break ;
608
627
}
609
- }
628
+ // This packet can be deleted
629
+ memory_freed += sizeof (buffer_t ) + entry -> size ;
630
+ packets_freed ++ ;
631
+ ns_list_remove (& interface_ptr -> directTxQueue , entry );
632
+ interface_ptr -> directTxQueue_size -- ;
633
+ lowpan_adaptation_tx_queue_level_update (cur , interface_ptr );
634
+ socket_tx_buffer_event_and_free (entry , SOCKET_TX_FAIL );
635
+ } while (memory_freed < requested_amount );
636
+
610
637
tr_info ("Adaptation Free low priority packets memory: %" PRIi32 " queue: %d deallocated %" PRIi32 " bytes, %d packets, %" PRIi32 " requested" , adaptation_memory , adaptation_packets , memory_freed , packets_freed , requested_amount );
611
638
return 0 ;
612
639
}
@@ -1210,8 +1237,7 @@ static void lowpan_adaptation_high_priority_state_enable(protocol_interface_info
1210
1237
interface_ptr -> activeTxList_size -- ;
1211
1238
ns_dyn_mem_free (entry );
1212
1239
//Add message to tx queue front based on priority. Now same priority at buf is prioritised at order
1213
- lowpan_adaptation_tx_queue_write_to_front (interface_ptr , buf );
1214
- random_early_detetction_aq_calc (cur -> random_early_detection , interface_ptr -> directTxQueue_size );
1240
+ lowpan_adaptation_tx_queue_write_to_front (cur , interface_ptr , buf );
1215
1241
}
1216
1242
}
1217
1243
}
@@ -1260,13 +1286,11 @@ void lowpan_adaptation_interface_slow_timer(protocol_interface_info_entry_t *cur
1260
1286
1261
1287
if (lowpan_adaptation_high_priority_state_exit (interface_ptr )) {
1262
1288
//Activate Packets from TX queue
1263
- buffer_t * buf_from_queue = lowpan_adaptation_tx_queue_read (interface_ptr );
1289
+ buffer_t * buf_from_queue = lowpan_adaptation_tx_queue_read (cur , interface_ptr );
1264
1290
while (buf_from_queue ) {
1265
1291
lowpan_adaptation_interface_tx (cur , buf_from_queue );
1266
- buf_from_queue = lowpan_adaptation_tx_queue_read (interface_ptr );
1292
+ buf_from_queue = lowpan_adaptation_tx_queue_read (cur , interface_ptr );
1267
1293
}
1268
- //Update Average QUEUE
1269
- random_early_detetction_aq_calc (cur -> random_early_detection , interface_ptr -> directTxQueue_size );
1270
1294
}
1271
1295
}
1272
1296
@@ -1319,17 +1343,17 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
1319
1343
1320
1344
if (!lowpan_buffer_tx_allowed (interface_ptr , buf )) {
1321
1345
1322
- if (buf -> priority == QOS_NORMAL ) {
1323
-
1324
- if (random_early_detection_congestion_check (cur -> random_early_detection )) {
1325
- random_early_detetction_aq_calc (cur -> random_early_detection , interface_ptr -> directTxQueue_size );
1346
+ if (random_early_detection_congestion_check (cur -> random_early_detection )) {
1347
+ // If we need to drop packet we drop oldest normal Priority packet.
1348
+ buffer_t * dropped = lowpan_adaptation_get_oldest_packet (interface_ptr , QOS_NORMAL );
1349
+ if (dropped ) {
1350
+ ns_list_remove (& interface_ptr -> directTxQueue , dropped );
1351
+ interface_ptr -> directTxQueue_size -- ;
1352
+ socket_tx_buffer_event_and_free (dropped , SOCKET_TX_FAIL );
1326
1353
protocol_stats_update (STATS_AL_TX_CONGESTION_DROP , 1 );
1327
- goto tx_error_handler ;
1328
1354
}
1329
1355
}
1330
-
1331
- lowpan_adaptation_tx_queue_write (interface_ptr , buf );
1332
- random_early_detetction_aq_calc (cur -> random_early_detection , interface_ptr -> directTxQueue_size );
1356
+ lowpan_adaptation_tx_queue_write (cur , interface_ptr , buf );
1333
1357
return 0 ;
1334
1358
}
1335
1359
@@ -1605,13 +1629,11 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c
1605
1629
if (active_direct_confirm == true) {
1606
1630
//Check Possibility for exit from High Priority state
1607
1631
lowpan_adaptation_high_priority_state_exit (interface_ptr );
1608
- buffer_t * buf_from_queue = lowpan_adaptation_tx_queue_read (interface_ptr );
1632
+ buffer_t * buf_from_queue = lowpan_adaptation_tx_queue_read (cur , interface_ptr );
1609
1633
while (buf_from_queue ) {
1610
1634
lowpan_adaptation_interface_tx (cur , buf_from_queue );
1611
- buf_from_queue = lowpan_adaptation_tx_queue_read (interface_ptr );
1635
+ buf_from_queue = lowpan_adaptation_tx_queue_read (cur , interface_ptr );
1612
1636
}
1613
- //Update Average QUEUE
1614
- random_early_detetction_aq_calc (cur -> random_early_detection , interface_ptr -> directTxQueue_size );
1615
1637
}
1616
1638
return 0 ;
1617
1639
}
@@ -1815,8 +1837,7 @@ int8_t lowpan_adaptation_free_messages_from_queues_by_address(struct protocol_in
1815
1837
ns_list_remove (& interface_ptr -> directTxQueue , entry );
1816
1838
interface_ptr -> directTxQueue_size -- ;
1817
1839
//Update Average QUEUE
1818
- random_early_detetction_aq_calc (cur -> random_early_detection , interface_ptr -> directTxQueue_size );
1819
- lowpan_adaptation_tx_queue_level_update (interface_ptr );
1840
+ lowpan_adaptation_tx_queue_level_update (cur , interface_ptr );
1820
1841
socket_tx_buffer_event_and_free (entry , SOCKET_TX_FAIL );
1821
1842
}
1822
1843
}
0 commit comments