@@ -214,6 +214,8 @@ static void notify(struct bt_aics *inst, enum bt_aics_notify notify, const struc
214
214
notify_work_reschedule (inst , notify , K_USEC (BT_AUDIO_NOTIFY_RETRY_DELAY_US ));
215
215
} else if (err < 0 && err != - ENOTCONN ) {
216
216
LOG_ERR ("Notify %s err %d" , aics_notify_str (notify ), err );
217
+ } else {
218
+ /* Notification sent successfully */
217
219
}
218
220
}
219
221
@@ -246,99 +248,160 @@ static void value_changed(struct bt_aics *inst, enum bt_aics_notify notify)
246
248
#define value_changed (...)
247
249
#endif /* CONFIG_BT_AICS */
248
250
249
- static ssize_t write_aics_control (struct bt_conn * conn ,
250
- const struct bt_gatt_attr * attr ,
251
- const void * buf , uint16_t len ,
252
- uint16_t offset , uint8_t flags )
251
+ static uint8_t valid_control_point_write (uint16_t len , uint16_t offset ,
252
+ const struct bt_aics_gain_control * cp ,
253
+ uint8_t change_counter )
253
254
{
254
- struct bt_aics * inst = BT_AUDIO_CHRC_USER_DATA (attr );
255
- const struct bt_aics_gain_control * cp = buf ;
256
- bool notify = false;
257
-
258
- if (offset ) {
259
- return BT_GATT_ERR (BT_ATT_ERR_INVALID_OFFSET );
255
+ if (offset != 0 ) {
256
+ LOG_DBG ("Invalid offset: %u" , offset );
257
+ return BT_ATT_ERR_INVALID_OFFSET ;
260
258
}
261
259
262
- if (!len || !buf ) {
263
- return BT_GATT_ERR (BT_ATT_ERR_INVALID_ATTRIBUTE_LEN );
260
+ if (len == 0 || cp == NULL ) {
261
+ LOG_DBG ("Invalid length (%u) or NULL data (%p)" , len , cp );
262
+ return BT_ATT_ERR_INVALID_ATTRIBUTE_LEN ;
264
263
}
265
264
266
265
/* Check opcode before length */
267
266
if (!VALID_AICS_OPCODE (cp -> cp .opcode )) {
268
267
LOG_DBG ("Invalid opcode %u" , cp -> cp .opcode );
269
- return BT_GATT_ERR ( BT_AICS_ERR_OP_NOT_SUPPORTED ) ;
268
+ return BT_AICS_ERR_OP_NOT_SUPPORTED ;
270
269
}
271
270
272
271
if ((len < AICS_CP_LEN ) ||
273
272
(len == AICS_CP_SET_GAIN_LEN && cp -> cp .opcode != BT_AICS_OPCODE_SET_GAIN ) ||
274
273
(len > AICS_CP_SET_GAIN_LEN )) {
275
- return BT_GATT_ERR (BT_ATT_ERR_INVALID_ATTRIBUTE_LEN );
274
+ LOG_DBG ("Invalid length: %u" , len );
275
+ return BT_ATT_ERR_INVALID_ATTRIBUTE_LEN ;
276
276
}
277
277
278
278
LOG_DBG ("Opcode %u, counter %u" , cp -> cp .opcode , cp -> cp .counter );
279
- if (cp -> cp .counter != inst -> srv .state .change_counter ) {
280
- return BT_GATT_ERR (BT_AICS_ERR_INVALID_COUNTER );
279
+ if (cp -> cp .counter != change_counter ) {
280
+ LOG_DBG ("Invalid counter: %u != %u" , cp -> cp .counter , change_counter );
281
+ return BT_AICS_ERR_INVALID_COUNTER ;
282
+ }
283
+
284
+ return BT_ATT_ERR_SUCCESS ;
285
+ }
286
+
287
+ static uint8_t handle_set_gain_op (struct bt_aics * inst , const struct bt_aics_gain_control * cp ,
288
+ bool * state_change )
289
+ {
290
+ LOG_DBG ("Set gain %d" , cp -> gain_setting );
291
+ if (cp -> gain_setting < inst -> srv .gain_settings .minimum ||
292
+ cp -> gain_setting > inst -> srv .gain_settings .maximum ) {
293
+ return BT_AICS_ERR_OUT_OF_RANGE ;
294
+ }
295
+
296
+ if (BT_AICS_INPUT_MODE_SETTABLE (inst -> srv .state .gain_mode ) &&
297
+ inst -> srv .state .gain != cp -> gain_setting ) {
298
+ inst -> srv .state .gain = cp -> gain_setting ;
299
+ * state_change = true;
300
+ }
301
+
302
+ return BT_ATT_ERR_SUCCESS ;
303
+ }
304
+
305
+ static uint8_t handle_unmute_op (struct bt_aics * inst , bool * state_change )
306
+ {
307
+ LOG_DBG ("Unmute" );
308
+ if (inst -> srv .state .mute == BT_AICS_STATE_MUTE_DISABLED ) {
309
+ return BT_AICS_ERR_MUTE_DISABLED ;
310
+ }
311
+ if (inst -> srv .state .mute != BT_AICS_STATE_UNMUTED ) {
312
+ inst -> srv .state .mute = BT_AICS_STATE_UNMUTED ;
313
+ * state_change = true;
314
+ }
315
+
316
+ return BT_ATT_ERR_SUCCESS ;
317
+ }
318
+
319
+ static uint8_t handle_mute_op (struct bt_aics * inst , bool * state_change )
320
+ {
321
+ LOG_DBG ("Mute" );
322
+
323
+ if (inst -> srv .state .mute == BT_AICS_STATE_MUTE_DISABLED ) {
324
+ return BT_AICS_ERR_MUTE_DISABLED ;
325
+ }
326
+
327
+ if (inst -> srv .state .mute != BT_AICS_STATE_MUTED ) {
328
+ inst -> srv .state .mute = BT_AICS_STATE_MUTED ;
329
+ * state_change = true;
330
+ }
331
+
332
+ return BT_ATT_ERR_SUCCESS ;
333
+ }
334
+
335
+ static uint8_t handle_set_manual_mode_op (struct bt_aics * inst , bool * state_change )
336
+ {
337
+ LOG_DBG ("Set manual mode" );
338
+
339
+ if (BT_AICS_INPUT_MODE_IMMUTABLE (inst -> srv .state .gain_mode )) {
340
+ return BT_AICS_ERR_GAIN_MODE_NOT_ALLOWED ;
341
+ }
342
+
343
+ if (inst -> srv .state .gain_mode != BT_AICS_MODE_MANUAL ) {
344
+ inst -> srv .state .gain_mode = BT_AICS_MODE_MANUAL ;
345
+ * state_change = true;
346
+ }
347
+
348
+ return BT_ATT_ERR_SUCCESS ;
349
+ }
350
+ static uint8_t handle_set_automatic_mode_op (struct bt_aics * inst , bool * state_change )
351
+ {
352
+ LOG_DBG ("Set automatic mode" );
353
+
354
+ if (BT_AICS_INPUT_MODE_IMMUTABLE (inst -> srv .state .gain_mode )) {
355
+ return BT_AICS_ERR_GAIN_MODE_NOT_ALLOWED ;
356
+ }
357
+
358
+ if (inst -> srv .state .gain_mode != BT_AICS_MODE_AUTO ) {
359
+ inst -> srv .state .gain_mode = BT_AICS_MODE_AUTO ;
360
+ * state_change = true;
361
+ }
362
+
363
+ return BT_ATT_ERR_SUCCESS ;
364
+ }
365
+
366
+ static ssize_t write_aics_control (struct bt_conn * conn , const struct bt_gatt_attr * attr ,
367
+ const void * buf , uint16_t len , uint16_t offset , uint8_t flags )
368
+ {
369
+ struct bt_aics * inst = BT_AUDIO_CHRC_USER_DATA (attr );
370
+ const struct bt_aics_gain_control * cp = buf ;
371
+ bool state_change = false;
372
+ int ret ;
373
+
374
+ ret = valid_control_point_write (len , offset , cp , inst -> srv .state .change_counter );
375
+ if (ret != BT_ATT_ERR_SUCCESS ) {
376
+ return BT_GATT_ERR (ret );
281
377
}
282
378
283
379
switch (cp -> cp .opcode ) {
284
380
case BT_AICS_OPCODE_SET_GAIN :
285
- LOG_DBG ("Set gain %d" , cp -> gain_setting );
286
- if (cp -> gain_setting < inst -> srv .gain_settings .minimum ||
287
- cp -> gain_setting > inst -> srv .gain_settings .maximum ) {
288
- return BT_GATT_ERR (BT_AICS_ERR_OUT_OF_RANGE );
289
- }
290
- if (BT_AICS_INPUT_MODE_SETTABLE (inst -> srv .state .gain_mode ) &&
291
- inst -> srv .state .gain != cp -> gain_setting ) {
292
- inst -> srv .state .gain = cp -> gain_setting ;
293
- notify = true;
294
- }
381
+ ret = handle_set_gain_op (inst , cp , & state_change );
295
382
break ;
296
383
case BT_AICS_OPCODE_UNMUTE :
297
- LOG_DBG ("Unmute" );
298
- if (inst -> srv .state .mute == BT_AICS_STATE_MUTE_DISABLED ) {
299
- return BT_GATT_ERR (BT_AICS_ERR_MUTE_DISABLED );
300
- }
301
- if (inst -> srv .state .mute != BT_AICS_STATE_UNMUTED ) {
302
- inst -> srv .state .mute = BT_AICS_STATE_UNMUTED ;
303
- notify = true;
304
- }
384
+ ret = handle_unmute_op (inst , & state_change );
305
385
break ;
306
386
case BT_AICS_OPCODE_MUTE :
307
- LOG_DBG ("Mute" );
308
- if (inst -> srv .state .mute == BT_AICS_STATE_MUTE_DISABLED ) {
309
- return BT_GATT_ERR (BT_AICS_ERR_MUTE_DISABLED );
310
- }
311
- if (inst -> srv .state .mute != BT_AICS_STATE_MUTED ) {
312
- inst -> srv .state .mute = BT_AICS_STATE_MUTED ;
313
- notify = true;
314
- }
387
+ ret = handle_mute_op (inst , & state_change );
315
388
break ;
316
389
case BT_AICS_OPCODE_SET_MANUAL :
317
- LOG_DBG ("Set manual mode" );
318
- if (BT_AICS_INPUT_MODE_IMMUTABLE (inst -> srv .state .gain_mode )) {
319
- return BT_GATT_ERR (BT_AICS_ERR_GAIN_MODE_NOT_ALLOWED );
320
- }
321
- if (inst -> srv .state .gain_mode != BT_AICS_MODE_MANUAL ) {
322
- inst -> srv .state .gain_mode = BT_AICS_MODE_MANUAL ;
323
- notify = true;
324
- }
390
+ ret = handle_set_manual_mode_op (inst , & state_change );
325
391
break ;
326
392
case BT_AICS_OPCODE_SET_AUTO :
327
- LOG_DBG ("Set automatic mode" );
328
- if (BT_AICS_INPUT_MODE_IMMUTABLE (inst -> srv .state .gain_mode )) {
329
- return BT_GATT_ERR (BT_AICS_ERR_GAIN_MODE_NOT_ALLOWED );
330
- }
331
- if (inst -> srv .state .gain_mode != BT_AICS_MODE_AUTO ) {
332
- inst -> srv .state .gain_mode = BT_AICS_MODE_AUTO ;
333
- notify = true;
334
- }
393
+ ret = handle_set_automatic_mode_op (inst , & state_change );
335
394
break ;
336
395
default :
337
- return BT_GATT_ERR (BT_AICS_ERR_OP_NOT_SUPPORTED );
396
+ ret = BT_AICS_ERR_OP_NOT_SUPPORTED ;
397
+ }
398
+
399
+ if (ret != BT_ATT_ERR_SUCCESS ) {
400
+ return BT_GATT_ERR (ret );
338
401
}
339
402
340
- if (notify ) {
341
- inst -> srv .state .change_counter ++ ;
403
+ if (state_change ) {
404
+ inst -> srv .state .change_counter ++ ; /* May overflow which is OK */
342
405
343
406
LOG_DBG ("New state: gain %d, mute %u, gain_mode %u, counter %u" ,
344
407
inst -> srv .state .gain , inst -> srv .state .mute , inst -> srv .state .gain_mode ,
0 commit comments