77#include "settings_test_backend.h"
88#include "mesh/mesh.h"
99#include "mesh/net.h"
10+ #include "mesh/rpl.h"
11+ #include "mesh/transport.h"
1012
1113#define LOG_MODULE_NAME test_rpc
1214
@@ -192,6 +194,214 @@ static void test_rx_power_replay_attack(void)
192194 PASS ();
193195}
194196
197+ static void send_end_cb (int err , void * cb_data )
198+ {
199+ struct k_sem * sem = cb_data ;
200+
201+ ASSERT_EQUAL (err , 0 );
202+ k_sem_give (sem );
203+ }
204+
205+ static bool msg_send (uint16_t src , uint16_t dst )
206+ {
207+ struct bt_mesh_send_cb cb = {
208+ .end = send_end_cb ,
209+ };
210+ struct bt_mesh_msg_ctx ctx = {
211+ .net_idx = 0 ,
212+ .app_idx = 0 ,
213+ .addr = dst ,
214+ .send_rel = false,
215+ .send_ttl = BT_MESH_TTL_DEFAULT ,
216+ };
217+ struct bt_mesh_net_tx tx = {
218+ .ctx = & ctx ,
219+ .src = src ,
220+ };
221+ struct k_sem sem ;
222+ int err ;
223+
224+ k_sem_init (& sem , 0 , 1 );
225+ BT_MESH_MODEL_BUF_DEFINE (msg , TEST_MSG_OP_1 , 0 );
226+
227+ bt_mesh_model_msg_init (& msg , TEST_MSG_OP_1 );
228+
229+ err = bt_mesh_trans_send (& tx , & msg , & cb , & sem );
230+ if (err ) {
231+ LOG_ERR ("Failed to send message (err %d)" , err );
232+ return false;
233+ }
234+
235+ err = k_sem_take (& sem , K_SECONDS (10 ));
236+ if (err ) {
237+ LOG_ERR ("Send timed out (err %d)" , err );
238+ return false;
239+ }
240+
241+ return true;
242+ }
243+
244+ static bool msg_recv (uint16_t expected_addr )
245+ {
246+ struct bt_mesh_test_msg msg ;
247+ int err ;
248+
249+ err = bt_mesh_test_recv_msg (& msg , K_SECONDS (10 ));
250+ if (err ) {
251+ LOG_ERR ("Failed to receive message from %u (err %d)" , expected_addr , err );
252+ return false;
253+ }
254+
255+ LOG_DBG ("Received msg from %u" , msg .ctx .addr );
256+ ASSERT_EQUAL (expected_addr , msg .ctx .addr );
257+
258+ return true;
259+ }
260+
261+ static bool ivi_update_toggle (void )
262+ {
263+ bool res ;
264+
265+ bt_mesh_iv_update_test (true);
266+ res = bt_mesh_iv_update ();
267+ bt_mesh_iv_update_test (false);
268+
269+ return res ;
270+ }
271+
272+ static void test_rx_rpl_frag (void )
273+ {
274+ settings_test_backend_clear ();
275+ bt_mesh_test_setup ();
276+
277+ k_sleep (K_SECONDS (10 ));
278+
279+ /* Wait 3 messages from different sources. */
280+ for (int i = 0 ; i < 3 ; i ++ ) {
281+ ASSERT_TRUE (msg_recv (100 + i ));
282+ }
283+
284+ /* Ask tx node to proceed to next test step. */
285+ ASSERT_TRUE (msg_send (rx_cfg .addr , tx_cfg .addr ));
286+
287+ /* Start IVI Update. This will set old_iv for all entries in RPL to 1. */
288+ ASSERT_TRUE (ivi_update_toggle ());
289+
290+ /* Receive messages from even nodes with new IVI. RPL entry with odd address will stay
291+ * with old IVI.
292+ */
293+ ASSERT_TRUE (msg_recv (100 ));
294+ ASSERT_TRUE (msg_recv (102 ));
295+
296+ /* Ask tx node to proceed to next test step. */
297+ ASSERT_TRUE (msg_send (rx_cfg .addr , tx_cfg .addr ));
298+
299+ /* Complete IVI Update. */
300+ ASSERT_FALSE (ivi_update_toggle ());
301+
302+ /* Bump SeqNum in RPL for even addresses. */
303+ ASSERT_TRUE (msg_recv (100 ));
304+ ASSERT_TRUE (msg_recv (102 ));
305+
306+ /* Start IVI Update again. */
307+ /* RPL entry with odd address should be removed causing fragmentation in RPL. old_iv flag
308+ * for even entries will be set to 1.
309+ */
310+ ASSERT_TRUE (ivi_update_toggle ());
311+
312+ /* Ask tx node to proceed to next test step. */
313+ ASSERT_TRUE (msg_send (rx_cfg .addr , tx_cfg .addr ));
314+
315+ /* Complete IVI Update. */
316+ ASSERT_FALSE (ivi_update_toggle ());
317+
318+ /* Odd address entry should have been removed keeping even addresses accessible. */
319+ struct bt_mesh_rpl * rpl = NULL ;
320+ struct bt_mesh_net_rx rx = {
321+ .old_iv = 1 ,
322+ .seq = 0 ,
323+ .ctx .addr = 100 ,
324+ .local_match = 1 ,
325+ };
326+ ASSERT_TRUE (bt_mesh_rpl_check (& rx , & rpl ));
327+ rx .ctx .addr = 101 ;
328+ ASSERT_FALSE (bt_mesh_rpl_check (& rx , & rpl ));
329+ rx .ctx .addr = 102 ;
330+ ASSERT_TRUE (bt_mesh_rpl_check (& rx , & rpl ));
331+
332+ /* Let the settings store RPL. */
333+ k_sleep (K_SECONDS (CONFIG_BT_MESH_RPL_STORE_TIMEOUT ));
334+
335+ PASS ();
336+ }
337+
338+ static void test_tx_rpl_frag (void )
339+ {
340+ settings_test_backend_clear ();
341+ bt_mesh_test_setup ();
342+
343+ k_sleep (K_SECONDS (10 ));
344+
345+ /* Send message for 3 different addresses. */
346+ for (size_t i = 0 ; i < 3 ; i ++ ) {
347+ ASSERT_TRUE (msg_send (100 + i , rx_cfg .addr ));
348+ }
349+
350+ k_sleep (K_SECONDS (3 ));
351+
352+ /* Wait for the rx node. */
353+ ASSERT_TRUE (msg_recv (rx_cfg .addr ));
354+
355+ /* Start IVI Update. */
356+ ASSERT_TRUE (ivi_update_toggle ());
357+
358+ /* Send msg from elem 1 and 3 with new IVI. 2nd elem should have old IVI. */
359+ ASSERT_TRUE (msg_send (100 , rx_cfg .addr ));
360+ ASSERT_TRUE (msg_send (102 , rx_cfg .addr ));
361+
362+ /* Wait for the rx node. */
363+ ASSERT_TRUE (msg_recv (rx_cfg .addr ));
364+
365+ /* Complete IVI Update. */
366+ ASSERT_FALSE (ivi_update_toggle ());
367+
368+ /* Send message from even addresses with new IVI keeping odd address with old IVI. */
369+ ASSERT_TRUE (msg_send (100 , rx_cfg .addr ));
370+ ASSERT_TRUE (msg_send (102 , rx_cfg .addr ));
371+
372+ /* Start IVI Update again to be in sync with rx node. */
373+ ASSERT_TRUE (ivi_update_toggle ());
374+
375+ /* Wait for rx node. */
376+ ASSERT_TRUE (msg_recv (rx_cfg .addr ));
377+
378+ /* Complete IVI Update. */
379+ ASSERT_FALSE (ivi_update_toggle ());
380+
381+ PASS ();
382+ }
383+
384+ static void test_rx_reboot_after_defrag (void )
385+ {
386+ bt_mesh_test_setup ();
387+
388+ /* Test that RPL entries are restored correctly after defrag and reboot. */
389+ struct bt_mesh_rpl * rpl = NULL ;
390+ struct bt_mesh_net_rx rx = {
391+ .old_iv = 1 ,
392+ .seq = 0 ,
393+ .ctx .addr = 100 ,
394+ .local_match = 1 ,
395+ };
396+ ASSERT_TRUE (bt_mesh_rpl_check (& rx , & rpl ));
397+ rx .ctx .addr = 101 ;
398+ ASSERT_FALSE (bt_mesh_rpl_check (& rx , & rpl ));
399+ rx .ctx .addr = 102 ;
400+ ASSERT_TRUE (bt_mesh_rpl_check (& rx , & rpl ));
401+
402+ PASS ();
403+ }
404+
195405#define TEST_CASE (role , name , description ) \
196406 { \
197407 .test_id = "rpc_" #role "_" #name, \
@@ -204,9 +414,12 @@ static void test_rx_power_replay_attack(void)
204414static const struct bst_test_instance test_rpc [] = {
205415 TEST_CASE (tx , immediate_replay_attack , "RPC: perform replay attack immediately" ),
206416 TEST_CASE (tx , power_replay_attack , "RPC: perform replay attack after power cycle" ),
417+ TEST_CASE (tx , rpl_frag , "RPC: Send messages after double IVI Update" ),
207418
208419 TEST_CASE (rx , immediate_replay_attack , "RPC: device under immediate attack" ),
209420 TEST_CASE (rx , power_replay_attack , "RPC: device under power cycle reply attack" ),
421+ TEST_CASE (rx , rpl_frag , "RPC: Test RPL fragmentation after double IVI Update" ),
422+ TEST_CASE (rx , reboot_after_defrag , "RPC: Test PRL after defrag and reboot" ),
210423 BSTEST_END_MARKER
211424};
212425
0 commit comments