Skip to content

Commit a40e012

Browse files
author
Arto Kinnunen
authored
Check MAC status when purging indirect queue (ARMmbed#1811)
When more room is needed for indirect messages then old messages are purged from MAC. If MAC is already processing a message then it can not be freed. Check MAC return value to avoid freeing message that is under processing. Update MPX API to return non-zero value in case of data purging fails.
1 parent 6fe5ea5 commit a40e012

File tree

9 files changed

+67
-37
lines changed

9 files changed

+67
-37
lines changed

nanostack/mac_api.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,9 @@ typedef void mcps_data_request_ext(const mac_api_t* api, const mcps_data_req_t *
137137
* @brief mcps_purge_request MCPS_PURGE request call
138138
* @param api API to handle the request
139139
* @param data MCPS-PURGE.request specific values
140+
* @return 0 in case of success, non-zero otherwise
140141
*/
141-
typedef void mcps_purge_request(const mac_api_t* api, const mcps_purge_t *data);
142+
typedef uint8_t mcps_purge_request(const mac_api_t* api, const mcps_purge_t *data);
142143

143144
//Upper layer specific callback functions (will also be set by Upper layer after mac_api_t has been created and given to it)
144145

source/6LoWPAN/MAC/mpx_api.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,10 @@ typedef void mpx_data_request(const mpx_api_t *api, const struct mcps_data_req_s
3939
* @param api API to handle the request
4040
* @param purge MCPS-purge request
4141
* @param user_id MPX user ID
42+
* @return 0 if purge requst was OK, non-zero otherwise
4243
*
4344
*/
44-
typedef void mpx_data_purge_request(const mpx_api_t *api, struct mcps_purge_s *purge, uint16_t user_id);
45+
typedef uint8_t mpx_data_purge_request(const mpx_api_t *api, struct mcps_purge_s *purge, uint16_t user_id);
4546

4647
/**
4748
* @brief mpx_data_confirm MPX-DATA confirm is called as a response to MPX-DATA request

source/6LoWPAN/adaptation_interface.c

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ typedef struct {
7171
bool fragmented_data:1;
7272
bool first_fragment:1;
7373
bool indirect_data:1;
74-
bool indirect_data_cached:1; /* Data cached for delayed transmission as mac request is already active */
74+
bool indirect_data_cached:1; /*!< Data cached for delayed transmission as mac request is already active */
7575
buffer_t *buf;
7676
uint8_t *fragmenter_buf;
7777
ns_list_link_t link; /*!< List link entry */
@@ -131,7 +131,7 @@ static bool lowpan_adaptation_tx_process_ready(fragmenter_tx_entry_t *tx_ptr);
131131
/* Fragmentation local functions */
132132
static int8_t lowpan_message_fragmentation_init(buffer_t *buf, fragmenter_tx_entry_t *frag_entry, protocol_interface_info_entry_t *cur, fragmenter_interface_t *interface_ptr);
133133
static bool lowpan_message_fragmentation_message_write(const fragmenter_tx_entry_t *frag_entry, mcps_data_req_t *dataReq);
134-
static void lowpan_adaptation_indirect_queue_free_message(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr);
134+
static bool lowpan_adaptation_indirect_queue_free_message(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr);
135135

136136
static fragmenter_tx_entry_t* lowpan_adaptation_indirect_mac_data_request_active(fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr);
137137

@@ -749,7 +749,7 @@ static bool lowpan_adaptation_indirect_cache_trigger(protocol_interface_info_ent
749749
ns_list_foreach(fragmenter_tx_entry_t, fragmenter_tx_entry, &interface_ptr->indirect_tx_queue) {
750750
if (fragmenter_tx_entry->indirect_data_cached) {
751751
if (addr_ipv6_equal(tx_ptr->buf->dst_sa.address, fragmenter_tx_entry->buf->dst_sa.address)) {
752-
tr_debug_extra("pushing seq %d to addr %s", fragmenter_tx_entry->buf->seq, trace_ipv6(fragmenter_tx_entry->buf->dst_sa.address));
752+
tr_debug_extra("Pushing seq %d to addr %s", fragmenter_tx_entry->buf->seq, trace_ipv6(fragmenter_tx_entry->buf->dst_sa.address));
753753
fragmenter_tx_entry->indirect_data_cached = false;
754754
lowpan_data_request_to_mac(cur, fragmenter_tx_entry->buf, fragmenter_tx_entry, interface_ptr);
755755
return true;
@@ -799,7 +799,12 @@ static void lowpan_adaptation_make_room_for_small_packet(protocol_interface_info
799799
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);
800800
if (tx_neighbour == neighbour_to_count && buffer_data_length(tx_entry->buf) <= interface_ptr->indirect_big_packet_threshold) {
801801
if (++count >= interface_ptr->max_indirect_small_packets_per_child) {
802-
lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, tx_entry);
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) {
804+
/* entry could not be purged from mac, try next entry */
805+
tr_debug_extra("Purge failed, try next");
806+
count--;
807+
}
803808
}
804809
}
805810
}
@@ -816,8 +821,12 @@ static void lowpan_adaptation_make_room_for_big_packet(struct protocol_interface
816821
ns_list_foreach_reverse_safe(fragmenter_tx_entry_t, tx_entry, &interface_ptr->indirect_tx_queue) {
817822
if (buffer_data_length(tx_entry->buf) > interface_ptr->indirect_big_packet_threshold) {
818823
if (++count >= interface_ptr->max_indirect_big_packets_total) {
819-
tr_debug_extra("free seq: %d", tx_entry->buf->seq);
820-
lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, tx_entry);
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");
827+
/* entry could not be purged from mac, try next entry */
828+
count--;
829+
}
821830
}
822831
}
823832
}
@@ -1275,29 +1284,44 @@ static bool lowpan_tx_buffer_address_compare(sockaddr_t *dst_sa, uint8_t *addres
12751284
return true;
12761285
}
12771286

1278-
static void lowpan_adaptation_purge_from_mac(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, uint8_t msduhandle)
1287+
static bool lowpan_adaptation_purge_from_mac(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, uint8_t msduhandle)
12791288
{
12801289
mcps_purge_t purge_req;
12811290
purge_req.msduHandle = msduhandle;
1291+
bool mac_purge_success = false;
12821292
if (interface_ptr->mpx_api) {
1283-
interface_ptr->mpx_api->mpx_data_purge(interface_ptr->mpx_api, &purge_req, interface_ptr->mpx_user_id);
1293+
if (interface_ptr->mpx_api->mpx_data_purge(interface_ptr->mpx_api, &purge_req, interface_ptr->mpx_user_id) == 0) {
1294+
mac_purge_success = true;
1295+
}
12841296
} else {
12851297
if (cur->mac_api->mcps_purge_req) {
1286-
cur->mac_api->mcps_purge_req(cur->mac_api, &purge_req);
1298+
if (cur->mac_api->mcps_purge_req(cur->mac_api, &purge_req) == 0) {
1299+
mac_purge_success = true;
1300+
}
12871301
}
12881302
}
1303+
1304+
return mac_purge_success;
12891305
}
12901306

1291-
static void lowpan_adaptation_indirect_queue_free_message(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr)
1307+
static bool lowpan_adaptation_indirect_queue_free_message(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr)
12921308
{
1293-
tr_debug("Purge from indirect handle %u", tx_ptr->buf->seq);
1294-
lowpan_adaptation_purge_from_mac(cur, interface_ptr, tx_ptr->buf->seq);
1309+
tr_debug("Purge from indirect handle %u, cached %d", tx_ptr->buf->seq, tx_ptr->indirect_data_cached);
1310+
if (tx_ptr->indirect_data_cached == false) {
1311+
if (lowpan_adaptation_purge_from_mac(cur, interface_ptr, tx_ptr->buf->seq) == false) {
1312+
// MAC purge failed
1313+
return false;
1314+
}
1315+
}
1316+
12951317
lowpan_adaptation_data_process_clean(interface_ptr, tx_ptr, SOCKET_TX_FAIL);
1318+
1319+
return true;
12961320
}
12971321

12981322
void lowpan_adaptation_remove_free_indirect_table(protocol_interface_info_entry_t *cur_interface, mac_neighbor_table_entry_t *entry_ptr)
12991323
{
1300-
//Free firts by defined short address
1324+
//Free first by defined short address
13011325
if (entry_ptr->mac16 < 0xfffe) {
13021326
uint8_t temp_address[2];
13031327
common_write_16_bit(entry_ptr->mac16, temp_address);
@@ -1317,15 +1341,13 @@ int8_t lowpan_adaptation_indirect_free_messages_from_queues_by_address(struct pr
13171341

13181342
//Check first indirect queue
13191343
ns_list_foreach_safe(fragmenter_tx_entry_t, entry, &interface_ptr->indirect_tx_queue) {
1320-
13211344
if (lowpan_tx_buffer_address_compare(&entry->buf->dst_sa, address_ptr, adr_type)) {
13221345
//Purge from mac
13231346
lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, entry);
13241347
}
13251348
}
13261349

13271350
return 0;
1328-
13291351
}
13301352

13311353
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)

source/6LoWPAN/ws/ws_llc_data_service.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ static uint16_t ws_mpx_header_size_get(llc_data_base_t *base, uint16_t user_id);
130130
static void ws_llc_mpx_data_request(const mpx_api_t *api, const struct mcps_data_req_s *data, uint16_t user_id);
131131
static int8_t ws_llc_mpx_data_cb_register(const mpx_api_t* api, mpx_data_confirm *confirm_cb, mpx_data_indication *indication_cb, uint16_t user_id);
132132
static uint16_t ws_llc_mpx_header_size_get(const mpx_api_t * api, uint16_t user_id);
133-
static void ws_llc_mpx_data_purge_request(const mpx_api_t *api, struct mcps_purge_s *purge, uint16_t user_id);
133+
static uint8_t ws_llc_mpx_data_purge_request(const mpx_api_t *api, struct mcps_purge_s *purge, uint16_t user_id);
134134
static void ws_llc_mpx_init(mpx_class_t *mpx_class);
135135

136136
/** Discover Message by message handle id */
@@ -734,22 +734,26 @@ static uint16_t ws_llc_mpx_header_size_get(const mpx_api_t * api, uint16_t user_
734734
return ws_mpx_header_size_get(base, user_id);
735735
}
736736

737-
static void ws_llc_mpx_data_purge_request(const mpx_api_t *api, struct mcps_purge_s *purge, uint16_t user_id)
737+
static uint8_t ws_llc_mpx_data_purge_request(const mpx_api_t *api, struct mcps_purge_s *purge, uint16_t user_id)
738738
{
739739
llc_data_base_t *base = ws_llc_discover_by_mpx(api);
740740
if (!base) {
741-
return;
741+
return MLME_INVALID_HANDLE;
742742
}
743743
llc_message_t * message = llc_message_discover_mpx_user_id(purge->msduHandle,user_id, &base->llc_message_list);
744744
if (!message) {
745-
return;
745+
return MLME_INVALID_HANDLE;
746746
}
747747

748748
mcps_purge_t purge_req;
749+
uint8_t purge_status;
749750
purge_req.msduHandle = message->msg_handle;
750-
llc_message_free(message, base);
751-
base->interface_ptr->mac_api->mcps_purge_req(base->interface_ptr->mac_api, &purge_req);
751+
purge_status = base->interface_ptr->mac_api->mcps_purge_req(base->interface_ptr->mac_api, &purge_req);
752+
if (purge_status == 0) {
753+
llc_message_free(message, base);
754+
}
752755

756+
return purge_status;
753757
}
754758

755759
static void ws_llc_mpx_init(mpx_class_t *mpx_class)

source/MAC/IEEE802_15_4/mac_mcps_sap.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2234,17 +2234,14 @@ static bool mcps_sap_purge_req_from_queue(protocol_interface_rf_mac_setup_s *rf_
22342234
uint8_t status = false;
22352235
rf_mac_setup->pd_data_request_queue_to_go = mcps_sap_purge_from_list(rf_mac_setup->pd_data_request_queue_to_go, msduhandle, &status);
22362236

2237-
if (status) {
2238-
return true;
2237+
if (!status) {
2238+
rf_mac_setup->indirect_pd_data_request_queue = mcps_sap_purge_from_list(rf_mac_setup->indirect_pd_data_request_queue, msduhandle, &status);
22392239
}
22402240

2241-
rf_mac_setup->indirect_pd_data_request_queue = mcps_sap_purge_from_list(rf_mac_setup->indirect_pd_data_request_queue, msduhandle, &status);
2242-
22432241
return status;
2244-
22452242
}
22462243

2247-
void mcps_sap_purge_reg_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mcps_purge_t *purge_req)
2244+
uint8_t mcps_sap_purge_reg_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mcps_purge_t *purge_req)
22482245
{
22492246
mcps_purge_conf_t confirmation;
22502247
confirmation.msduHandle = purge_req->msduHandle;
@@ -2258,4 +2255,6 @@ void mcps_sap_purge_reg_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup,
22582255
if( get_sw_mac_api(rf_mac_setup) ) {
22592256
get_sw_mac_api(rf_mac_setup)->purge_conf_cb(get_sw_mac_api(rf_mac_setup), &confirmation);
22602257
}
2258+
2259+
return confirmation.status;
22612260
}

source/MAC/IEEE802_15_4/mac_mcps_sap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ int mac_convert_frame_type_to_fhss(uint8_t frame_type);
200200

201201
void mcps_sap_trig_tx(void *mac_ptr);
202202

203-
void mcps_sap_purge_reg_handler(struct protocol_interface_rf_mac_setup *rf_mac_setup, const struct mcps_purge_s *purge_req);
203+
uint8_t mcps_sap_purge_reg_handler(struct protocol_interface_rf_mac_setup *rf_mac_setup, const struct mcps_purge_s *purge_req);
204204

205205
int8_t mcps_pd_data_rebuild(struct protocol_interface_rf_mac_setup *rf_ptr, mac_pre_build_frame_t *buffer);
206206

source/MAC/IEEE802_15_4/sw_mac.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ static int8_t ns_sw_mac_api_enable_mcps_ext(mac_api_t *api, mcps_data_indication
5454
static void mlme_req(const mac_api_t* api, mlme_primitive id, const void *data);
5555
static void mcps_req(const mac_api_t* api, const mcps_data_req_t *data);
5656
static void mcps_req_ext(const mac_api_t* api, const mcps_data_req_t *data, const mcps_data_req_ie_list_t *ie_ext, const channel_list_s *asynch_channel_list);
57-
static void purge_req(const mac_api_t* api, const mcps_purge_t *data);
57+
static uint8_t purge_req(const mac_api_t* api, const mcps_purge_t *data);
5858
static int8_t macext_mac64_address_set( const mac_api_t* api, const uint8_t *mac64);
5959
static int8_t macext_mac64_address_get( const mac_api_t* api, mac_extended_address_type type, uint8_t *mac64_buf);
6060

@@ -510,11 +510,12 @@ void mcps_req_ext(const mac_api_t* api, const mcps_data_req_t *data, const mcps_
510510
}
511511

512512

513-
static void purge_req(const mac_api_t* api, const mcps_purge_t *data)
513+
static uint8_t purge_req(const mac_api_t* api, const mcps_purge_t *data)
514514
{
515515
if (mac_store.mac_api == api) {
516-
mcps_sap_purge_reg_handler(mac_store.setup , data );
516+
return mcps_sap_purge_reg_handler(mac_store.setup , data );
517517
}
518+
return MLME_INVALID_HANDLE;
518519
}
519520

520521
static int8_t macext_mac64_address_set( const mac_api_t* api, const uint8_t *mac64)

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,13 @@ static void mcps_data_req_cb(const mac_api_t* api, const mcps_data_req_t *data)
5050
mcps_data_req_cnt++;
5151
}
5252

53-
static void tester_mcps_purge_request(const mac_api_t* api,
53+
static uint8_t tester_mcps_purge_request(const mac_api_t* api,
5454
const mcps_purge_t *data)
5555
{
5656
(void) api;
5757
(void) data;
5858
mcps_purge_req_cnt++;
59+
return 0;
5960
}
6061

6162
bool test_lowpan_adaptation_interface_init()
@@ -680,8 +681,8 @@ bool test_lowpan_adaptation_interface_indirect_tx()
680681
if (0 != lowpan_adaptation_interface_tx(&entry, test_buf2)) {
681682
return false;
682683
} else if ((data_request_count != mcps_data_req_cnt) ||
683-
(++data_purge_count != mcps_purge_req_cnt)) {
684-
// error if mac data request sent or no purging
684+
(data_purge_count != mcps_purge_req_cnt)) {
685+
// error if mac data request sent or purging
685686
return false;
686687
}
687688

test/nanostack/unittest/stub/mac_mcps_sap_stub.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,9 @@ void mcps_sap_trig_tx(void *mac_ptr)
141141
{
142142
}
143143

144-
void mcps_sap_purge_reg_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mcps_purge_t *data)
144+
uint8_t mcps_sap_purge_reg_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mcps_purge_t *data)
145145
{
146+
return 0;
146147
}
147148

148149
int mac_convert_frame_type_to_fhss(uint8_t frame_type)

0 commit comments

Comments
 (0)