7
7
#include "settings_test_backend.h"
8
8
#include "mesh/mesh.h"
9
9
#include "mesh/net.h"
10
+ #include "mesh/rpl.h"
11
+ #include "mesh/transport.h"
10
12
11
13
#define LOG_MODULE_NAME test_rpc
12
14
@@ -192,6 +194,214 @@ static void test_rx_power_replay_attack(void)
192
194
PASS ();
193
195
}
194
196
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
+
195
405
#define TEST_CASE (role , name , description ) \
196
406
{ \
197
407
.test_id = "rpc_" #role "_" #name, \
@@ -204,9 +414,12 @@ static void test_rx_power_replay_attack(void)
204
414
static const struct bst_test_instance test_rpc [] = {
205
415
TEST_CASE (tx , immediate_replay_attack , "RPC: perform replay attack immediately" ),
206
416
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" ),
207
418
208
419
TEST_CASE (rx , immediate_replay_attack , "RPC: device under immediate attack" ),
209
420
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" ),
210
423
BSTEST_END_MARKER
211
424
};
212
425
0 commit comments