Skip to content

Commit 23334b7

Browse files
author
Juha Heiskanen
committed
Added support for High Priority forward state
High priority forward state is activated when stack RX that spesific message to forward. Enabled state only trig new TX operation for Highest priority level and put other messages to queue. Mode is disabeld when all High priority messages are sended and 5 seconds from last RX messages. MPX have a new API for indicate enabled or disabled high priory state. Wi-sun LLC drop Asynch message send request at High priority state.
1 parent 3ec2a2c commit 23334b7

File tree

6 files changed

+172
-0
lines changed

6 files changed

+172
-0
lines changed

source/6LoWPAN/MAC/mpx_api.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,14 @@ typedef int8_t mpx_data_cb_register(const mpx_api_t *api, mpx_data_confirm *conf
9090
*/
9191
typedef void mpx_eui64_purge_request(const mpx_api_t *api, const uint8_t *eui64);
9292

93+
/**
94+
* \brief mpx_high_priority_mode_set Enable/Disable MPX high priority mode for TX process
95+
* @param api The API which handled the response
96+
* @param enable_mode True for enable High Priority mode, False disable
97+
*
98+
*/
99+
typedef void mpx_high_priority_mode_set(const mpx_api_t *api, bool enable_mode);
100+
93101
/**
94102
* \brief Struct mpx_api_s defines functions for MPX user for register call backs and send data.
95103
*/
@@ -99,6 +107,7 @@ struct mpx_api_s {
99107
mpx_header_size_get *mpx_headroom_size_get; /**< MPX headroom size get in bytes. */
100108
mpx_data_cb_register *mpx_user_registration; /**< MPX User cb registration must be call before enable to send or RX data*/
101109
mpx_eui64_purge_request *mpx_eui64_purge; /**< MPX Purge EUI-64 related data */
110+
mpx_high_priority_mode_set *mpx_priority_mode_set; /**< MPX request to enable / disable High Priority mode */
102111
};
103112

104113

source/6LoWPAN/adaptation_interface.c

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ typedef struct {
101101
uint16_t indirect_big_packet_threshold;
102102
uint16_t max_indirect_big_packets_total;
103103
uint16_t max_indirect_small_packets_per_child;
104+
uint32_t last_rx_high_priority;
104105
bool fragmenter_active; /*!< Fragmenter state */
105106
adaptation_etx_update_cb *etx_update_cb;
106107
mpx_api_t *mpx_api;
@@ -109,6 +110,7 @@ typedef struct {
109110
} fragmenter_interface_t;
110111

111112
#define LOWPAN_ACTIVE_UNICAST_ONGOING_MAX 10
113+
#define LOWPAN_HIGH_PRIORITY_STATE_LENGTH 50 //5 seconds 100us ticks
112114

113115
/* Minimum buffer amount and memory size to ensure operation even in out of memory situation
114116
*/
@@ -155,6 +157,7 @@ static bool lowpan_adaptation_indirect_queue_free_message(struct protocol_interf
155157
static fragmenter_tx_entry_t *lowpan_adaptation_indirect_mac_data_request_active(fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr);
156158

157159
static bool lowpan_buffer_tx_allowed(fragmenter_interface_t *interface_ptr, buffer_t *buf);
160+
static bool lowpan_adaptation_purge_from_mac(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, uint8_t msduhandle);
158161

159162
static void lowpan_adaptation_etx_update_cb(protocol_interface_info_entry_t *cur, buffer_t *buf, const mcps_data_conf_t *confirm)
160163
{
@@ -251,13 +254,41 @@ static void lowpan_adaptation_tx_queue_write(fragmenter_interface_t *interface_p
251254
protocol_stats_update(STATS_AL_TX_QUEUE_SIZE, interface_ptr->directTxQueue_size);
252255
}
253256

257+
static void lowpan_adaptation_tx_queue_write_to_front(fragmenter_interface_t *interface_ptr, buffer_t *buf)
258+
{
259+
buffer_t *lower_priority_buf = NULL;
260+
261+
ns_list_foreach(buffer_t, cur, &interface_ptr->directTxQueue) {
262+
263+
if (cur->priority <= buf->priority) {
264+
lower_priority_buf = cur;
265+
break;
266+
}
267+
}
268+
269+
if (lower_priority_buf) {
270+
ns_list_add_before(&interface_ptr->directTxQueue, lower_priority_buf, buf);
271+
} else {
272+
ns_list_add_to_end(&interface_ptr->directTxQueue, buf);
273+
}
274+
interface_ptr->directTxQueue_size++;
275+
lowpan_adaptation_tx_queue_level_update(interface_ptr);
276+
protocol_stats_update(STATS_AL_TX_QUEUE_SIZE, interface_ptr->directTxQueue_size);
277+
}
278+
254279
static buffer_t *lowpan_adaptation_tx_queue_read(fragmenter_interface_t *interface_ptr)
255280
{
256281
// Currently this function is called only when data confirm is received for previously sent packet.
257282
if (!interface_ptr->directTxQueue_size) {
258283
return NULL;
259284
}
260285
ns_list_foreach_safe(buffer_t, buf, &interface_ptr->directTxQueue) {
286+
287+
if (buf->link_specific.ieee802_15_4.requestAck && interface_ptr->last_rx_high_priority && buf->priority < QOS_EXPEDITE_FORWARD) {
288+
//Stop reading at this point when Priority is not enough big
289+
return NULL;
290+
}
291+
261292
if (lowpan_buffer_tx_allowed(interface_ptr, buf)) {
262293
ns_list_remove(&interface_ptr->directTxQueue, buf);
263294
interface_ptr->directTxQueue_size--;
@@ -460,6 +491,7 @@ int8_t lowpan_adaptation_interface_reset(int8_t interface_id)
460491
buffer_free_list(&interface_ptr->directTxQueue);
461492
interface_ptr->directTxQueue_size = 0;
462493
interface_ptr->directTxQueue_level = 0;
494+
interface_ptr->last_rx_high_priority = 0;
463495

464496
return 0;
465497
}
@@ -1075,9 +1107,110 @@ static bool lowpan_buffer_tx_allowed(fragmenter_interface_t *interface_ptr, buff
10751107
if (is_unicast && lowpan_adaptation_is_destination_tx_active(&interface_ptr->activeUnicastList, buf)) {
10761108
return false;
10771109
}
1110+
1111+
if (is_unicast && interface_ptr->last_rx_high_priority && buf->priority < QOS_EXPEDITE_FORWARD) {
1112+
return false;
1113+
}
1114+
return true;
1115+
}
1116+
1117+
static uint32_t lowpan_adaptation_time_stamp_diff(uint32_t compare_stamp)
1118+
{
1119+
if (protocol_core_monotonic_time < compare_stamp) {
1120+
return compare_stamp - protocol_core_monotonic_time;
1121+
}
1122+
return protocol_core_monotonic_time - compare_stamp;
1123+
}
1124+
1125+
static bool lowpan_adaptation_high_priority_state_exit(fragmenter_interface_t *interface_ptr)
1126+
{
1127+
if (!interface_ptr->last_rx_high_priority || lowpan_adaptation_time_stamp_diff(interface_ptr->last_rx_high_priority) < LOWPAN_HIGH_PRIORITY_STATE_LENGTH) {
1128+
return false;
1129+
}
1130+
1131+
//Check First buffer_from tx queue
1132+
buffer_t *buf = ns_list_get_first(&interface_ptr->directTxQueue);
1133+
if (buf && buf->priority == QOS_EXPEDITE_FORWARD) {
1134+
//TX queue must not include any
1135+
return false;
1136+
}
1137+
1138+
//Check If we have a Any active TX process still active
1139+
ns_list_foreach(fragmenter_tx_entry_t, entry, &interface_ptr->activeUnicastList) {
1140+
if (entry->buf->priority == QOS_EXPEDITE_FORWARD) {
1141+
return false;
1142+
}
1143+
}
1144+
1145+
//Disable High Priority Mode
1146+
if (interface_ptr->mpx_api) {
1147+
interface_ptr->mpx_api->mpx_priority_mode_set(interface_ptr->mpx_api, false);
1148+
}
1149+
interface_ptr->last_rx_high_priority = 0;
10781150
return true;
10791151
}
10801152

1153+
static void lowpan_adaptation_high_priority_state_enable(protocol_interface_info_entry_t *cur, fragmenter_interface_t *interface_ptr)
1154+
{
1155+
1156+
if (!interface_ptr->last_rx_high_priority) {
1157+
// MPX enaled stack must inform MPX to priority enable
1158+
if (interface_ptr->mpx_api) {
1159+
interface_ptr->mpx_api->mpx_priority_mode_set(interface_ptr->mpx_api, true);
1160+
}
1161+
//Purge Active tx queue's all possible's
1162+
if (!interface_ptr->fragmenter_active) {
1163+
//Purge Only When Fragmenter is not active
1164+
ns_list_foreach_reverse_safe(fragmenter_tx_entry_t, entry, &interface_ptr->activeUnicastList) {
1165+
1166+
if (lowpan_adaptation_purge_from_mac(cur, interface_ptr, entry->buf->seq)) {
1167+
buffer_t *buf = entry->buf;
1168+
ns_list_remove(&interface_ptr->activeUnicastList, entry);
1169+
interface_ptr->activeTxList_size--;
1170+
ns_dyn_mem_free(entry);
1171+
//Add message to tx queue front based on priority. Now same priority at buf is prioritised at order
1172+
lowpan_adaptation_tx_queue_write_to_front(interface_ptr, buf);
1173+
random_early_detetction_aq_calc(cur->random_early_detection, interface_ptr->directTxQueue_size);
1174+
}
1175+
}
1176+
}
1177+
}
1178+
1179+
//Store timestamp for indicate last RX High Priority message
1180+
interface_ptr->last_rx_high_priority = protocol_core_monotonic_time ? protocol_core_monotonic_time : 1;
1181+
1182+
}
1183+
1184+
1185+
static void lowpan_adaptation_priority_status_update(protocol_interface_info_entry_t *cur, fragmenter_interface_t *interface_ptr, buffer_priority_t priority)
1186+
{
1187+
if (priority == QOS_EXPEDITE_FORWARD) {
1188+
lowpan_adaptation_high_priority_state_enable(cur, interface_ptr);
1189+
} else {
1190+
//Let check can we disable possible High Priority state
1191+
lowpan_adaptation_high_priority_state_exit(interface_ptr);
1192+
}
1193+
}
1194+
1195+
void lowpan_adaptation_interface_slow_timer(protocol_interface_info_entry_t *cur)
1196+
{
1197+
fragmenter_interface_t *interface_ptr = lowpan_adaptation_interface_discover(cur->id);
1198+
if (!interface_ptr) {
1199+
return;
1200+
}
1201+
1202+
if (lowpan_adaptation_high_priority_state_exit(interface_ptr)) {
1203+
//Activate Packets from TX queue
1204+
buffer_t *buf_from_queue = lowpan_adaptation_tx_queue_read(interface_ptr);
1205+
while (buf_from_queue) {
1206+
lowpan_adaptation_interface_tx(cur, buf_from_queue);
1207+
buf_from_queue = lowpan_adaptation_tx_queue_read(interface_ptr);
1208+
}
1209+
//Update Average QUEUE
1210+
random_early_detetction_aq_calc(cur->random_early_detection, interface_ptr->directTxQueue_size);
1211+
}
1212+
}
1213+
10811214
int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buffer_t *buf)
10821215
{
10831216
bool is_room_for_new_message;
@@ -1105,6 +1238,8 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
11051238
buffer_priority_set(buf, QOS_HIGH);
11061239
}
11071240

1241+
//Update priority status
1242+
lowpan_adaptation_priority_status_update(cur, interface_ptr, buf->priority);
11081243

11091244
//Check packet size
11101245
bool fragmented_needed = lowpan_adaptation_request_longer_than_mtu(cur, buf, interface_ptr);
@@ -1409,6 +1544,8 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c
14091544
}
14101545
// When confirmation is for direct transmission, push all allowed buffers to MAC
14111546
if (active_direct_confirm == true) {
1547+
//Check Possibility for exit from High Priority state
1548+
lowpan_adaptation_high_priority_state_exit(interface_ptr);
14121549
buffer_t *buf_from_queue = lowpan_adaptation_tx_queue_read(interface_ptr);
14131550
while (buf_from_queue) {
14141551
lowpan_adaptation_interface_tx(cur, buf_from_queue);

source/6LoWPAN/lowpan_adaptation_interface.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,6 @@ int8_t lowpan_adaptation_free_messages_from_queues_by_address(struct protocol_in
6262

6363
int8_t lowpan_adaptation_indirect_queue_params_set(struct protocol_interface_info_entry *cur, uint16_t indirect_big_packet_threshold, uint16_t max_indirect_big_packets_total, uint16_t max_indirect_small_packets_per_child);
6464

65+
void lowpan_adaptation_interface_slow_timer(struct protocol_interface_info_entry *cur);
66+
6567
#endif /* LOWPAN_ADAPTATION_INTERFACE_H_ */

source/6LoWPAN/ws/ws_llc_data_service.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ typedef struct {
135135
ws_neighbor_info_request *ws_neighbor_info_request_cb; /**< LLC Neighbour discover API*/
136136
uint8_t ws_enhanced_response_elements[ENHANCED_FRAME_RESPONSE];
137137
ns_ie_iovec_t ws_header_vector;
138+
bool high_priority_mode;
138139
protocol_interface_info_entry_t *interface_ptr; /**< List link entry */
139140
} llc_data_base_t;
140141

@@ -1343,6 +1344,15 @@ static uint8_t ws_llc_mpx_data_purge_request(const mpx_api_t *api, struct mcps_p
13431344
return purge_status;
13441345
}
13451346

1347+
static void wc_llc_mpx_priority_set_request(const mpx_api_t *api, bool enable_mode)
1348+
{
1349+
llc_data_base_t *base = ws_llc_discover_by_mpx(api);
1350+
if (!base) {
1351+
return;
1352+
}
1353+
base->high_priority_mode = enable_mode;
1354+
}
1355+
13461356
static void ws_llc_mpx_init(mpx_class_t *mpx_class)
13471357
{
13481358
//Init Mbed Class and API
@@ -1353,6 +1363,7 @@ static void ws_llc_mpx_init(mpx_class_t *mpx_class)
13531363
mpx_class->mpx_api.mpx_data_request = &ws_llc_mpx_data_request;
13541364
mpx_class->mpx_api.mpx_data_purge = &ws_llc_mpx_data_purge_request;
13551365
mpx_class->mpx_api.mpx_eui64_purge = &ws_llc_mpx_eui64_purge_request;
1366+
mpx_class->mpx_api.mpx_priority_mode_set = &wc_llc_mpx_priority_set_request;
13561367
}
13571368

13581369
static void ws_llc_clean(llc_data_base_t *base)
@@ -1375,6 +1386,8 @@ static void ws_llc_clean(llc_data_base_t *base)
13751386
memset(&base->ie_params, 0, sizeof(llc_ie_params_t));
13761387

13771388
ws_llc_temp_neigh_info_table_reset(base->temp_entries);
1389+
//Disable High Priority mode
1390+
base->high_priority_mode = false;
13781391
}
13791392

13801393
static void ws_llc_temp_neigh_info_table_reset(temp_entriest_t *base)
@@ -1677,6 +1690,11 @@ int8_t ws_llc_asynch_request(struct protocol_interface_info_entry *interface, as
16771690
return -1;
16781691
}
16791692

1693+
if (base->high_priority_mode) {
1694+
//Drop asynch messages at High Priority mode
1695+
return -1;
1696+
}
1697+
16801698

16811699
//Calculate IE Buffer size
16821700
request->wh_requested_ie_list.fc_ie = false; //Never should not be a part Asynch message

source/NWK_INTERFACE/protocol_core.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ void core_timer_event_handle(uint16_t ticksUpdate)
265265
cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, false);
266266
}
267267
etx_cache_timer(cur->id, seconds);
268+
lowpan_adaptation_interface_slow_timer(cur);
268269
}
269270
} else if (cur->nwk_id == IF_IPV6) {
270271
//Slow Pointer Update

test/nanostack/unittest/stub/adaptation_interface_stub.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,8 @@ void lowpan_adaptation_neigh_remove_free_tx_tables(struct protocol_interface_inf
111111
{
112112

113113
}
114+
115+
void lowpan_adaptation_interface_slow_timer(protocol_interface_info_entry_t *cur)
116+
{
117+
118+
}

0 commit comments

Comments
 (0)