@@ -148,11 +148,33 @@ static void avrcp_subunit_info_req(struct bt_avrcp_tg *tg, uint8_t tid)
148
148
tg_tid = tid ;
149
149
}
150
150
151
+ static void avrcp_passthrough_cmd_req (struct bt_avrcp_tg * tg , uint8_t tid , bt_avrcp_opid_t opid ,
152
+ bt_avrcp_button_state_t state , const uint8_t * data , uint8_t len )
153
+ {
154
+ const char * state_str ;
155
+
156
+ /* Convert button state to string */
157
+ state_str = (state == BT_AVRCP_BUTTON_PRESSED ) ? "PRESSED" : "RELEASED" ;
158
+
159
+ bt_shell_print ("AVRCP passthrough command received: opid = 0x%02x (%s), tid=0x%02x, len=%u" ,
160
+ opid , state_str , tid , len );
161
+
162
+ if (len > 0U && data != NULL ) {
163
+ bt_shell_print ("Payload:" );
164
+ for (uint8_t i = 0U ; i < len ; i ++ ) {
165
+ bt_shell_print (" [%u]: 0x%02x" , i , data [i ]);
166
+ }
167
+ }
168
+
169
+ tg_tid = tid ;
170
+ }
171
+
151
172
static struct bt_avrcp_tg_cb app_avrcp_tg_cb = {
152
173
.connected = avrcp_tg_connected ,
153
174
.disconnected = avrcp_tg_disconnected ,
154
175
.unit_info_req = avrcp_unit_info_req ,
155
176
.subunit_info_req = avrcp_subunit_info_req ,
177
+ .passthrough_cmd_req = avrcp_passthrough_cmd_req ,
156
178
};
157
179
158
180
static int register_ct_cb (const struct shell * sh )
@@ -331,6 +353,104 @@ static int cmd_send_subunit_info_rsp(const struct shell *sh, int32_t argc, char
331
353
return 0 ;
332
354
}
333
355
356
+ static int cmd_send_passthrough_rsp (const struct shell * sh , int32_t argc , char * argv [])
357
+ {
358
+ bt_avrcp_rsp_t response ;
359
+ bt_avrcp_opid_t opid ;
360
+ bt_avrcp_button_state_t state ;
361
+ uint16_t vu_opid = 0 ;
362
+ uint8_t is_op_vu = 0 ;
363
+ struct bt_avrcp_passthrough_opvu_data payload ;
364
+ int err ;
365
+
366
+ if (!avrcp_tg_registered && register_tg_cb (sh ) != 0 ) {
367
+ return - ENOEXEC ;
368
+ }
369
+
370
+ if (default_tg == NULL ) {
371
+ shell_error (sh , "AVRCP TG is not connected" );
372
+ return - ENOEXEC ;
373
+ }
374
+
375
+ if (argc < 5 ) {
376
+ shell_print (sh , "Usage: send_passthrough_rsp <response> <op/opvu> <opid> <state>\n"
377
+ " op/opvu: passthrough command (normal/passthrough VENDOR UNIQUE)\n"
378
+ " response: [accepted|rejected|not_impl]\n"
379
+ " opid: operation identifier (e.g., play/pause or hex value)\n"
380
+ " state: [pressed|released]" );
381
+ return - EINVAL ;
382
+ }
383
+
384
+ if (!strcmp (argv [1 ], "accepted" )) {
385
+ response = BT_AVRCP_RSP_ACCEPTED ;
386
+ } else if (!strcmp (argv [1 ], "rejected" )) {
387
+ response = BT_AVRCP_RSP_REJECTED ;
388
+ } else if (!strcmp (argv [1 ], "not_impl" )) {
389
+ response = BT_AVRCP_RSP_NOT_IMPLEMENTED ;
390
+ } else {
391
+ shell_error (sh , "Invalid response: %s" , argv [1 ]);
392
+ return - EINVAL ;
393
+ }
394
+
395
+ if (!strcmp (argv [2 ], "op" )) {
396
+ is_op_vu = 0 ;
397
+ } else if (!strcmp (argv [2 ], "opvu" )) {
398
+ opid = BT_AVRCP_OPID_VENDOR_UNIQUE ;
399
+ is_op_vu = 1 ;
400
+ } else {
401
+ shell_error (sh , "Invalid response: %s" , argv [2 ]);
402
+ return - EINVAL ;
403
+ }
404
+
405
+ if (!strcmp (argv [3 ], "play" )) {
406
+ opid = BT_AVRCP_OPID_PLAY ;
407
+ vu_opid = (uint16_t )opid ;
408
+ } else if (!strcmp (argv [3 ], "pause" )) {
409
+ opid = BT_AVRCP_OPID_PAUSE ;
410
+ vu_opid = (uint16_t )opid ;
411
+ } else {
412
+ /* Try to parse as hex value */
413
+ char * endptr ;
414
+ unsigned long val = strtoul (argv [3 ], & endptr , 16 );
415
+ if (* endptr != '\0' || val > 0xFFFFU ) {
416
+ shell_error (sh , "Invalid opid: %s" , argv [3 ]);
417
+ return - EINVAL ;
418
+ }
419
+ if (is_op_vu == 1 ) {
420
+ vu_opid = (uint16_t )val ;
421
+ } else {
422
+ opid = (bt_avrcp_opid_t )val ;
423
+ }
424
+ }
425
+
426
+ if (!strcmp (argv [4 ], "pressed" )) {
427
+ state = BT_AVRCP_BUTTON_PRESSED ;
428
+ } else if (!strcmp (argv [4 ], "released" )) {
429
+ state = BT_AVRCP_BUTTON_RELEASED ;
430
+ } else {
431
+ shell_error (sh , "Invalid state: %s" , argv [4 ]);
432
+ return - EINVAL ;
433
+ }
434
+
435
+ if (is_op_vu == 1 ) {
436
+ sys_put_be24 (BT_AVRCP_COMPANY_ID_BLUETOOTH_SIG , payload .company_id );
437
+ payload .op_len = 5U ;
438
+ payload .opid_vu = vu_opid ;
439
+ }
440
+
441
+ err = bt_avrcp_tg_send_passthrough_rsp (default_tg , tg_tid , response , opid , state ,
442
+ payload .op_len ? (const uint8_t * )& payload : NULL ,
443
+ payload .op_len );
444
+ if (err ) {
445
+ shell_error (sh , "Failed to send passthrough response: %d" , err );
446
+ } else {
447
+ shell_print (sh , "Passthrough response sent: %s, opid=0x%02x, state=%s" ,
448
+ argv [1 ], opid , argv [3 ]);
449
+ }
450
+
451
+ return err ;
452
+ }
453
+
334
454
static int cmd_get_subunit_info (const struct shell * sh , int32_t argc , char * argv [])
335
455
{
336
456
if (!avrcp_ct_registered && register_ct_cb (sh ) != 0 ) {
@@ -415,6 +535,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE(
415
535
SHELL_CMD_ARG (send_unit_rsp , NULL , "send unit info response" , cmd_send_unit_info_rsp , 1 , 0 ),
416
536
SHELL_CMD_ARG (send_subunit_rsp , NULL , "send subunit info response" ,
417
537
cmd_send_subunit_info_rsp , 1 , 0 ),
538
+ SHELL_CMD_ARG (send_passthrough_rsp , NULL ,
539
+ "send_passthrough_rsp <response> <op/opvu> <opid> <state>" ,
540
+ cmd_send_passthrough_rsp , 5 , 0 ),
418
541
SHELL_SUBCMD_SET_END );
419
542
420
543
static int cmd_avrcp (const struct shell * sh , size_t argc , char * * argv )
0 commit comments