Skip to content

Commit 853ef58

Browse files
committed
GH-47: Add fail safe to tx queue
This should prevent a faulty frame to block all the tx queue by itself. Forwarded: #47 Bug-SiliconLabs: UIC-3335 Bug-Github: #47
1 parent 954fdce commit 853ef58

File tree

2 files changed

+89
-6
lines changed

2 files changed

+89
-6
lines changed

applications/zpc/components/zwave/zwave_tx/src/zwave_tx.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,16 @@ sl_status_t
141141

142142
sl_log_error(LOG_TAG, "Tx Queue rejected new frame request.");
143143
tx_queue.log(true);
144+
// Add a failsafe in case the queue is getting blocked
145+
// This prevent one faulty device to block the whole queue
146+
// The subsequent frames will most likely discarded since they timed out by now
147+
if (tx_queue.size() == ZWAVE_TX_QUEUE_BUFFER_SIZE) {
148+
sl_log_info(
149+
LOG_TAG,
150+
"Abort transmission of first frame in queue due to full Tx Queue.");
151+
zwave_tx_process_abort_transmission(
152+
tx_queue.first_in_queue()->zwave_tx_session_id);
153+
}
144154
return SL_STATUS_FAIL;
145155
}
146156

applications/zpc/components/zwave/zwave_tx/test/zwave_tx_test.c

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2064,6 +2064,8 @@ void test_full_zwave_tx_queue()
20642064
&test_tx_session_id_2));
20652065
contiki_test_helper_run(0);
20662066

2067+
2068+
20672069
for (int i = 1; i < ZWAVE_TX_QUEUE_BUFFER_SIZE; ++i) {
20682070
TEST_ASSERT_EQUAL(SL_STATUS_OK,
20692071
zwave_tx_send_data(&test_connection_1,
@@ -2074,9 +2076,14 @@ void test_full_zwave_tx_queue()
20742076
(void *)&my_user_pointer,
20752077
&test_tx_session_id));
20762078
}
2079+
zwave_tx_session_id_t second_message_id = test_tx_session_id;
20772080

20782081
TEST_ASSERT_EQUAL(ZWAVE_TX_QUEUE_BUFFER_SIZE, zwave_tx_get_queue_size());
20792082

2083+
zwave_controller_transport_abort_send_data_ExpectAndReturn(
2084+
test_tx_session_id_2,
2085+
SL_STATUS_FAIL);
2086+
20802087
// Now there is no more queue space:
20812088
TEST_ASSERT_EQUAL(SL_STATUS_FAIL,
20822089
zwave_tx_send_data(&test_connection_1,
@@ -2087,14 +2094,11 @@ void test_full_zwave_tx_queue()
20872094
(void *)&my_user_pointer,
20882095
&test_tx_session_id));
20892096

2090-
// Get one free slot
2091-
on_zwave_transport_send_data_complete(TRANSMIT_COMPLETE_OK,
2092-
NULL,
2093-
test_tx_session_id_2);
2094-
2097+
// Process events
20952098
contiki_test_helper_run(0);
20962099
TEST_ASSERT_EQUAL(1, send_done_count);
2097-
TEST_ASSERT_EQUAL(TRANSMIT_COMPLETE_OK, send_done_status);
2100+
TEST_ASSERT_EQUAL(TRANSMIT_COMPLETE_FAIL, send_done_status);
2101+
20982102

20992103
// Now queueing should work again:
21002104
TEST_ASSERT_EQUAL(SL_STATUS_OK,
@@ -2106,6 +2110,9 @@ void test_full_zwave_tx_queue()
21062110
(void *)&my_user_pointer,
21072111
&test_tx_session_id));
21082112

2113+
zwave_controller_transport_abort_send_data_ExpectAndReturn(
2114+
second_message_id,
2115+
SL_STATUS_FAIL);
21092116
// And now we are full again:
21102117
TEST_ASSERT_EQUAL(SL_STATUS_FAIL,
21112118
zwave_tx_send_data(&test_connection_1,
@@ -2117,6 +2124,72 @@ void test_full_zwave_tx_queue()
21172124
&test_tx_session_id));
21182125
}
21192126

2127+
void test_full_zwave_tx_queue_with_timeouts()
2128+
{
2129+
// We do not care about interactions with the transports for this test.
2130+
zwave_controller_transport_send_data_IgnoreAndReturn(SL_STATUS_OK);
2131+
2132+
// Queue a first element:
2133+
TEST_ASSERT_EQUAL(SL_STATUS_OK,
2134+
zwave_tx_send_data(&test_connection_2,
2135+
sizeof(test_expected_frame_data_2),
2136+
test_expected_frame_data_2,
2137+
&test_tx_options_2,
2138+
send_data_callback,
2139+
(void *)&my_user_pointer,
2140+
&test_tx_session_id_2));
2141+
contiki_test_helper_run(0);
2142+
2143+
2144+
2145+
for (int i = 1; i < ZWAVE_TX_QUEUE_BUFFER_SIZE; ++i) {
2146+
TEST_ASSERT_EQUAL(SL_STATUS_OK,
2147+
zwave_tx_send_data(&test_connection_2,
2148+
sizeof(test_expected_frame_data_2),
2149+
test_expected_frame_data_2,
2150+
&test_tx_options_2,
2151+
send_data_callback,
2152+
(void *)&my_user_pointer,
2153+
&test_tx_session_id));
2154+
}
2155+
//zwave_tx_session_id_t second_message_id = test_tx_session_id;
2156+
2157+
TEST_ASSERT_EQUAL(ZWAVE_TX_QUEUE_BUFFER_SIZE, zwave_tx_get_queue_size());
2158+
2159+
zwave_controller_transport_abort_send_data_ExpectAndReturn(
2160+
test_tx_session_id_2,
2161+
SL_STATUS_FAIL);
2162+
2163+
// Now there is no more queue space:
2164+
TEST_ASSERT_EQUAL(SL_STATUS_FAIL,
2165+
zwave_tx_send_data(&test_connection_1,
2166+
sizeof(test_expected_frame_data_1),
2167+
test_expected_frame_data_1,
2168+
&test_tx_options_1,
2169+
send_data_callback,
2170+
(void *)&my_user_pointer,
2171+
&test_tx_session_id));
2172+
2173+
// Process events
2174+
contiki_test_helper_run(1000);
2175+
TEST_ASSERT_EQUAL(ZWAVE_TX_QUEUE_BUFFER_SIZE, send_done_count);
2176+
TEST_ASSERT_EQUAL(TRANSMIT_COMPLETE_FAIL, send_done_status);
2177+
2178+
2179+
// Now queueing should work again:
2180+
for (int i = 1; i < ZWAVE_TX_QUEUE_BUFFER_SIZE; ++i) {
2181+
TEST_ASSERT_EQUAL(SL_STATUS_OK,
2182+
zwave_tx_send_data(&test_connection_2,
2183+
sizeof(test_expected_frame_data_2),
2184+
test_expected_frame_data_2,
2185+
&test_tx_options_2,
2186+
send_data_callback,
2187+
(void *)&my_user_pointer,
2188+
&test_tx_session_id));
2189+
}
2190+
}
2191+
2192+
21202193
void test_additional_back_off()
21212194
{
21222195
zwave_node_id_t chatty_node_id = 23;

0 commit comments

Comments
 (0)