@@ -326,6 +326,33 @@ static int control_point_send(struct has_client *client, struct net_buf_simple *
326326 return - ECANCELED ;
327327}
328328
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+
329356static int bt_has_cp_read_preset_rsp (struct has_client * client , const struct has_preset * preset ,
330357 bool is_last )
331358{
@@ -393,6 +420,54 @@ static void process_control_point_work(struct k_work *work)
393420 }
394421}
395422
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+
396471static uint8_t handle_read_preset_req (struct bt_conn * conn , struct net_buf_simple * buf )
397472{
398473 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)
524599 return - ENOMEM ;
525600 }
526601
527- return 0 ;
602+ return bt_has_cp_generic_update ( preset , BT_HAS_IS_LAST ) ;
528603}
529604
530605int bt_has_preset_unregister (uint8_t index )
531606{
532607 struct has_preset * preset = NULL ;
533608
609+ NET_BUF_SIMPLE_DEFINE (buf , sizeof (struct bt_has_cp_hdr ) +
610+ sizeof (struct bt_has_cp_preset_changed ) + sizeof (uint8_t ));
611+
534612 CHECKIF (index == BT_HAS_PRESET_INDEX_NONE ) {
535613 BT_ERR ("index is invalid" );
536614 return - EINVAL ;
@@ -541,8 +619,61 @@ int bt_has_preset_unregister(uint8_t index)
541619 return - ENOENT ;
542620 }
543621
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+
544625 preset_free (preset );
545626
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+
546677 return 0 ;
547678}
548679
0 commit comments