@@ -326,6 +326,33 @@ static int control_point_send(struct has_client *client, struct net_buf_simple *
326
326
return - ECANCELED ;
327
327
}
328
328
329
+ static int control_point_send_all (struct net_buf_simple * buf )
330
+ {
331
+ int result = 0 ;
332
+
333
+ for (size_t i = 0 ; i < ARRAY_SIZE (has_client_list ); i ++ ) {
334
+ struct has_client * client = & has_client_list [i ];
335
+ int err ;
336
+
337
+ if (!client -> conn ) {
338
+ continue ;
339
+ }
340
+
341
+ if (!bt_gatt_is_subscribed (client -> conn , PRESET_CONTROL_POINT_ATTR ,
342
+ BT_GATT_CCC_NOTIFY | BT_GATT_CCC_INDICATE )) {
343
+ continue ;
344
+ }
345
+
346
+ err = control_point_send (client , buf );
347
+ if (err ) {
348
+ result = err ;
349
+ /* continue anyway */
350
+ }
351
+ }
352
+
353
+ return result ;
354
+ }
355
+
329
356
static int bt_has_cp_read_preset_rsp (struct has_client * client , const struct has_preset * preset ,
330
357
bool is_last )
331
358
{
@@ -393,6 +420,54 @@ static void process_control_point_work(struct k_work *work)
393
420
}
394
421
}
395
422
423
+ static uint8_t get_prev_preset_index (struct has_preset * preset )
424
+ {
425
+ const struct has_preset * prev = NULL ;
426
+
427
+ for (size_t i = 0 ; i < ARRAY_SIZE (has_preset_list ); i ++ ) {
428
+ const struct has_preset * tmp = & has_preset_list [i ];
429
+
430
+ if (tmp -> index == BT_HAS_PRESET_INDEX_NONE || tmp == preset ) {
431
+ break ;
432
+ }
433
+
434
+ prev = tmp ;
435
+ }
436
+
437
+ return prev ? prev -> index : BT_HAS_PRESET_INDEX_NONE ;
438
+ }
439
+
440
+ static void preset_changed_prepare (struct net_buf_simple * buf , uint8_t change_id , uint8_t is_last )
441
+ {
442
+ struct bt_has_cp_hdr * hdr ;
443
+ struct bt_has_cp_preset_changed * preset_changed ;
444
+
445
+ hdr = net_buf_simple_add (buf , sizeof (* hdr ));
446
+ hdr -> opcode = BT_HAS_OP_PRESET_CHANGED ;
447
+ preset_changed = net_buf_simple_add (buf , sizeof (* preset_changed ));
448
+ preset_changed -> change_id = change_id ;
449
+ preset_changed -> is_last = is_last ;
450
+ }
451
+
452
+ static int bt_has_cp_generic_update (struct has_preset * preset , uint8_t is_last )
453
+ {
454
+ struct bt_has_cp_generic_update * generic_update ;
455
+
456
+ NET_BUF_SIMPLE_DEFINE (buf , sizeof (struct bt_has_cp_hdr ) +
457
+ sizeof (struct bt_has_cp_preset_changed ) +
458
+ sizeof (struct bt_has_cp_generic_update ) + BT_HAS_PRESET_NAME_MAX );
459
+
460
+ preset_changed_prepare (& buf , BT_HAS_CHANGE_ID_GENERIC_UPDATE , is_last );
461
+
462
+ generic_update = net_buf_simple_add (& buf , sizeof (* generic_update ));
463
+ generic_update -> prev_index = get_prev_preset_index (preset );
464
+ generic_update -> index = preset -> index ;
465
+ generic_update -> properties = preset -> properties ;
466
+ net_buf_simple_add_mem (& buf , preset -> name , strlen (preset -> name ));
467
+
468
+ return control_point_send_all (& buf );
469
+ }
470
+
396
471
static uint8_t handle_read_preset_req (struct bt_conn * conn , struct net_buf_simple * buf )
397
472
{
398
473
const struct bt_has_cp_read_presets_req * req ;
@@ -524,13 +599,16 @@ int bt_has_preset_register(const struct bt_has_preset_register_param *param)
524
599
return - ENOMEM ;
525
600
}
526
601
527
- return 0 ;
602
+ return bt_has_cp_generic_update ( preset , BT_HAS_IS_LAST ) ;
528
603
}
529
604
530
605
int bt_has_preset_unregister (uint8_t index )
531
606
{
532
607
struct has_preset * preset = NULL ;
533
608
609
+ NET_BUF_SIMPLE_DEFINE (buf , sizeof (struct bt_has_cp_hdr ) +
610
+ sizeof (struct bt_has_cp_preset_changed ) + sizeof (uint8_t ));
611
+
534
612
CHECKIF (index == BT_HAS_PRESET_INDEX_NONE ) {
535
613
BT_ERR ("index is invalid" );
536
614
return - EINVAL ;
@@ -541,8 +619,61 @@ int bt_has_preset_unregister(uint8_t index)
541
619
return - ENOENT ;
542
620
}
543
621
622
+ preset_changed_prepare (& buf , BT_HAS_CHANGE_ID_PRESET_DELETED , BT_HAS_IS_LAST );
623
+ net_buf_simple_add_u8 (& buf , preset -> index );
624
+
544
625
preset_free (preset );
545
626
627
+ return control_point_send_all (& buf );
628
+ }
629
+
630
+ int bt_has_preset_available (uint8_t index )
631
+ {
632
+ struct has_preset * preset = NULL ;
633
+
634
+ CHECKIF (index == BT_HAS_PRESET_INDEX_NONE ) {
635
+ BT_ERR ("index is invalid" );
636
+ return - EINVAL ;
637
+ }
638
+
639
+ /* toggle property bit if needed */
640
+ if (!(preset -> properties & BT_HAS_PROP_AVAILABLE )) {
641
+ NET_BUF_SIMPLE_DEFINE (buf , sizeof (struct bt_has_cp_hdr ) +
642
+ sizeof (struct bt_has_cp_preset_changed ) + sizeof (uint8_t ));
643
+
644
+ preset -> properties ^= BT_HAS_PROP_AVAILABLE ;
645
+
646
+ preset_changed_prepare (& buf , BT_HAS_CHANGE_ID_PRESET_AVAILABLE , BT_HAS_IS_LAST );
647
+ net_buf_simple_add_u8 (& buf , preset -> index );
648
+
649
+ return control_point_send_all (& buf );
650
+ }
651
+
652
+ return 0 ;
653
+ }
654
+
655
+ int bt_has_preset_unavailable (uint8_t index )
656
+ {
657
+ struct has_preset * preset = NULL ;
658
+
659
+ CHECKIF (index == BT_HAS_PRESET_INDEX_NONE ) {
660
+ BT_ERR ("index is invalid" );
661
+ return - EINVAL ;
662
+ }
663
+
664
+ /* toggle property bit if needed */
665
+ if (preset -> properties & BT_HAS_PROP_AVAILABLE ) {
666
+ NET_BUF_SIMPLE_DEFINE (buf , sizeof (struct bt_has_cp_hdr ) +
667
+ sizeof (struct bt_has_cp_preset_changed ) + sizeof (uint8_t ));
668
+
669
+ preset -> properties ^= BT_HAS_PROP_AVAILABLE ;
670
+
671
+ preset_changed_prepare (& buf , BT_HAS_CHANGE_ID_PRESET_UNAVAILABLE , BT_HAS_IS_LAST );
672
+ net_buf_simple_add_u8 (& buf , preset -> index );
673
+
674
+ return control_point_send_all (& buf );
675
+ }
676
+
546
677
return 0 ;
547
678
}
548
679
0 commit comments