@@ -436,13 +436,108 @@ static void avdtp_get_capabilities_rsp(struct bt_avdtp *session, struct net_buf
436
436
}
437
437
}
438
438
439
+ struct bt_avdtp_service_category_handler {
440
+ uint8_t min_len ;
441
+ uint8_t max_len ;
442
+ bool reconfig_support ;
443
+ uint8_t err_code ;
444
+ uint8_t (* handler )(struct net_buf * buf );
445
+ };
446
+
447
+ uint8_t bt_avdtp_check_media_recovery_type (struct net_buf * buf )
448
+ {
449
+ struct bt_avdtp_recovery_capabilities * cap
450
+ = (struct bt_avdtp_recovery_capabilities * )buf -> data ;
451
+
452
+ if (cap -> recovery_type != BT_AVDTP_RECOVERY_TYPE_FORBIDDEN &&
453
+ cap -> recovery_type != BT_ADVTP_RECOVERY_TYPE_RFC2733 ) {
454
+ return BT_AVDTP_BAD_RECOVERY_TYPE ;
455
+ }
456
+ return BT_AVDTP_SUCCESS ;
457
+ }
458
+
459
+ static struct bt_avdtp_service_category_handler category_handler [] = {
460
+ {0 , 0 , false, 0 , NULL }, /*None*/
461
+ {0 , 0 , false, BT_AVDTP_BAD_MEDIA_TRANSPORT_FORMAT ,
462
+ NULL }, /*BT_AVDTP_SERVICE_MEDIA_TRANSPORT*/
463
+ {0 , 0 , false, BT_AVDTP_BAD_LENGTH , NULL }, /*BT_AVDTP_SERVICE_REPORTING*/
464
+ {sizeof (struct bt_avdtp_recovery_capabilities ),
465
+ sizeof (struct bt_avdtp_recovery_capabilities ), false, BT_AVDTP_BAD_RECOVERY_FORMAT ,
466
+ bt_avdtp_check_media_recovery_type }, /*BT_AVDTP_SERVICE_MEDIA_RECOVERY*/
467
+ {sizeof (struct bt_avdtp_content_protection_capabilities ), UINT8_MAX ,
468
+ true, BT_AVDTP_BAD_CP_FORMAT , NULL }, /*BT_AVDTP_SERVICE_CONTENT_PROTECTION*/
469
+ {sizeof (struct bt_avdtp_header_compression_capabilities ),
470
+ sizeof (struct bt_avdtp_header_compression_capabilities ),
471
+ false, BT_AVDTP_BAD_LENGTH , NULL }, /*BT_AVDTP_SERVICE_HEADER_COMPRESSION*/
472
+ {sizeof (struct bt_avdtp_multiplexing_capabilities ),
473
+ sizeof (struct bt_avdtp_multiplexing_capabilities ),
474
+ false, BT_AVDTP_BAD_MULTIPLEXING_FORMAT , NULL }, /*BT_AVDTP_SERVICE_MULTIPLEXING*/
475
+ {sizeof (struct bt_avdtp_media_codec_capabilities ), UINT8_MAX ,
476
+ true, BT_AVDTP_BAD_LENGTH , NULL }, /*BT_AVDTP_SERVICE_MEDIA_CODEC*/
477
+ {0 , 0 , 0 , BT_AVDTP_BAD_LENGTH , NULL }, /*BT_AVDTP_SERVICE_DELAY_REPORTING*/
478
+ };
479
+
480
+ uint8_t bt_avdtp_check_service_category (struct net_buf * buf , uint8_t * service_category ,
481
+ bool reconfig )
482
+ {
483
+ struct bt_avdtp_generic_service_cap * hdr ;
484
+ uint8_t err ;
485
+ struct bt_avdtp_service_category_handler * handler ;
486
+ struct net_buf_simple_state state ;
487
+
488
+ if (buf -> len == 0U ) {
489
+ LOG_DBG ("Error: buf not valid" );
490
+ return BT_AVDTP_BAD_LENGTH ;
491
+ }
492
+
493
+ while (buf -> len > 0U ) {
494
+ if (buf -> len < sizeof (* hdr )) {
495
+ LOG_DBG ("Error: buf not valid" );
496
+ return BT_AVDTP_BAD_LENGTH ;
497
+ }
498
+
499
+ hdr = net_buf_pull_mem (buf , sizeof (* hdr ));
500
+ * service_category = hdr -> service_category ;
501
+
502
+ if (hdr -> service_category != 0 &&
503
+ hdr -> service_category < ARRAY_SIZE (category_handler )) {
504
+ handler = & category_handler [hdr -> service_category ];
505
+
506
+ if (hdr -> losc > buf -> len || hdr -> losc > handler -> max_len ||
507
+ hdr -> losc < handler -> min_len ) {
508
+ return handler -> err_code ;
509
+ }
510
+
511
+ if (!handler -> reconfig_support && reconfig ) {
512
+ return BT_AVDTP_INVALID_CAPABILITIES ;
513
+ }
514
+
515
+ if (handler -> handler != NULL ) {
516
+ net_buf_simple_save (& buf -> b , & state );
517
+ err = handler -> handler (buf );
518
+ net_buf_simple_restore (& buf -> b , & state );
519
+ if (err != BT_AVDTP_SUCCESS ) {
520
+ return err ;
521
+ }
522
+ }
523
+ net_buf_pull_mem (buf , hdr -> losc );
524
+ } else {
525
+ return BT_AVDTP_BAD_SERV_CATEGORY ;
526
+ }
527
+ }
528
+
529
+ return BT_AVDTP_SUCCESS ;
530
+ }
531
+
439
532
static void avdtp_process_configuration_cmd (struct bt_avdtp * session , struct net_buf * buf ,
440
533
uint8_t tid , bool reconfig )
441
534
{
442
535
int err = 0 ;
443
536
struct bt_avdtp_sep * sep ;
444
537
struct net_buf * rsp_buf ;
445
538
uint8_t avdtp_err_code = 0 ;
539
+ struct net_buf_simple_state state ;
540
+ uint8_t service_category = 0 ;
446
541
447
542
sep = avdtp_get_cmd_sep (buf , & avdtp_err_code );
448
543
avdtp_sep_lock (sep );
@@ -453,6 +548,9 @@ static void avdtp_process_configuration_cmd(struct bt_avdtp *session, struct net
453
548
err = - ENOTSUP ;
454
549
} else if (reconfig && session -> ops -> re_configuration_ind == NULL ) {
455
550
err = - ENOTSUP ;
551
+ } else if (!reconfig && sep -> sep_info .inuse == 1 ) {
552
+ avdtp_err_code = BT_AVDTP_SEP_IN_USE ;
553
+ err = - EBUSY ;
456
554
} else {
457
555
uint8_t expected_state ;
458
556
@@ -466,17 +564,29 @@ static void avdtp_process_configuration_cmd(struct bt_avdtp *session, struct net
466
564
err = - ENOTSUP ;
467
565
avdtp_err_code = BT_AVDTP_BAD_STATE ;
468
566
} else if (buf -> len >= 1U ) {
469
- uint8_t int_seid ;
567
+ uint8_t int_seid = 0 ;
568
+ uint8_t err_code = 0 ;
470
569
471
570
/* INT Stream Endpoint ID */
472
- int_seid = net_buf_pull_u8 (buf ) >> 2 ;
473
-
474
571
if (!reconfig ) {
475
- err = session -> ops -> set_configuration_ind (session , sep , int_seid ,
476
- buf , & avdtp_err_code );
572
+ /* int seid not in reconfig cmd*/
573
+ int_seid = net_buf_pull_u8 (buf ) >> 2 ;
574
+ }
575
+ net_buf_simple_save (& buf -> b , & state );
576
+ err_code = bt_avdtp_check_service_category (buf , & service_category ,
577
+ reconfig );
578
+ net_buf_simple_restore (& buf -> b , & state );
579
+ if (err_code ) {
580
+ avdtp_err_code = err_code ;
581
+ err = - ENOTSUP ;
477
582
} else {
478
- err = session -> ops -> re_configuration_ind (session , sep , int_seid ,
479
- buf , & avdtp_err_code );
583
+ if (!reconfig ) {
584
+ err = session -> ops -> set_configuration_ind (
585
+ session , sep , int_seid , buf , & avdtp_err_code );
586
+ } else {
587
+ err = session -> ops -> re_configuration_ind (session , sep , buf ,
588
+ & avdtp_err_code );
589
+ }
480
590
}
481
591
} else {
482
592
LOG_WRN ("Invalid INT SEID" );
@@ -499,8 +609,8 @@ static void avdtp_process_configuration_cmd(struct bt_avdtp *session, struct net
499
609
}
500
610
501
611
LOG_DBG ("set configuration err code:%d" , avdtp_err_code );
502
- /* Service Category: Media Codec */
503
- net_buf_add_u8 (rsp_buf , BT_AVDTP_SERVICE_MEDIA_CODEC );
612
+ /* error Service Category*/
613
+ net_buf_add_u8 (rsp_buf , service_category );
504
614
/* ERROR CODE */
505
615
net_buf_add_u8 (rsp_buf , avdtp_err_code );
506
616
}
@@ -705,6 +815,7 @@ static void avdtp_start_cmd(struct bt_avdtp *session, struct net_buf *buf, uint8
705
815
}
706
816
707
817
LOG_DBG ("start err code:%d" , avdtp_err_code );
818
+ net_buf_add_u8 (rsp_buf , sep -> sep_info .id << 2 );
708
819
net_buf_add_u8 (rsp_buf , avdtp_err_code );
709
820
}
710
821
@@ -860,6 +971,7 @@ static void avdtp_suspend_cmd(struct bt_avdtp *session, struct net_buf *buf, uin
860
971
}
861
972
862
973
LOG_DBG ("suspend err code:%d" , avdtp_err_code );
974
+ net_buf_add_u8 (rsp_buf , sep -> sep_info .id << 2 );
863
975
net_buf_add_u8 (rsp_buf , avdtp_err_code );
864
976
}
865
977
@@ -1555,12 +1667,14 @@ static int avdtp_process_configure_command(struct bt_avdtp *session, uint8_t cmd
1555
1667
/* Body of the message */
1556
1668
/* ACP Stream Endpoint ID */
1557
1669
net_buf_add_u8 (buf , (param -> acp_stream_ep_id << 2U ));
1558
- /* INT Stream Endpoint ID */
1559
- net_buf_add_u8 (buf , (param -> int_stream_endpoint_id << 2U ));
1560
- /* Service Category: Media Transport */
1561
- net_buf_add_u8 (buf , BT_AVDTP_SERVICE_MEDIA_TRANSPORT );
1562
- /* LOSC */
1563
- net_buf_add_u8 (buf , 0 );
1670
+ if (cmd == BT_AVDTP_SET_CONFIGURATION ) {
1671
+ /* INT Stream Endpoint ID */
1672
+ net_buf_add_u8 (buf , (param -> int_stream_endpoint_id << 2U ));
1673
+ /* Service Category: Media Transport */
1674
+ net_buf_add_u8 (buf , BT_AVDTP_SERVICE_MEDIA_TRANSPORT );
1675
+ /* LOSC */
1676
+ net_buf_add_u8 (buf , 0 );
1677
+ }
1564
1678
/* Service Category: Media Codec */
1565
1679
net_buf_add_u8 (buf , BT_AVDTP_SERVICE_MEDIA_CODEC );
1566
1680
/* LOSC */
0 commit comments