32
32
#include <zephyr/types.h>
33
33
34
34
#include "aics_internal.h"
35
+ #include "common/bt_str.h"
35
36
36
37
LOG_MODULE_REGISTER (bt_aics_client , CONFIG_BT_AICS_CLIENT_LOG_LEVEL );
37
38
@@ -60,8 +61,8 @@ uint8_t aics_client_notify_handler(struct bt_conn *conn, struct bt_gatt_subscrib
60
61
{
61
62
uint16_t handle = params -> value_handle ;
62
63
struct bt_aics * inst ;
63
- struct bt_aics_state * state ;
64
- uint8_t * status ;
64
+ const struct bt_aics_state * state ;
65
+ const uint8_t * status ;
65
66
66
67
if (conn == NULL ) {
67
68
return BT_GATT_ITER_CONTINUE ;
@@ -80,7 +81,7 @@ uint8_t aics_client_notify_handler(struct bt_conn *conn, struct bt_gatt_subscrib
80
81
81
82
if (handle == inst -> cli .state_handle ) {
82
83
if (length == sizeof (* state )) {
83
- state = (struct bt_aics_state * )data ;
84
+ state = (const struct bt_aics_state * )data ;
84
85
LOG_DBG ("Inst %p: Gain %d, mute %u, gain_mode %u, counter %u" , inst ,
85
86
state -> gain , state -> mute , state -> gain_mode , state -> change_counter );
86
87
@@ -94,7 +95,7 @@ uint8_t aics_client_notify_handler(struct bt_conn *conn, struct bt_gatt_subscrib
94
95
}
95
96
} else if (handle == inst -> cli .status_handle ) {
96
97
if (length == sizeof (* status )) {
97
- status = (uint8_t * )data ;
98
+ status = (const uint8_t * )data ;
98
99
LOG_DBG ("Inst %p: Status %u" , inst , * status );
99
100
if (inst -> cli .cb && inst -> cli .cb -> status ) {
100
101
inst -> cli .cb -> status (inst , 0 , * status );
@@ -116,6 +117,8 @@ uint8_t aics_client_notify_handler(struct bt_conn *conn, struct bt_gatt_subscrib
116
117
if (inst -> cli .cb && inst -> cli .cb -> description ) {
117
118
inst -> cli .cb -> description (inst , 0 , desc );
118
119
}
120
+ } else {
121
+ LOG_DBG ("Receive notification on unexpected handle 0x%04X" , handle );
119
122
}
120
123
121
124
return BT_GATT_ITER_CONTINUE ;
@@ -127,7 +130,7 @@ static uint8_t aics_client_read_state_cb(struct bt_conn *conn, uint8_t err,
127
130
{
128
131
int cb_err = err ;
129
132
struct bt_aics * inst = lookup_aics_by_handle (conn , params -> single .handle );
130
- struct bt_aics_state * state = (struct bt_aics_state * )data ;
133
+ const struct bt_aics_state * state = (const struct bt_aics_state * )data ;
131
134
132
135
memset (params , 0 , sizeof (* params ));
133
136
@@ -176,7 +179,8 @@ static uint8_t aics_client_read_gain_settings_cb(struct bt_conn *conn, uint8_t e
176
179
{
177
180
int cb_err = err ;
178
181
struct bt_aics * inst = lookup_aics_by_handle (conn , params -> single .handle );
179
- struct bt_aics_gain_settings * gain_settings = (struct bt_aics_gain_settings * )data ;
182
+ const struct bt_aics_gain_settings * gain_settings =
183
+ (const struct bt_aics_gain_settings * )data ;
180
184
181
185
memset (params , 0 , sizeof (* params ));
182
186
@@ -223,7 +227,7 @@ static uint8_t aics_client_read_type_cb(struct bt_conn *conn, uint8_t err,
223
227
const void * data , uint16_t length )
224
228
{
225
229
int cb_err = err ;
226
- uint8_t * type = (uint8_t * )data ;
230
+ const uint8_t * type = (const uint8_t * )data ;
227
231
struct bt_aics * inst = lookup_aics_by_handle (conn , params -> single .handle );
228
232
229
233
memset (params , 0 , sizeof (* params ));
@@ -268,7 +272,7 @@ static uint8_t aics_client_read_status_cb(struct bt_conn *conn, uint8_t err,
268
272
const void * data , uint16_t length )
269
273
{
270
274
int cb_err = err ;
271
- uint8_t * status = (uint8_t * )data ;
275
+ const uint8_t * status = (const uint8_t * )data ;
272
276
struct bt_aics * inst = lookup_aics_by_handle (conn , params -> single .handle );
273
277
274
278
memset (params , 0 , sizeof (* params ));
@@ -352,7 +356,7 @@ static uint8_t internal_read_state_cb(struct bt_conn *conn, uint8_t err,
352
356
{
353
357
int cb_err = err ;
354
358
struct bt_aics * inst = lookup_aics_by_handle (conn , params -> single .handle );
355
- struct bt_aics_state * state = (struct bt_aics_state * )data ;
359
+ const struct bt_aics_state * state = (const struct bt_aics_state * )data ;
356
360
357
361
memset (params , 0 , sizeof (* params ));
358
362
@@ -389,6 +393,9 @@ static uint8_t internal_read_state_cb(struct bt_conn *conn, uint8_t err,
389
393
LOG_DBG ("Invalid length %u (expected %zu)" , length , sizeof (* state ));
390
394
cb_err = BT_ATT_ERR_UNLIKELY ;
391
395
}
396
+ } else {
397
+ /* Since we return BT_GATT_ITER_STOP this should never happen */
398
+ __ASSERT (false, "Unexpected NULL data without error" );
392
399
}
393
400
394
401
if (cb_err ) {
@@ -439,6 +446,8 @@ static void aics_client_write_aics_cp_cb(struct bt_conn *conn, uint8_t err,
439
446
/* Wait for read callback */
440
447
return ;
441
448
}
449
+ } else {
450
+ /* Write failed, fallthrough and notify application */
442
451
}
443
452
444
453
atomic_clear_bit (inst -> cli .flags , BT_AICS_CLIENT_FLAG_CP_RETRIED );
@@ -550,13 +559,74 @@ static bool valid_inst_discovered(struct bt_aics *inst)
550
559
inst -> cli .desc_handle ;
551
560
}
552
561
562
+ static int store_attr_handle_and_subscribe (struct bt_aics_client * client_inst , struct bt_conn * conn ,
563
+ const struct bt_gatt_chrc * chrc )
564
+ {
565
+ struct bt_gatt_subscribe_params * sub_params = NULL ;
566
+
567
+ if (bt_uuid_cmp (chrc -> uuid , BT_UUID_AICS_STATE ) == 0U ) {
568
+ LOG_DBG ("Audio Input state" );
569
+ client_inst -> state_handle = chrc -> value_handle ;
570
+ sub_params = & client_inst -> state_sub_params ;
571
+ } else if (bt_uuid_cmp (chrc -> uuid , BT_UUID_AICS_GAIN_SETTINGS ) == 0U ) {
572
+ LOG_DBG ("Gain settings" );
573
+ client_inst -> gain_handle = chrc -> value_handle ;
574
+ } else if (bt_uuid_cmp (chrc -> uuid , BT_UUID_AICS_INPUT_TYPE ) == 0U ) {
575
+ LOG_DBG ("Input type" );
576
+ client_inst -> type_handle = chrc -> value_handle ;
577
+ } else if (bt_uuid_cmp (chrc -> uuid , BT_UUID_AICS_INPUT_STATUS ) == 0U ) {
578
+ LOG_DBG ("Input status" );
579
+ client_inst -> status_handle = chrc -> value_handle ;
580
+ sub_params = & client_inst -> status_sub_params ;
581
+ } else if (bt_uuid_cmp (chrc -> uuid , BT_UUID_AICS_CONTROL ) == 0U ) {
582
+ LOG_DBG ("Control point" );
583
+ client_inst -> control_handle = chrc -> value_handle ;
584
+ } else if (bt_uuid_cmp (chrc -> uuid , BT_UUID_AICS_DESCRIPTION ) == 0U ) {
585
+ LOG_DBG ("Description" );
586
+ client_inst -> desc_handle = chrc -> value_handle ;
587
+ if ((chrc -> properties & BT_GATT_CHRC_NOTIFY ) != 0U ) {
588
+ sub_params = & client_inst -> desc_sub_params ;
589
+ }
590
+
591
+ if ((chrc -> properties & BT_GATT_CHRC_WRITE_WITHOUT_RESP ) != 0U ) {
592
+ atomic_set_bit (client_inst -> flags , BT_AICS_CLIENT_FLAG_DESC_WRITABLE );
593
+ }
594
+ } else {
595
+ __ASSERT (false, "Unexpected UUID %s discovered" , bt_uuid_str (chrc -> uuid ));
596
+ }
597
+
598
+ if (sub_params ) {
599
+ int err ;
600
+
601
+ sub_params -> value = BT_GATT_CCC_NOTIFY ;
602
+ sub_params -> value_handle = chrc -> value_handle ;
603
+ /*
604
+ * TODO: Don't assume that CCC is at value handle + 1;
605
+ * do proper discovery;
606
+ */
607
+ sub_params -> ccc_handle = chrc -> value_handle + 1 ;
608
+ sub_params -> notify = aics_client_notify_handler ;
609
+ atomic_set_bit (sub_params -> flags , BT_GATT_SUBSCRIBE_FLAG_VOLATILE );
610
+
611
+ err = bt_gatt_subscribe (conn , sub_params );
612
+ if (err != 0 && err != - EALREADY ) {
613
+ LOG_ERR ("Failed to subscribe: %d" , err );
614
+
615
+ return err ;
616
+ }
617
+ }
618
+
619
+ return 0 ;
620
+ }
621
+
553
622
static uint8_t aics_discover_func (struct bt_conn * conn , const struct bt_gatt_attr * attr ,
554
623
struct bt_gatt_discover_params * params )
555
624
{
556
- struct bt_aics_client * client_inst = CONTAINER_OF (params ,
557
- struct bt_aics_client ,
558
- discover_params );
625
+ struct bt_aics_client * client_inst =
626
+ CONTAINER_OF (params , struct bt_aics_client , discover_params );
559
627
struct bt_aics * inst = CONTAINER_OF (client_inst , struct bt_aics , cli );
628
+ const struct bt_gatt_chrc * chrc ;
629
+ int err ;
560
630
561
631
if (!attr ) {
562
632
LOG_DBG ("Discovery complete for AICS %p" , inst );
@@ -566,7 +636,7 @@ static uint8_t aics_discover_func(struct bt_conn *conn, const struct bt_gatt_att
566
636
atomic_clear_bit (inst -> cli .flags , BT_AICS_CLIENT_FLAG_BUSY );
567
637
568
638
if (inst -> cli .cb && inst -> cli .cb -> discover ) {
569
- int err = valid_inst_discovered (inst ) ? 0 : - ENOENT ;
639
+ err = valid_inst_discovered (inst ) ? 0 : - ENOENT ;
570
640
571
641
inst -> cli .cb -> discover (inst , err );
572
642
}
@@ -576,69 +646,21 @@ static uint8_t aics_discover_func(struct bt_conn *conn, const struct bt_gatt_att
576
646
577
647
LOG_DBG ("[ATTRIBUTE] handle 0x%04X" , attr -> handle );
578
648
579
- if (params -> type == BT_GATT_DISCOVER_CHARACTERISTIC ) {
580
- struct bt_gatt_subscribe_params * sub_params = NULL ;
581
- struct bt_gatt_chrc * chrc ;
649
+ __ASSERT_NO_MSG (params -> type == BT_GATT_DISCOVER_CHARACTERISTIC );
582
650
583
- chrc = (struct bt_gatt_chrc * )attr -> user_data ;
584
- if (inst -> cli .start_handle == 0 ) {
585
- inst -> cli .start_handle = chrc -> value_handle ;
586
- }
587
- inst -> cli .end_handle = chrc -> value_handle ;
588
-
589
- if (!bt_uuid_cmp (chrc -> uuid , BT_UUID_AICS_STATE )) {
590
- LOG_DBG ("Audio Input state" );
591
- inst -> cli .state_handle = chrc -> value_handle ;
592
- sub_params = & inst -> cli .state_sub_params ;
593
- } else if (!bt_uuid_cmp (chrc -> uuid , BT_UUID_AICS_GAIN_SETTINGS )) {
594
- LOG_DBG ("Gain settings" );
595
- inst -> cli .gain_handle = chrc -> value_handle ;
596
- } else if (!bt_uuid_cmp (chrc -> uuid , BT_UUID_AICS_INPUT_TYPE )) {
597
- LOG_DBG ("Input type" );
598
- inst -> cli .type_handle = chrc -> value_handle ;
599
- } else if (!bt_uuid_cmp (chrc -> uuid , BT_UUID_AICS_INPUT_STATUS )) {
600
- LOG_DBG ("Input status" );
601
- inst -> cli .status_handle = chrc -> value_handle ;
602
- sub_params = & inst -> cli .status_sub_params ;
603
- } else if (!bt_uuid_cmp (chrc -> uuid , BT_UUID_AICS_CONTROL )) {
604
- LOG_DBG ("Control point" );
605
- inst -> cli .control_handle = chrc -> value_handle ;
606
- } else if (!bt_uuid_cmp (chrc -> uuid , BT_UUID_AICS_DESCRIPTION )) {
607
- LOG_DBG ("Description" );
608
- inst -> cli .desc_handle = chrc -> value_handle ;
609
- if (chrc -> properties & BT_GATT_CHRC_NOTIFY ) {
610
- sub_params = & inst -> cli .desc_sub_params ;
611
- }
651
+ chrc = (const struct bt_gatt_chrc * )attr -> user_data ;
652
+ if (inst -> cli .start_handle == 0U ) { /* if start handle is unset */
653
+ inst -> cli .start_handle = chrc -> value_handle ;
654
+ }
655
+ inst -> cli .end_handle = chrc -> value_handle ;
612
656
613
- if (chrc -> properties & BT_GATT_CHRC_WRITE_WITHOUT_RESP ) {
614
- atomic_set_bit (inst -> cli .flags , BT_AICS_CLIENT_FLAG_DESC_WRITABLE );
615
- }
657
+ err = store_attr_handle_and_subscribe (client_inst , conn , chrc );
658
+ if (err != 0 ) {
659
+ if (client_inst -> cb && client_inst -> cb -> discover ) {
660
+ client_inst -> cb -> discover (inst , err );
616
661
}
617
662
618
- if (sub_params ) {
619
- int err ;
620
-
621
- sub_params -> value = BT_GATT_CCC_NOTIFY ;
622
- sub_params -> value_handle = chrc -> value_handle ;
623
- /*
624
- * TODO: Don't assume that CCC is at handle + 2;
625
- * do proper discovery;
626
- */
627
- sub_params -> ccc_handle = attr -> handle + 2 ;
628
- sub_params -> notify = aics_client_notify_handler ;
629
- atomic_set_bit (sub_params -> flags , BT_GATT_SUBSCRIBE_FLAG_VOLATILE );
630
-
631
- err = bt_gatt_subscribe (conn , sub_params );
632
- if (err != 0 && err != - EALREADY ) {
633
- LOG_ERR ("Failed to subscribe: %d" , err );
634
-
635
- if (inst -> cli .cb && inst -> cli .cb -> discover ) {
636
- inst -> cli .cb -> discover (inst , err );
637
- }
638
-
639
- return BT_GATT_ITER_STOP ;
640
- }
641
- }
663
+ return BT_GATT_ITER_STOP ;
642
664
}
643
665
644
666
return BT_GATT_ITER_CONTINUE ;
0 commit comments