45
45
46
46
#define XACT_ID_MAX 0x7f
47
47
#define XACT_ID_NVAL 0xff
48
+ #define SEG_NVAL 0xff
48
49
49
50
#define RETRANSMIT_TIMEOUT K_MSEC(500)
50
51
#define BUF_TIMEOUT K_MSEC(400)
@@ -333,27 +334,27 @@ static void gen_prov_cont(struct prov_rx *rx, struct os_mbuf *buf)
333
334
return ;
334
335
}
335
336
336
- if (rx -> xact_id != link .rx .id ) {
337
+ if (!link .rx .seg &&
338
+ next_transaction_id (link .rx .id ) == rx -> xact_id ) {
339
+ BT_DBG ("Start segment lost" );
340
+
341
+ link .rx .id = rx -> xact_id ;
342
+
343
+ net_buf_simple_reset (link .rx .buf );
344
+ link .rx .seg = SEG_NVAL ;
345
+ link .rx .last_seg = SEG_NVAL ;
346
+
347
+ prov_clear_tx ();
348
+ } else if (rx -> xact_id != link .rx .id ) {
337
349
BT_WARN ("Data for unknown transaction (0x%x != 0x%x)" ,
338
- rx -> xact_id , link .rx .id );
350
+ rx -> xact_id , link .rx .id );
339
351
return ;
340
352
}
341
353
342
354
if (seg > link .rx .last_seg ) {
343
355
BT_ERR ("Invalid segment index %u" , seg );
344
356
prov_failed (PROV_ERR_NVAL_FMT );
345
357
return ;
346
- } else if (seg == link .rx .last_seg ) {
347
- u8_t expect_len ;
348
-
349
- expect_len = (link .rx .buf -> om_len - 20U -
350
- ((link .rx .last_seg - 1 ) * 23U ));
351
- if (expect_len != buf -> om_len ) {
352
- BT_ERR ("Incorrect last seg len: %u != %u" , expect_len ,
353
- buf -> om_len );
354
- prov_failed (PROV_ERR_NVAL_FMT );
355
- return ;
356
- }
357
358
}
358
359
359
360
if (!(link .rx .seg & BIT (seg ))) {
@@ -364,6 +365,19 @@ static void gen_prov_cont(struct prov_rx *rx, struct os_mbuf *buf)
364
365
memcpy (XACT_SEG_DATA (seg ), buf -> om_data , buf -> om_len );
365
366
XACT_SEG_RECV (seg );
366
367
368
+ if (seg == link .rx .last_seg && !(link .rx .seg & BIT (0 ))) {
369
+ uint8_t expect_len ;
370
+
371
+ expect_len = (link .rx .buf -> om_len - 20U -
372
+ ((link .rx .last_seg - 1 ) * 23U ));
373
+ if (expect_len != buf -> om_len ) {
374
+ BT_ERR ("Incorrect last seg len: %u != %u" , expect_len ,
375
+ buf -> om_len );
376
+ prov_failed (PROV_ERR_NVAL_FMT );
377
+ return ;
378
+ }
379
+ }
380
+
367
381
if (!link .rx .seg ) {
368
382
prov_msg_recv ();
369
383
}
@@ -391,29 +405,25 @@ static void gen_prov_ack(struct prov_rx *rx, struct os_mbuf *buf)
391
405
392
406
static void gen_prov_start (struct prov_rx * rx , struct os_mbuf * buf )
393
407
{
394
- u8_t expected_id = next_transaction_id (link .rx .id );
395
-
396
- if (link .rx .seg ) {
397
- if (rx -> xact_id != link .rx .id ) {
398
- BT_WARN ("Got Start while there are unreceived "
399
- "segments" );
400
- }
401
-
402
- return ;
403
- }
408
+ uint8_t seg = SEG_NVAL ;
404
409
405
410
if (rx -> xact_id == link .rx .id ) {
406
- if (!ack_pending ()) {
407
- BT_DBG ("Resending ack" );
408
- gen_prov_ack_send (rx -> xact_id );
409
- }
411
+ if (!link .rx .seg ) {
412
+ if (!ack_pending ()) {
413
+ BT_DBG ("Resending ack" );
414
+ gen_prov_ack_send (rx -> xact_id );
415
+ }
410
416
411
- return ;
412
- }
417
+ return ;
418
+ }
413
419
414
- if (rx -> xact_id != expected_id ) {
420
+ if (!(link .rx .seg & BIT (0 ))) {
421
+ BT_DBG ("Ignoring duplicate segment" );
422
+ return ;
423
+ }
424
+ } else if (rx -> xact_id != next_transaction_id (link .rx .id )) {
415
425
BT_WARN ("Unexpected xact 0x%x, expected 0x%x" , rx -> xact_id ,
416
- expected_id );
426
+ next_transaction_id ( link . rx . id ) );
417
427
return ;
418
428
}
419
429
@@ -439,8 +449,19 @@ static void gen_prov_start(struct prov_rx *rx, struct os_mbuf *buf)
439
449
440
450
prov_clear_tx ();
441
451
442
- link .rx .seg = (1 << (START_LAST_SEG (rx -> gpc ) + 1 )) - 1 ;
443
452
link .rx .last_seg = START_LAST_SEG (rx -> gpc );
453
+ if ((link .rx .seg & BIT (0 )) &&
454
+ (find_msb_set (~link .rx .seg ) >= link .rx .last_seg )) {
455
+ BT_ERR ("Invalid segment index %u" , seg );
456
+ prov_failed (PROV_ERR_NVAL_FMT );
457
+ return ;
458
+ }
459
+
460
+ if (link .rx .seg ) {
461
+ seg = link .rx .seg ;
462
+ }
463
+
464
+ link .rx .seg = seg & ((1 << (START_LAST_SEG (rx -> gpc ) + 1 )) - 1 );
444
465
memcpy (link .rx .buf -> om_data , buf -> om_data , buf -> om_len );
445
466
XACT_SEG_RECV (0 );
446
467
0 commit comments