1 /* 2 * Copyright (C) 2016 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the copyright holders nor the names of 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 4. Any redistribution, use, or modification is done solely for 17 * personal benefit and not for any commercial purpose or for 18 * monetary gain. 19 * 20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24 * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * Please inquire about commercial licensing options at 34 * [email protected] 35 * 36 */ 37 38 #define __BTSTACK_FILE__ "avrcp.c" 39 40 #include <stdint.h> 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <string.h> 44 45 #include "btstack.h" 46 #include "classic/avrcp.h" 47 48 #define AV_REMOTE_CONTROL_TARGET 0x110C 49 #define AV_REMOTE_CONTROL 0x110E 50 #define AV_REMOTE_CONTROL_CONTROLLER 0x110F 51 52 #define PSM_AVCTP BLUETOOTH_PROTOCOL_AVCTP 53 #define PSM_AVCTP_BROWSING 0xFF17 54 55 /* 56 Category 1: Player/Recorder 57 Category 2: Monitor/Amplifier 58 Category 3: Tuner 59 Category 4: Menu 60 */ 61 62 /* controller supported features 63 Bit 0 = Category 1 64 Bit 1 = Category 2 65 Bit 2 = Category 3 66 Bit 3 = Category 4 67 Bit 4-5 = RFA 68 Bit 6 = Supports browsing 69 Bit 7-15 = RFA 70 The bits for supported categories are set to 1. Others are set to 0. 71 */ 72 73 /* target supported features 74 Bit 0 = Category 1 75 Bit 1 = Category 2 76 Bit 2 = Category 3 77 Bit 3 = Category 4 78 Bit 4 = Player Application Settings. Bit 0 should be set for this bit to be set. 79 Bit 5 = Group Navigation. Bit 0 should be set for this bit to be set. 80 Bit 6 = Supports browsing*4 81 Bit 7 = Supports multiple media player applications 82 Bit 8-15 = RFA 83 The bits for supported categories are set to 1. Others are set to 0. 84 */ 85 86 // TODO: merge with avdtp_packet_type_t 87 typedef enum { 88 AVRCP_SINGLE_PACKET= 0, 89 AVRCP_START_PACKET , 90 AVRCP_CONTINUE_PACKET , 91 AVRCP_END_PACKET 92 } avrcp_packet_type_t; 93 94 typedef enum { 95 AVRCP_COMMAND_FRAME = 0, 96 AVRCP_RESPONSE_FRAME 97 } avrcp_frame_type_t; 98 99 static const char * default_avrcp_controller_service_name = "BTstack AVRCP Controller Service"; 100 static const char * default_avrcp_controller_service_provider_name = "BTstack AVRCP Controller Service Provider"; 101 static const char * default_avrcp_target_service_name = "BTstack AVRCP Target Service"; 102 static const char * default_avrcp_target_service_provider_name = "BTstack AVRCP Target Service Provider"; 103 104 static btstack_linked_list_t avrcp_connections; 105 static btstack_packet_handler_t avrcp_callback; 106 107 static const char * avrcp_subunit_type_name[] = { 108 "MONITOR", "AUDIO", "PRINTER", "DISC", "TAPE_RECORDER_PLAYER", "TUNER", 109 "CA", "CAMERA", "RESERVED", "PANEL", "BULLETIN_BOARD", "CAMERA_STORAGE", 110 "VENDOR_UNIQUE", "RESERVED_FOR_ALL_SUBUNIT_TYPES", 111 "EXTENDED_TO_NEXT_BYTE", "UNIT", "ERROR" 112 }; 113 const char * avrcp_subunit2str(uint16_t index){ 114 if (index <= 11) return avrcp_subunit_type_name[index]; 115 if (index >= 0x1C && index <= 0x1F) return avrcp_subunit_type_name[index - 0x10]; 116 return avrcp_subunit_type_name[16]; 117 } 118 119 static const char * avrcp_event_name[] = { 120 "ERROR", "PLAYBACK_STATUS_CHANGED", 121 "TRACK_CHANGED", "TRACK_REACHED_END", "TRACK_REACHED_START", 122 "PLAYBACK_POS_CHANGED", "BATT_STATUS_CHANGED", "SYSTEM_STATUS_CHANGED", 123 "PLAYER_APPLICATION_SETTING_CHANGED", "NOW_PLAYING_CONTENT_CHANGED", 124 "AVAILABLE_PLAYERS_CHANGED", "ADDRESSED_PLAYER_CHANGED", "UIDS_CHANGED", "VOLUME_CHANGED" 125 }; 126 const char * avrcp_event2str(uint16_t index){ 127 if (index <= 0x0d) return avrcp_event_name[index]; 128 return avrcp_event_name[0]; 129 } 130 131 static const char * avrcp_operation_name[] = { 132 "NOT SUPPORTED", // 0x3B 133 "SKIP", "NOT SUPPORTED", "NOT SUPPORTED", "NOT SUPPORTED", "NOT SUPPORTED", 134 "VOLUME_UP", "VOLUME_DOWN", "MUTE", "PLAY", "STOP", "PAUSE", "NOT SUPPORTED", 135 "REWIND", "FAST_FORWARD", "NOT SUPPORTED", "FORWARD", "BACKWARD" // 0x4C 136 }; 137 const char * avrcp_operation2str(uint8_t index){ 138 if (index >= 0x3B && index <= 0x4C) return avrcp_operation_name[index - 0x3B]; 139 return avrcp_operation_name[0]; 140 } 141 142 static const char * avrcp_media_attribute_id_name[] = { 143 "NONE", "TITLE", "ARTIST", "ALBUM", "TRACK", "TOTAL TRACKS", "GENRE", "SONG LENGTH" 144 }; 145 const char * avrcp_attribute2str(uint8_t index){ 146 if (index >= 1 && index <= 7) return avrcp_media_attribute_id_name[index]; 147 return avrcp_media_attribute_id_name[0]; 148 } 149 150 static const char * avrcp_play_status_name[] = { 151 "STOPPED", "PLAYING", "PAUSED", "FORWARD SEEK", "REVERSE SEEK", 152 "ERROR" // 0xFF 153 }; 154 const char * avrcp_play_status2str(uint8_t index){ 155 if (index >= 1 && index <= 4) return avrcp_play_status_name[index]; 156 return avrcp_play_status_name[5]; 157 } 158 159 static const char * avrcp_ctype_name[] = { 160 "CONTROL", 161 "STATUS", 162 "SPECIFIC_INQUIRY", 163 "NOTIFY", 164 "GENERAL_INQUIRY", 165 "RESERVED5", 166 "RESERVED6", 167 "RESERVED7", 168 "NOT IMPLEMENTED IN REMOTE", 169 "ACCEPTED BY REMOTE", 170 "REJECTED BY REMOTE", 171 "IN_TRANSITION", 172 "IMPLEMENTED_STABLE", 173 "CHANGED_STABLE", 174 "RESERVED", 175 "INTERIM" 176 }; 177 const char * avrcp_ctype2str(uint8_t index){ 178 if (index < sizeof(avrcp_ctype_name)){ 179 return avrcp_ctype_name[index]; 180 } 181 return "NONE"; 182 } 183 184 static const char * avrcp_shuffle_mode_name[] = { 185 "SHUFFLE OFF", 186 "SHUFFLE ALL TRACKS", 187 "SHUFFLE GROUP" 188 }; 189 190 const char * avrcp_shuffle2str(uint8_t index){ 191 if (index >= 1 && index <= 3) return avrcp_shuffle_mode_name[index-1]; 192 return "NONE"; 193 } 194 195 static const char * avrcp_repeat_mode_name[] = { 196 "REPEAT OFF", 197 "REPEAT SINGLE TRACK", 198 "REPEAT ALL TRACKS", 199 "REPEAT GROUP" 200 }; 201 202 const char * avrcp_repeat2str(uint8_t index){ 203 if (index >= 1 && index <= 4) return avrcp_repeat_mode_name[index-1]; 204 return "NONE"; 205 } 206 static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); 207 208 static void avrcp_create_sdp_record(uint8_t controller, uint8_t * service, uint32_t service_record_handle, uint8_t browsing, uint16_t supported_features, const char * service_name, const char * service_provider_name){ 209 uint8_t* attribute; 210 de_create_sequence(service); 211 212 // 0x0000 "Service Record Handle" 213 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_RECORD_HANDLE); 214 de_add_number(service, DE_UINT, DE_SIZE_32, service_record_handle); 215 216 // 0x0001 "Service Class ID List" 217 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_CLASS_ID_LIST); 218 attribute = de_push_sequence(service); 219 { 220 if (controller){ 221 de_add_number(attribute, DE_UUID, DE_SIZE_16, AV_REMOTE_CONTROL); 222 de_add_number(attribute, DE_UUID, DE_SIZE_16, AV_REMOTE_CONTROL_CONTROLLER); 223 } else { 224 de_add_number(attribute, DE_UUID, DE_SIZE_16, AV_REMOTE_CONTROL_TARGET); 225 } 226 } 227 de_pop_sequence(service, attribute); 228 229 // 0x0004 "Protocol Descriptor List" 230 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST); 231 attribute = de_push_sequence(service); 232 { 233 uint8_t* l2cpProtocol = de_push_sequence(attribute); 234 { 235 de_add_number(l2cpProtocol, DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP); 236 de_add_number(l2cpProtocol, DE_UINT, DE_SIZE_16, BLUETOOTH_PROTOCOL_AVCTP); 237 } 238 de_pop_sequence(attribute, l2cpProtocol); 239 240 uint8_t* avctpProtocol = de_push_sequence(attribute); 241 { 242 de_add_number(avctpProtocol, DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_AVCTP); // avctpProtocol_service 243 de_add_number(avctpProtocol, DE_UINT, DE_SIZE_16, 0x0103); // version 244 } 245 de_pop_sequence(attribute, avctpProtocol); 246 247 if (browsing){ 248 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST); 249 attribute = de_push_sequence(service); 250 { 251 uint8_t* browsing_l2cpProtocol = de_push_sequence(attribute); 252 { 253 de_add_number(browsing_l2cpProtocol, DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP); 254 de_add_number(browsing_l2cpProtocol, DE_UINT, DE_SIZE_16, PSM_AVCTP_BROWSING); 255 } 256 de_pop_sequence(attribute, browsing_l2cpProtocol); 257 258 uint8_t* browsing_avctpProtocol = de_push_sequence(attribute); 259 { 260 de_add_number(browsing_avctpProtocol, DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_AVCTP); // browsing_avctpProtocol_service 261 de_add_number(browsing_avctpProtocol, DE_UINT, DE_SIZE_16, 0x0103); // version 262 } 263 de_pop_sequence(attribute, browsing_avctpProtocol); 264 } 265 de_pop_sequence(service, attribute); 266 } 267 } 268 de_pop_sequence(service, attribute); 269 270 // 0x0005 "Public Browse Group" 271 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BROWSE_GROUP_LIST); // public browse group 272 attribute = de_push_sequence(service); 273 { 274 de_add_number(attribute, DE_UUID, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PUBLIC_BROWSE_ROOT); 275 } 276 de_pop_sequence(service, attribute); 277 278 // 0x0009 "Bluetooth Profile Descriptor List" 279 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST); 280 attribute = de_push_sequence(service); 281 { 282 uint8_t *avrcProfile = de_push_sequence(attribute); 283 { 284 de_add_number(avrcProfile, DE_UUID, DE_SIZE_16, AV_REMOTE_CONTROL); 285 de_add_number(avrcProfile, DE_UINT, DE_SIZE_16, 0x0105); 286 } 287 de_pop_sequence(attribute, avrcProfile); 288 } 289 de_pop_sequence(service, attribute); 290 291 292 // 0x0100 "Service Name" 293 de_add_number(service, DE_UINT, DE_SIZE_16, 0x0100); 294 if (service_name){ 295 de_add_data(service, DE_STRING, strlen(service_name), (uint8_t *) service_name); 296 } else { 297 if (controller){ 298 de_add_data(service, DE_STRING, strlen(default_avrcp_controller_service_name), (uint8_t *) default_avrcp_controller_service_name); 299 } else { 300 de_add_data(service, DE_STRING, strlen(default_avrcp_target_service_name), (uint8_t *) default_avrcp_target_service_name); 301 } 302 } 303 304 // 0x0100 "Provider Name" 305 de_add_number(service, DE_UINT, DE_SIZE_16, 0x0102); 306 if (service_provider_name){ 307 de_add_data(service, DE_STRING, strlen(service_provider_name), (uint8_t *) service_provider_name); 308 } else { 309 if (controller){ 310 de_add_data(service, DE_STRING, strlen(default_avrcp_controller_service_provider_name), (uint8_t *) default_avrcp_controller_service_provider_name); 311 } else { 312 de_add_data(service, DE_STRING, strlen(default_avrcp_target_service_provider_name), (uint8_t *) default_avrcp_target_service_provider_name); 313 } 314 } 315 316 // 0x0311 "Supported Features" 317 de_add_number(service, DE_UINT, DE_SIZE_16, 0x0311); 318 de_add_number(service, DE_UINT, DE_SIZE_16, supported_features); 319 } 320 321 void avrcp_controller_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint8_t browsing, uint16_t supported_features, const char * service_name, const char * service_provider_name){ 322 avrcp_create_sdp_record(1, service, service_record_handle, browsing, supported_features, service_name, service_provider_name); 323 } 324 325 void avrcp_target_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint8_t browsing, uint16_t supported_features, const char * service_name, const char * service_provider_name){ 326 avrcp_create_sdp_record(0, service, service_record_handle, browsing, supported_features, service_name, service_provider_name); 327 } 328 329 static void avrcp_emit_connection_established(btstack_packet_handler_t callback, uint8_t status, bd_addr_t addr, uint16_t con_handle, uint16_t avrcp_cid){ 330 if (!callback) return; 331 uint8_t event[14]; 332 int pos = 0; 333 event[pos++] = HCI_EVENT_AVRCP_META; 334 event[pos++] = sizeof(event) - 2; 335 event[pos++] = AVRCP_SUBEVENT_CONNECTION_ESTABLISHED; 336 event[pos++] = status; 337 reverse_bd_addr(addr,&event[pos]); 338 pos += 6; 339 little_endian_store_16(event, pos, con_handle); 340 pos += 2; 341 little_endian_store_16(event, pos, avrcp_cid); 342 pos += 2; 343 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 344 } 345 346 static void avrcp_emit_repeat_and_shuffle_mode(btstack_packet_handler_t callback, uint16_t avrcp_cid, uint8_t ctype, avrcp_repeat_mode_t repeat_mode, avrcp_shuffle_mode_t shuffle_mode){ 347 if (!callback) return; 348 uint8_t event[8]; 349 int pos = 0; 350 event[pos++] = HCI_EVENT_AVRCP_META; 351 event[pos++] = sizeof(event) - 2; 352 event[pos++] = AVRCP_SUBEVENT_SHUFFLE_AND_REPEAT_MODE; 353 little_endian_store_16(event, pos, avrcp_cid); 354 pos += 2; 355 event[pos++] = ctype; 356 event[pos++] = repeat_mode; 357 event[pos++] = shuffle_mode; 358 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 359 } 360 361 static void avrcp_emit_operation_status(btstack_packet_handler_t callback, uint8_t subevent, uint16_t avrcp_cid, uint8_t ctype, uint8_t operation_id){ 362 if (!callback) return; 363 uint8_t event[7]; 364 int pos = 0; 365 event[pos++] = HCI_EVENT_AVRCP_META; 366 event[pos++] = sizeof(event) - 2; 367 event[pos++] = subevent; 368 little_endian_store_16(event, pos, avrcp_cid); 369 pos += 2; 370 event[pos++] = ctype; 371 event[pos++] = operation_id; 372 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 373 } 374 375 static void avrcp_emit_connection_closed(btstack_packet_handler_t callback, uint16_t avrcp_cid){ 376 if (!callback) return; 377 uint8_t event[5]; 378 int pos = 0; 379 event[pos++] = HCI_EVENT_AVRCP_META; 380 event[pos++] = sizeof(event) - 2; 381 event[pos++] = AVRCP_SUBEVENT_CONNECTION_RELEASED; 382 little_endian_store_16(event, pos, avrcp_cid); 383 pos += 2; 384 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 385 } 386 387 static avrcp_connection_t * get_avrcp_connection_for_bd_addr(bd_addr_t addr){ 388 btstack_linked_list_iterator_t it; 389 btstack_linked_list_iterator_init(&it, (btstack_linked_list_t *) &avrcp_connections); 390 while (btstack_linked_list_iterator_has_next(&it)){ 391 avrcp_connection_t * connection = (avrcp_connection_t *)btstack_linked_list_iterator_next(&it); 392 if (memcmp(addr, connection->remote_addr, 6) != 0) continue; 393 return connection; 394 } 395 return NULL; 396 } 397 398 static avrcp_connection_t * get_avrcp_connection_for_l2cap_signaling_cid(uint16_t l2cap_cid){ 399 btstack_linked_list_iterator_t it; 400 btstack_linked_list_iterator_init(&it, (btstack_linked_list_t *) &avrcp_connections); 401 while (btstack_linked_list_iterator_has_next(&it)){ 402 avrcp_connection_t * connection = (avrcp_connection_t *)btstack_linked_list_iterator_next(&it); 403 if (connection->l2cap_signaling_cid != l2cap_cid) continue; 404 return connection; 405 } 406 return NULL; 407 } 408 409 static void avrcp_request_can_send_now(avrcp_connection_t * connection, uint16_t l2cap_cid){ 410 connection->wait_to_send = 1; 411 l2cap_request_can_send_now_event(l2cap_cid); 412 } 413 414 static void avrcp_press_and_hold_timeout_handler(btstack_timer_source_t * timer){ 415 UNUSED(timer); 416 avrcp_connection_t * connection = btstack_run_loop_get_timer_context(timer); 417 btstack_run_loop_set_timer(&connection->press_and_hold_cmd_timer, 2000); // 2 seconds timeout 418 btstack_run_loop_add_timer(&connection->press_and_hold_cmd_timer); 419 connection->state = AVCTP_W2_SEND_PRESS_COMMAND; 420 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 421 } 422 423 static void avrcp_press_and_hold_timer_start(avrcp_connection_t * connection){ 424 btstack_run_loop_remove_timer(&connection->press_and_hold_cmd_timer); 425 btstack_run_loop_set_timer_handler(&connection->press_and_hold_cmd_timer, avrcp_press_and_hold_timeout_handler); 426 btstack_run_loop_set_timer_context(&connection->press_and_hold_cmd_timer, connection); 427 btstack_run_loop_set_timer(&connection->press_and_hold_cmd_timer, 2000); // 2 seconds timeout 428 btstack_run_loop_add_timer(&connection->press_and_hold_cmd_timer); 429 } 430 431 static void avrcp_press_and_hold_timer_stop(avrcp_connection_t * connection){ 432 connection->continuous_fast_forward_cmd = 0; 433 btstack_run_loop_remove_timer(&connection->press_and_hold_cmd_timer); 434 } 435 436 static uint8_t request_pass_through_release_control_cmd(avrcp_connection_t * connection){ 437 connection->state = AVCTP_W2_SEND_RELEASE_COMMAND; 438 if (connection->continuous_fast_forward_cmd){ 439 avrcp_press_and_hold_timer_stop(connection); 440 } 441 connection->cmd_operands[0] = 0x80 | connection->cmd_operands[0]; 442 connection->transaction_label++; 443 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 444 return ERROR_CODE_SUCCESS; 445 } 446 447 static inline uint8_t request_pass_through_press_control_cmd(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint16_t playback_speed, uint8_t continuous_fast_forward_cmd){ 448 avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid); 449 if (!connection){ 450 log_error("avrcp: could not find a connection."); 451 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 452 } 453 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 454 connection->state = AVCTP_W2_SEND_PRESS_COMMAND; 455 connection->command_opcode = AVRCP_CMD_OPCODE_PASS_THROUGH; 456 connection->command_type = AVRCP_CTYPE_CONTROL; 457 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 458 connection->subunit_id = AVRCP_SUBUNIT_ID; 459 connection->cmd_operands_length = 0; 460 461 connection->continuous_fast_forward_cmd = continuous_fast_forward_cmd; 462 connection->cmd_operands_length = 2; 463 connection->cmd_operands[0] = opid; 464 if (playback_speed > 0){ 465 connection->cmd_operands[2] = playback_speed; 466 connection->cmd_operands_length++; 467 } 468 connection->cmd_operands[1] = connection->cmd_operands_length - 2; 469 470 if (connection->continuous_fast_forward_cmd){ 471 avrcp_press_and_hold_timer_start(connection); 472 } 473 474 connection->transaction_label++; 475 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 476 return ERROR_CODE_SUCCESS; 477 } 478 479 static uint8_t request_single_pass_through_press_control_cmd(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint16_t playback_speed){ 480 return request_pass_through_press_control_cmd(avrcp_cid, opid, playback_speed, 0); 481 } 482 483 static uint8_t request_continuous_pass_through_press_control_cmd(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint16_t playback_speed){ 484 return request_pass_through_press_control_cmd(avrcp_cid, opid, playback_speed, 1); 485 } 486 487 static int avrcp_send_cmd(uint16_t cid, avrcp_connection_t * connection){ 488 uint8_t command[30]; 489 int pos = 0; 490 // transport header 491 // Transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier) 492 command[pos++] = (connection->transaction_label << 4) | (AVRCP_SINGLE_PACKET << 2) | (AVRCP_COMMAND_FRAME << 1) | 0; 493 // Profile IDentifier (PID) 494 command[pos++] = AV_REMOTE_CONTROL >> 8; 495 command[pos++] = AV_REMOTE_CONTROL & 0x00FF; 496 497 // command_type 498 command[pos++] = connection->command_type; 499 // subunit_type | subunit ID 500 command[pos++] = (connection->subunit_type << 3) | connection->subunit_id; 501 // opcode 502 command[pos++] = (uint8_t)connection->command_opcode; 503 // operands 504 memcpy(command+pos, connection->cmd_operands, connection->cmd_operands_length); 505 pos += connection->cmd_operands_length; 506 507 return l2cap_send(cid, command, pos); 508 } 509 510 static int avrcp_register_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t event_id){ 511 if (connection->notifications_to_deregister & (1 << event_id)) return 0; 512 if (connection->notifications_enabled & (1 << event_id)) return 0; 513 if (connection->notifications_to_register & (1 << event_id)) return 0; 514 connection->notifications_to_register |= (1 << event_id); 515 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 516 return 1; 517 } 518 519 static void avrcp_prepare_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t event_id){ 520 connection->transaction_label++; 521 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 522 connection->command_type = AVRCP_CTYPE_NOTIFY; 523 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 524 connection->subunit_id = AVRCP_SUBUNIT_ID; 525 int pos = 0; 526 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 527 pos += 3; 528 connection->cmd_operands[pos++] = AVRCP_PDU_ID_REGISTER_NOTIFICATION; 529 connection->cmd_operands[pos++] = 0; // reserved(upper 6) | packet_type -> 0 530 big_endian_store_16(connection->cmd_operands, pos, 5); // parameter length 531 pos += 2; 532 connection->cmd_operands[pos++] = event_id; 533 big_endian_store_32(connection->cmd_operands, pos, 0); 534 pos += 4; 535 connection->cmd_operands_length = pos; 536 // AVRCP_SPEC_V14.pdf 166 537 // answer page 61 538 } 539 540 static uint8_t avrcp_cmd_opcode(uint8_t *packet, uint16_t size){ 541 uint8_t cmd_opcode_index = 5; 542 if (cmd_opcode_index > size) return AVRCP_CMD_OPCODE_UNDEFINED; 543 return packet[cmd_opcode_index]; 544 } 545 546 static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connection_t * connection, uint8_t *packet, uint16_t size){ 547 uint8_t operands[20]; 548 uint8_t opcode; 549 int pos = 3; 550 // uint8_t transport_header = packet[0]; 551 // uint8_t transaction_label = transport_header >> 4; 552 // uint8_t packet_type = (transport_header & 0x0F) >> 2; 553 // uint8_t frame_type = (transport_header & 0x03) >> 1; 554 // uint8_t ipid = transport_header & 0x01; 555 // uint8_t byte_value = packet[2]; 556 // uint16_t pid = (byte_value << 8) | packet[2]; 557 558 avrcp_command_type_t ctype = (avrcp_command_type_t) packet[pos++]; 559 uint8_t byte_value = packet[pos++]; 560 avrcp_subunit_type_t subunit_type = (avrcp_subunit_type_t) (byte_value >> 3); 561 avrcp_subunit_type_t subunit_id = (avrcp_subunit_type_t) (byte_value & 0x07); 562 opcode = packet[pos++]; 563 564 // printf(" Transport header 0x%02x (transaction_label %d, packet_type %d, frame_type %d, ipid %d), pid 0x%4x\n", 565 // transport_header, transaction_label, packet_type, frame_type, ipid, pid); 566 // // printf_hexdump(packet+pos, size-pos); 567 568 uint8_t pdu_id; 569 uint16_t param_length; 570 switch (avrcp_cmd_opcode(packet,size)){ 571 case AVRCP_CMD_OPCODE_UNIT_INFO:{ 572 if (connection->state != AVCTP_W2_RECEIVE_RESPONSE) return; 573 connection->state = AVCTP_CONNECTION_OPENED; 574 575 // operands: 576 memcpy(operands, packet+pos, 5); 577 uint8_t unit_type = operands[1] >> 3; 578 uint8_t unit = operands[1] & 0x07; 579 uint32_t company_id = operands[2] << 16 | operands[3] << 8 | operands[4]; 580 log_info(" UNIT INFO response: ctype 0x%02x (0C), subunit_type 0x%02x (1F), subunit_id 0x%02x (07), opcode 0x%02x (30), unit_type 0x%02x, unit %d, company_id 0x%06x", 581 ctype, subunit_type, subunit_id, opcode, unit_type, unit, company_id ); 582 break; 583 } 584 case AVRCP_CMD_OPCODE_VENDOR_DEPENDENT: 585 if (size - pos < 7) { 586 log_error("avrcp: wrong packet size"); 587 return; 588 }; 589 // operands: 590 memcpy(operands, packet+pos, 7); 591 pos += 7; 592 // uint32_t company_id = operands[0] << 16 | operands[1] << 8 | operands[2]; 593 pdu_id = operands[3]; 594 595 if (connection->state != AVCTP_W2_RECEIVE_RESPONSE && pdu_id != AVRCP_PDU_ID_REGISTER_NOTIFICATION){ 596 log_info("AVRCP_CMD_OPCODE_VENDOR_DEPENDENT state %d", connection->state); 597 return; 598 } 599 connection->state = AVCTP_CONNECTION_OPENED; 600 601 602 // uint8_t unit_type = operands[4] >> 3; 603 // uint8_t unit = operands[4] & 0x07; 604 param_length = big_endian_read_16(operands, 5); 605 606 // printf(" VENDOR DEPENDENT response: ctype 0x%02x (0C), subunit_type 0x%02x (1F), subunit_id 0x%02x (07), opcode 0x%02x (30), unit_type 0x%02x, unit %d, company_id 0x%06x\n", 607 // ctype, subunit_type, subunit_id, opcode, unit_type, unit, company_id ); 608 609 // if (ctype == AVRCP_CTYPE_RESPONSE_INTERIM) return; 610 log_info(" VENDOR DEPENDENT response: pdu id 0x%02x, param_length %d, status %s", pdu_id, param_length, avrcp_ctype2str(ctype)); 611 switch (pdu_id){ 612 case AVRCP_PDU_ID_GetCurrentPlayerApplicationSettingValue:{ 613 uint8_t num_attributes = packet[pos++]; 614 int i; 615 avrcp_repeat_mode_t repeat_mode = AVRCP_REPEAT_MODE_INVALID; 616 avrcp_shuffle_mode_t shuffle_mode = AVRCP_SHUFFLE_MODE_INVALID; 617 for (i = 0; i < num_attributes; i++){ 618 uint8_t attribute_id = packet[pos++]; 619 uint8_t attribute_value = packet[pos++]; 620 switch (attribute_id){ 621 case 0x02: 622 repeat_mode = (avrcp_repeat_mode_t) attribute_value; 623 break; 624 case 0x03: 625 shuffle_mode = (avrcp_shuffle_mode_t) attribute_value; 626 break; 627 default: 628 break; 629 } 630 } 631 avrcp_emit_repeat_and_shuffle_mode(avrcp_callback, connection->l2cap_signaling_cid, ctype, repeat_mode, shuffle_mode); 632 break; 633 } 634 case AVRCP_PDU_ID_SetPlayerApplicationSettingValue:{ 635 uint8_t event[6]; 636 int offset = 0; 637 event[offset++] = HCI_EVENT_AVRCP_META; 638 event[offset++] = sizeof(event) - 2; 639 event[offset++] = AVRCP_SUBEVENT_PLAYER_APPLICATION_VALUE_RESPONSE; 640 little_endian_store_16(event, offset, connection->l2cap_signaling_cid); 641 offset += 2; 642 event[offset++] = ctype; 643 (*avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 644 break; 645 } 646 case AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME:{ 647 uint8_t event[7]; 648 int offset = 0; 649 event[offset++] = HCI_EVENT_AVRCP_META; 650 event[offset++] = sizeof(event) - 2; 651 event[offset++] = AVRCP_SUBEVENT_SET_ABSOLUTE_VOLUME_RESPONSE; 652 little_endian_store_16(event, offset, connection->l2cap_signaling_cid); 653 offset += 2; 654 event[offset++] = ctype; 655 event[offset++] = packet[pos++]; 656 (*avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 657 break; 658 } 659 case AVRCP_PDU_ID_GET_CAPABILITIES:{ 660 avrcp_capability_id_t capability_id = (avrcp_capability_id_t) packet[pos++]; 661 uint8_t capability_count = packet[pos++]; 662 int i; 663 switch (capability_id){ 664 case AVRCP_CAPABILITY_ID_COMPANY: 665 // log_info("Supported companies %d: ", capability_count); 666 for (i = 0; i < capability_count; i++){ 667 uint32_t company_id = big_endian_read_24(packet, pos); 668 pos += 3; 669 log_info(" 0x%06x, ", company_id); 670 } 671 break; 672 case AVRCP_CAPABILITY_ID_EVENT: 673 // log_info("Supported events %d: ", capability_count); 674 for (i = 0; i < capability_count; i++){ 675 uint8_t event_id = packet[pos++]; 676 log_info(" 0x%02x %s", event_id, avrcp_event2str(event_id)); 677 } 678 break; 679 } 680 break; 681 } 682 case AVRCP_PDU_ID_GET_PLAY_STATUS:{ 683 uint32_t song_length = big_endian_read_32(packet, pos); 684 pos += 4; 685 uint32_t song_position = big_endian_read_32(packet, pos); 686 pos += 4; 687 uint8_t play_status = packet[pos]; 688 // log_info(" GET_PLAY_STATUS length 0x%04X, position 0x%04X, status %s", song_length, song_position, avrcp_play_status2str(play_status)); 689 690 uint8_t event[15]; 691 int offset = 0; 692 event[offset++] = HCI_EVENT_AVRCP_META; 693 event[offset++] = sizeof(event) - 2; 694 event[offset++] = AVRCP_SUBEVENT_PLAY_STATUS; 695 little_endian_store_16(event, offset, connection->l2cap_signaling_cid); 696 offset += 2; 697 event[offset++] = ctype; 698 little_endian_store_32(event, offset, song_length); 699 offset += 4; 700 little_endian_store_32(event, offset, song_position); 701 offset += 4; 702 event[offset++] = play_status; 703 (*avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 704 break; 705 } 706 case AVRCP_PDU_ID_REGISTER_NOTIFICATION:{ 707 avrcp_notification_event_id_t event_id = (avrcp_notification_event_id_t) packet[pos++]; 708 uint16_t event_mask = (1 << event_id); 709 uint16_t reset_event_mask = ~event_mask; 710 switch (ctype){ 711 case AVRCP_CTYPE_RESPONSE_INTERIM: 712 // register as enabled 713 connection->notifications_enabled |= event_mask; 714 // printf("INTERIM notifications_enabled 0x%2x, notifications_to_register 0x%2x\n", connection->notifications_enabled, connection->notifications_to_register); 715 break; 716 case AVRCP_CTYPE_RESPONSE_CHANGED_STABLE: 717 // received change, event is considered deregistered 718 // we are re-enabling it automatically, if it is not 719 // explicitly disabled 720 connection->notifications_enabled &= reset_event_mask; 721 if (! (connection->notifications_to_deregister & event_mask)){ 722 avrcp_register_notification(connection, event_id); 723 // printf("CHANGED_STABLE notifications_enabled 0x%2x, notifications_to_register 0x%2x\n", connection->notifications_enabled, connection->notifications_to_register); 724 } else { 725 connection->notifications_to_deregister &= reset_event_mask; 726 } 727 break; 728 default: 729 connection->notifications_to_register &= reset_event_mask; 730 connection->notifications_enabled &= reset_event_mask; 731 connection->notifications_to_deregister &= reset_event_mask; 732 break; 733 } 734 735 switch (event_id){ 736 case AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED:{ 737 uint8_t event[7]; 738 int offset = 0; 739 event[offset++] = HCI_EVENT_AVRCP_META; 740 event[offset++] = sizeof(event) - 2; 741 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_PLAYBACK_STATUS_CHANGED; 742 little_endian_store_16(event, offset, connection->l2cap_signaling_cid); 743 offset += 2; 744 event[offset++] = ctype; 745 event[offset++] = packet[pos]; 746 (*avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 747 break; 748 } 749 case AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED:{ 750 uint8_t event[6]; 751 int offset = 0; 752 event[offset++] = HCI_EVENT_AVRCP_META; 753 event[offset++] = sizeof(event) - 2; 754 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_TRACK_CHANGED; 755 little_endian_store_16(event, offset, connection->l2cap_signaling_cid); 756 offset += 2; 757 event[offset++] = ctype; 758 (*avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 759 break; 760 } 761 case AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED:{ 762 uint8_t event[6]; 763 int offset = 0; 764 event[offset++] = HCI_EVENT_AVRCP_META; 765 event[offset++] = sizeof(event) - 2; 766 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_NOW_PLAYING_CONTENT_CHANGED; 767 little_endian_store_16(event, offset, connection->l2cap_signaling_cid); 768 offset += 2; 769 event[offset++] = ctype; 770 (*avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 771 break; 772 } 773 case AVRCP_NOTIFICATION_EVENT_AVAILABLE_PLAYERS_CHANGED:{ 774 uint8_t event[6]; 775 int offset = 0; 776 event[offset++] = HCI_EVENT_AVRCP_META; 777 event[offset++] = sizeof(event) - 2; 778 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_AVAILABLE_PLAYERS_CHANGED; 779 little_endian_store_16(event, offset, connection->l2cap_signaling_cid); 780 offset += 2; 781 event[offset++] = ctype; 782 (*avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 783 break; 784 } 785 case AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED:{ 786 uint8_t event[7]; 787 int offset = 0; 788 event[offset++] = HCI_EVENT_AVRCP_META; 789 event[offset++] = sizeof(event) - 2; 790 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED; 791 little_endian_store_16(event, offset, connection->l2cap_signaling_cid); 792 offset += 2; 793 event[offset++] = ctype; 794 event[offset++] = packet[pos++] & 0x7F; 795 (*avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 796 break; 797 } 798 // case AVRCP_NOTIFICATION_EVENT_PLAYER_APPLICATION_SETTING_CHANGED:{ 799 // uint8_t num_PlayerApplicationSettingAttributes = packet[pos++]; 800 // int i; 801 // for (i = 0; i < num_PlayerApplicationSettingAttributes; i++){ 802 // uint8_t PlayerApplicationSetting_AttributeID = packet[pos++]; 803 // uint8_t PlayerApplicationSettingValueID = packet[pos++]; 804 // } 805 // break; 806 // } 807 // case AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED: 808 // uint16_t player_id = big_endian_read_16(packet, pos); 809 // pos += 2; 810 // uint16_t uid_counter = big_endian_read_16(packet, pos); 811 // pos += 2; 812 // break; 813 // case AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED: 814 // uint16_t uid_counter = big_endian_read_16(packet, pos); 815 // pos += 2; 816 // break; 817 default: 818 log_info("avrcp: not implemented"); 819 break; 820 } 821 if (connection->notifications_to_register != 0){ 822 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 823 } 824 break; 825 } 826 827 case AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES:{ 828 uint8_t num_attributes = packet[pos++]; 829 int i; 830 struct item { 831 uint16_t len; 832 uint8_t * value; 833 } items[AVRCP_MEDIA_ATTR_COUNT]; 834 memset(items, 0, sizeof(items)); 835 836 uint16_t string_attributes_len = 0; 837 uint8_t num_string_attributes = 0; 838 uint16_t total_event_payload_for_string_attributes = HCI_EVENT_PAYLOAD_SIZE-2; 839 uint16_t max_string_attribute_value_len = 0; 840 if (ctype == AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE || ctype == AVRCP_CTYPE_RESPONSE_CHANGED_STABLE){ 841 for (i = 0; i < num_attributes; i++){ 842 avrcp_media_attribute_id_t attr_id = (avrcp_media_attribute_id_t) big_endian_read_32(packet, pos); 843 pos += 4; 844 // uint16_t character_set = big_endian_read_16(packet, pos); 845 pos += 2; 846 uint16_t attr_value_length = big_endian_read_16(packet, pos); 847 pos += 2; 848 849 // debug - to remove later 850 uint8_t value[100]; 851 uint16_t value_len = sizeof(value) <= attr_value_length? sizeof(value) - 1 : attr_value_length; 852 memcpy(value, packet+pos, value_len); 853 value[value_len] = 0; 854 // printf("Now Playing Info %s: %s \n", attribute2str(attr_id), value); 855 // end debug 856 857 if ((attr_id >= 1) || (attr_id <= AVRCP_MEDIA_ATTR_COUNT)) { 858 items[attr_id-1].len = attr_value_length; 859 items[attr_id-1].value = &packet[pos]; 860 switch (attr_id){ 861 case AVRCP_MEDIA_ATTR_TITLE: 862 case AVRCP_MEDIA_ATTR_ARTIST: 863 case AVRCP_MEDIA_ATTR_ALBUM: 864 case AVRCP_MEDIA_ATTR_GENRE: 865 num_string_attributes++; 866 string_attributes_len += attr_value_length; 867 if (max_string_attribute_value_len < attr_value_length){ 868 max_string_attribute_value_len = attr_value_length; 869 } 870 break; 871 default: 872 break; 873 } 874 } 875 pos += attr_value_length; 876 } 877 } 878 879 // subtract space for fixed fields 880 total_event_payload_for_string_attributes -= 14 + 4; // 4 for '\0' 881 882 // @TODO optimize space by repeatedly decreasing max_string_attribute_value_len until it fits into buffer instead of crude divion 883 uint16_t max_value_len = total_event_payload_for_string_attributes > string_attributes_len? max_string_attribute_value_len : total_event_payload_for_string_attributes/(string_attributes_len+1) - 1; 884 // printf("num_string_attributes %d, string_attributes_len %d, total_event_payload_for_string_attributes %d, max_value_len %d \n", num_string_attributes, string_attributes_len, total_event_payload_for_string_attributes, max_value_len); 885 886 const uint8_t attribute_order[] = { 887 AVRCP_MEDIA_ATTR_TRACK, 888 AVRCP_MEDIA_ATTR_TOTAL_TRACKS, 889 AVRCP_MEDIA_ATTR_SONG_LENGTH, 890 AVRCP_MEDIA_ATTR_TITLE, 891 AVRCP_MEDIA_ATTR_ARTIST, 892 AVRCP_MEDIA_ATTR_ALBUM, 893 AVRCP_MEDIA_ATTR_GENRE 894 }; 895 896 uint8_t event[HCI_EVENT_BUFFER_SIZE]; 897 event[0] = HCI_EVENT_AVRCP_META; 898 pos = 2; 899 event[pos++] = AVRCP_SUBEVENT_NOW_PLAYING_INFO; 900 little_endian_store_16(event, pos, connection->l2cap_signaling_cid); 901 pos += 2; 902 event[pos++] = ctype; 903 for (i = 0; i < sizeof(attribute_order); i++){ 904 avrcp_media_attribute_id_t attr_id = (avrcp_media_attribute_id_t) attribute_order[i]; 905 uint16_t value_len = 0; 906 switch (attr_id){ 907 case AVRCP_MEDIA_ATTR_TITLE: 908 case AVRCP_MEDIA_ATTR_ARTIST: 909 case AVRCP_MEDIA_ATTR_ALBUM: 910 case AVRCP_MEDIA_ATTR_GENRE: 911 if (items[attr_id-1].value){ 912 value_len = items[attr_id-1].len <= max_value_len ? items[attr_id-1].len : max_value_len; 913 } 914 event[pos++] = value_len + 1; 915 if (value_len){ 916 memcpy(event+pos, items[attr_id-1].value, value_len); 917 pos += value_len; 918 } 919 event[pos++] = 0; 920 break; 921 case AVRCP_MEDIA_ATTR_SONG_LENGTH: 922 if (items[attr_id-1].value){ 923 little_endian_store_32(event, pos, btstack_atoi((char *)items[attr_id-1].value)); 924 } else { 925 little_endian_store_32(event, pos, 0); 926 } 927 pos += 4; 928 break; 929 case AVRCP_MEDIA_ATTR_TRACK: 930 case AVRCP_MEDIA_ATTR_TOTAL_TRACKS: 931 if (items[attr_id-1].value){ 932 event[pos++] = btstack_atoi((char *)items[attr_id-1].value); 933 } else { 934 event[pos++] = 0; 935 } 936 break; 937 } 938 } 939 event[1] = pos - 2; 940 // printf_hexdump(event, pos); 941 (*avrcp_callback)(HCI_EVENT_PACKET, 0, event, pos); 942 break; 943 } 944 default: 945 break; 946 } 947 break; 948 case AVRCP_CMD_OPCODE_PASS_THROUGH:{ 949 // 0x80 | connection->cmd_operands[0] 950 uint8_t operation_id = packet[pos++]; 951 switch (connection->state){ 952 case AVCTP_W2_RECEIVE_PRESS_RESPONSE: 953 if (connection->continuous_fast_forward_cmd){ 954 connection->state = AVCTP_W4_STOP; 955 } else { 956 connection->state = AVCTP_W2_SEND_RELEASE_COMMAND; 957 } 958 break; 959 case AVCTP_W2_RECEIVE_RESPONSE: 960 connection->state = AVCTP_CONNECTION_OPENED; 961 break; 962 default: 963 // check for notifications? move state transition down 964 // log_info("AVRCP_CMD_OPCODE_PASS_THROUGH state %d\n", connection->state); 965 break; 966 } 967 if (connection->state == AVCTP_W4_STOP){ 968 avrcp_emit_operation_status(avrcp_callback, AVRCP_SUBEVENT_OPERATION_START, connection->l2cap_signaling_cid, ctype, operation_id); 969 } 970 if (connection->state == AVCTP_CONNECTION_OPENED) { 971 // RELEASE response 972 operation_id = operation_id & 0x7F; 973 avrcp_emit_operation_status(avrcp_callback, AVRCP_SUBEVENT_OPERATION_COMPLETE, connection->l2cap_signaling_cid, ctype, operation_id); 974 } 975 if (connection->state == AVCTP_W2_SEND_RELEASE_COMMAND){ 976 // PRESS response 977 request_pass_through_release_control_cmd(connection); 978 } 979 break; 980 } 981 default: 982 break; 983 } 984 } 985 986 static void avrcp_handle_can_send_now(avrcp_connection_t * connection){ 987 int i; 988 switch (connection->state){ 989 case AVCTP_W2_SEND_PRESS_COMMAND: 990 connection->state = AVCTP_W2_RECEIVE_PRESS_RESPONSE; 991 avrcp_send_cmd(connection->l2cap_signaling_cid, connection); 992 break; 993 case AVCTP_W2_SEND_COMMAND: 994 case AVCTP_W2_SEND_RELEASE_COMMAND: 995 connection->state = AVCTP_W2_RECEIVE_RESPONSE; 996 avrcp_send_cmd(connection->l2cap_signaling_cid, connection); 997 break; 998 case AVCTP_CONNECTION_OPENED: 999 if (connection->notifications_to_register != 0){ 1000 for (i = 1; i <= AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED; i++){ 1001 if (connection->notifications_to_register & (1<<i)){ 1002 connection->notifications_to_register &= ~ (1 << i); 1003 avrcp_prepare_notification(connection, (avrcp_notification_event_id_t) i); 1004 connection->state = AVCTP_W2_RECEIVE_RESPONSE; 1005 avrcp_send_cmd(connection->l2cap_signaling_cid, connection); 1006 return; 1007 } 1008 } 1009 } 1010 return; 1011 default: 1012 return; 1013 } 1014 } 1015 1016 static avrcp_connection_t * avrcp_create_connection(bd_addr_t remote_addr){ 1017 avrcp_connection_t * connection = btstack_memory_avrcp_connection_get(); 1018 memset(connection, 0, sizeof(avrcp_connection_t)); 1019 connection->state = AVCTP_CONNECTION_IDLE; 1020 connection->transaction_label = 0xFF; 1021 memcpy(connection->remote_addr, remote_addr, 6); 1022 btstack_linked_list_add(&avrcp_connections, (btstack_linked_item_t *) connection); 1023 return connection; 1024 } 1025 1026 static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 1027 bd_addr_t event_addr; 1028 uint16_t local_cid; 1029 uint8_t status; 1030 hci_con_handle_t con_handle; 1031 avrcp_connection_t * connection = NULL; 1032 1033 switch (packet_type) { 1034 case L2CAP_DATA_PACKET: 1035 connection = get_avrcp_connection_for_l2cap_signaling_cid(channel); 1036 if (!connection) break; 1037 avrcp_handle_l2cap_data_packet_for_signaling_connection(connection, packet, size); 1038 break; 1039 1040 case HCI_EVENT_PACKET: 1041 switch (hci_event_packet_get_type(packet)) { 1042 case L2CAP_EVENT_INCOMING_CONNECTION: 1043 l2cap_event_incoming_connection_get_address(packet, event_addr); 1044 local_cid = l2cap_event_incoming_connection_get_local_cid(packet); 1045 connection = avrcp_create_connection(event_addr); 1046 if (!connection) { 1047 log_error("Failed to alloc connection structure"); 1048 l2cap_decline_connection(local_cid); 1049 break; 1050 } 1051 connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED; 1052 connection->l2cap_signaling_cid = local_cid; 1053 l2cap_accept_connection(local_cid); 1054 break; 1055 1056 case L2CAP_EVENT_CHANNEL_OPENED: 1057 l2cap_event_channel_opened_get_address(packet, event_addr); 1058 1059 connection = get_avrcp_connection_for_bd_addr(event_addr); 1060 status = l2cap_event_channel_opened_get_status(packet); 1061 local_cid = l2cap_event_channel_opened_get_local_cid(packet); 1062 1063 if (connection){ 1064 // outgoing connection 1065 if (l2cap_event_channel_opened_get_status(packet)){ 1066 log_error("L2CAP connection to connection %s failed. status code 0x%02x", 1067 bd_addr_to_str(event_addr), l2cap_event_channel_opened_get_status(packet)); 1068 if (connection->state == AVCTP_CONNECTION_W4_L2CAP_CONNECTED){ 1069 avrcp_emit_connection_established(avrcp_callback, status, event_addr, HCI_CON_HANDLE_INVALID, local_cid); 1070 } 1071 // free connection 1072 btstack_linked_list_remove(&avrcp_connections, (btstack_linked_item_t*) connection); 1073 btstack_memory_avrcp_connection_free(connection); 1074 break; 1075 } 1076 } else { 1077 // incoming connection 1078 connection = avrcp_create_connection(event_addr); 1079 if (!connection) { 1080 log_error("Failed to alloc connection structure"); 1081 l2cap_disconnect(local_cid, 0); // reason isn't used 1082 break; 1083 } 1084 } 1085 1086 connection->l2cap_signaling_cid = local_cid; 1087 con_handle = l2cap_event_channel_opened_get_handle(packet); 1088 connection->state = AVCTP_CONNECTION_OPENED; 1089 avrcp_emit_connection_established(avrcp_callback, ERROR_CODE_SUCCESS, event_addr, con_handle, local_cid); 1090 break; 1091 1092 case L2CAP_EVENT_CAN_SEND_NOW: 1093 connection = get_avrcp_connection_for_l2cap_signaling_cid(channel); 1094 if (!connection) break; 1095 avrcp_handle_can_send_now(connection); 1096 break; 1097 1098 case L2CAP_EVENT_CHANNEL_CLOSED: 1099 // data: event (8), len(8), channel (16) 1100 local_cid = l2cap_event_channel_closed_get_local_cid(packet); 1101 connection = get_avrcp_connection_for_l2cap_signaling_cid(local_cid); 1102 if (connection){ 1103 avrcp_emit_connection_closed(avrcp_callback, connection->l2cap_signaling_cid); 1104 // free connection 1105 btstack_linked_list_remove(&avrcp_connections, (btstack_linked_item_t*) connection); 1106 btstack_memory_avrcp_connection_free(connection); 1107 break; 1108 } 1109 break; 1110 default: 1111 break; 1112 } 1113 break; 1114 default: 1115 break; 1116 } 1117 } 1118 1119 void avrcp_init(void){ 1120 avrcp_connections = NULL; 1121 l2cap_register_service(&packet_handler, BLUETOOTH_PROTOCOL_AVCTP, 0xffff, LEVEL_0); 1122 } 1123 1124 void avrcp_register_packet_handler(btstack_packet_handler_t callback){ 1125 if (callback == NULL){ 1126 log_error("avrcp_register_packet_handler called with NULL callback"); 1127 return; 1128 } 1129 avrcp_callback = callback; 1130 } 1131 1132 uint8_t avrcp_connect(bd_addr_t bd_addr, uint16_t * avrcp_cid){ 1133 avrcp_connection_t * connection = get_avrcp_connection_for_bd_addr(bd_addr); 1134 if (connection){ 1135 return ERROR_CODE_COMMAND_DISALLOWED; 1136 } 1137 1138 connection = avrcp_create_connection(bd_addr); 1139 if (!connection){ 1140 log_error("avrcp: could not allocate connection struct."); 1141 return BTSTACK_MEMORY_ALLOC_FAILED; 1142 } 1143 1144 connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED; 1145 l2cap_create_channel(packet_handler, connection->remote_addr, BLUETOOTH_PROTOCOL_AVCTP, 0xffff, &connection->l2cap_signaling_cid); 1146 if (avrcp_cid) { 1147 *avrcp_cid = connection->l2cap_signaling_cid; 1148 } 1149 return ERROR_CODE_SUCCESS; 1150 } 1151 1152 uint8_t avrcp_unit_info(uint16_t avrcp_cid){ 1153 avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid); 1154 if (!connection){ 1155 log_error("avrcp_unit_info: could not find a connection."); 1156 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1157 } 1158 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1159 connection->state = AVCTP_W2_SEND_COMMAND; 1160 1161 connection->transaction_label++; 1162 connection->command_opcode = AVRCP_CMD_OPCODE_UNIT_INFO; 1163 connection->command_type = AVRCP_CTYPE_STATUS; 1164 connection->subunit_type = AVRCP_SUBUNIT_TYPE_UNIT; //vendor unique 1165 connection->subunit_id = AVRCP_SUBUNIT_ID_IGNORE; 1166 memset(connection->cmd_operands, 0xFF, connection->cmd_operands_length); 1167 connection->cmd_operands_length = 5; 1168 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1169 return ERROR_CODE_SUCCESS; 1170 } 1171 1172 static uint8_t avrcp_get_capabilities(uint16_t avrcp_cid, uint8_t capability_id){ 1173 avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid); 1174 if (!connection){ 1175 log_error("avrcp_get_capabilities: could not find a connection."); 1176 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1177 } 1178 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1179 connection->state = AVCTP_W2_SEND_COMMAND; 1180 1181 connection->transaction_label++; 1182 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1183 connection->command_type = AVRCP_CTYPE_STATUS; 1184 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1185 connection->subunit_id = AVRCP_SUBUNIT_ID; 1186 big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID); 1187 connection->cmd_operands[3] = AVRCP_PDU_ID_GET_CAPABILITIES; // PDU ID 1188 connection->cmd_operands[4] = 0; 1189 big_endian_store_16(connection->cmd_operands, 5, 1); // parameter length 1190 connection->cmd_operands[7] = capability_id; // capability ID 1191 connection->cmd_operands_length = 8; 1192 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1193 return ERROR_CODE_SUCCESS; 1194 } 1195 1196 uint8_t avrcp_get_supported_company_ids(uint16_t avrcp_cid){ 1197 return avrcp_get_capabilities(avrcp_cid, AVRCP_CAPABILITY_ID_COMPANY); 1198 } 1199 1200 uint8_t avrcp_get_supported_events(uint16_t avrcp_cid){ 1201 return avrcp_get_capabilities(avrcp_cid, AVRCP_CAPABILITY_ID_EVENT); 1202 } 1203 1204 1205 uint8_t avrcp_play(uint16_t avrcp_cid){ 1206 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PLAY, 0); 1207 } 1208 1209 uint8_t avrcp_stop(uint16_t avrcp_cid){ 1210 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_STOP, 0); 1211 } 1212 1213 uint8_t avrcp_pause(uint16_t avrcp_cid){ 1214 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PAUSE, 0); 1215 } 1216 1217 uint8_t avrcp_forward(uint16_t avrcp_cid){ 1218 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FORWARD, 0); 1219 } 1220 1221 uint8_t avrcp_backward(uint16_t avrcp_cid){ 1222 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_BACKWARD, 0); 1223 } 1224 1225 uint8_t avrcp_start_rewind(uint16_t avrcp_cid){ 1226 return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_REWIND, 0); 1227 } 1228 1229 uint8_t avrcp_volume_up(uint16_t avrcp_cid){ 1230 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_UP, 0); 1231 } 1232 1233 uint8_t avrcp_volume_down(uint16_t avrcp_cid){ 1234 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_DOWN, 0); 1235 } 1236 1237 uint8_t avrcp_mute(uint16_t avrcp_cid){ 1238 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_MUTE, 0); 1239 } 1240 1241 uint8_t avrcp_skip(uint16_t avrcp_cid){ 1242 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_SKIP, 0); 1243 } 1244 1245 uint8_t avrcp_stop_rewind(uint16_t avrcp_cid){ 1246 avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid); 1247 if (!connection){ 1248 log_error("avrcp_stop_rewind: could not find a connection."); 1249 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1250 } 1251 if (connection->state != AVCTP_W4_STOP) return ERROR_CODE_COMMAND_DISALLOWED; 1252 return request_pass_through_release_control_cmd(connection); 1253 } 1254 1255 uint8_t avrcp_start_fast_forward(uint16_t avrcp_cid){ 1256 return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FAST_FORWARD, 0); 1257 } 1258 1259 uint8_t avrcp_fast_forward(uint16_t avrcp_cid){ 1260 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FAST_FORWARD, 0); 1261 } 1262 1263 uint8_t avrcp_rewind(uint16_t avrcp_cid){ 1264 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_REWIND, 0); 1265 } 1266 1267 1268 uint8_t avrcp_stop_fast_forward(uint16_t avrcp_cid){ 1269 avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid); 1270 if (!connection){ 1271 log_error("avrcp_stop_fast_forward: could not find a connection."); 1272 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1273 } 1274 if (connection->state != AVCTP_W4_STOP) return ERROR_CODE_COMMAND_DISALLOWED; 1275 return request_pass_through_release_control_cmd(connection); 1276 } 1277 1278 uint8_t avrcp_get_play_status(uint16_t avrcp_cid){ 1279 avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid); 1280 if (!connection){ 1281 log_error("avrcp_get_play_status: could not find a connection."); 1282 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1283 } 1284 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1285 connection->state = AVCTP_W2_SEND_COMMAND; 1286 1287 connection->transaction_label++; 1288 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1289 connection->command_type = AVRCP_CTYPE_STATUS; 1290 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1291 connection->subunit_id = AVRCP_SUBUNIT_ID; 1292 big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID); 1293 connection->cmd_operands[3] = AVRCP_PDU_ID_GET_PLAY_STATUS; 1294 connection->cmd_operands[4] = 0; // reserved(upper 6) | packet_type -> 0 1295 big_endian_store_16(connection->cmd_operands, 5, 0); // parameter length 1296 connection->cmd_operands_length = 7; 1297 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1298 1299 return ERROR_CODE_SUCCESS; 1300 } 1301 1302 uint8_t avrcp_enable_notification(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id){ 1303 avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid); 1304 if (!connection){ 1305 log_error("avrcp_get_play_status: could not find a connection."); 1306 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1307 } 1308 avrcp_register_notification(connection, event_id); 1309 return ERROR_CODE_SUCCESS; 1310 } 1311 1312 uint8_t avrcp_disable_notification(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id){ 1313 avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid); 1314 if (!connection){ 1315 log_error("avrcp_get_play_status: could not find a connection."); 1316 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1317 } 1318 connection->notifications_to_deregister |= (1 << event_id); 1319 return ERROR_CODE_SUCCESS; 1320 } 1321 1322 uint8_t avrcp_get_now_playing_info(uint16_t avrcp_cid){ 1323 avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid); 1324 if (!connection){ 1325 log_error("avrcp_get_capabilities: could not find a connection."); 1326 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1327 } 1328 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1329 connection->state = AVCTP_W2_SEND_COMMAND; 1330 1331 connection->transaction_label++; 1332 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1333 connection->command_type = AVRCP_CTYPE_STATUS; 1334 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1335 connection->subunit_id = AVRCP_SUBUNIT_ID; 1336 int pos = 0; 1337 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 1338 pos += 3; 1339 connection->cmd_operands[pos++] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES; // PDU ID 1340 connection->cmd_operands[pos++] = 0; 1341 1342 // Parameter Length 1343 big_endian_store_16(connection->cmd_operands, pos, 9); 1344 pos += 2; 1345 1346 // write 8 bytes value 1347 memset(connection->cmd_operands + pos, 0, 8); // identifier: PLAYING 1348 pos += 8; 1349 1350 connection->cmd_operands[pos++] = 0; // attribute count, if 0 get all attributes 1351 // every attribute is 4 bytes long 1352 1353 connection->cmd_operands_length = pos; 1354 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1355 return ERROR_CODE_SUCCESS; 1356 } 1357 1358 uint8_t avrcp_set_absolute_volume(uint16_t avrcp_cid, uint8_t volume){ 1359 avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid); 1360 if (!connection){ 1361 log_error("avrcp_get_capabilities: could not find a connection."); 1362 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1363 } 1364 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1365 connection->state = AVCTP_W2_SEND_COMMAND; 1366 1367 connection->transaction_label++; 1368 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1369 connection->command_type = AVRCP_CTYPE_CONTROL; 1370 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1371 connection->subunit_id = AVRCP_SUBUNIT_ID; 1372 int pos = 0; 1373 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 1374 pos += 3; 1375 connection->cmd_operands[pos++] = AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME; // PDU ID 1376 connection->cmd_operands[pos++] = 0; 1377 1378 // Parameter Length 1379 big_endian_store_16(connection->cmd_operands, pos, 1); 1380 pos += 2; 1381 connection->cmd_operands[pos++] = volume; 1382 1383 connection->cmd_operands_length = pos; 1384 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1385 return ERROR_CODE_SUCCESS; 1386 } 1387 1388 uint8_t avrcp_query_shuffle_and_repeat_modes(uint16_t avrcp_cid){ 1389 avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid); 1390 if (!connection){ 1391 log_error("avrcp_get_capabilities: could not find a connection."); 1392 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1393 } 1394 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1395 connection->state = AVCTP_W2_SEND_COMMAND; 1396 1397 connection->transaction_label++; 1398 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1399 connection->command_type = AVRCP_CTYPE_STATUS; 1400 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1401 connection->subunit_id = AVRCP_SUBUNIT_ID; 1402 big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID); 1403 connection->cmd_operands[3] = AVRCP_PDU_ID_GetCurrentPlayerApplicationSettingValue; // PDU ID 1404 connection->cmd_operands[4] = 0; 1405 big_endian_store_16(connection->cmd_operands, 5, 5); // parameter length 1406 connection->cmd_operands[7] = 4; // NumPlayerApplicationSettingAttributeID 1407 // PlayerApplicationSettingAttributeID1 AVRCP Spec, Appendix F, 133 1408 connection->cmd_operands[8] = 0x01; // equalizer (1-OFF, 2-ON) 1409 connection->cmd_operands[9] = 0x02; // repeat (1-off, 2-single track, 3-all tracks, 4-group repeat) 1410 connection->cmd_operands[10] = 0x03; // shuffle (1-off, 2-all tracks, 3-group shuffle) 1411 connection->cmd_operands[11] = 0x04; // scan (1-off, 2-all tracks, 3-group scan) 1412 connection->cmd_operands_length = 12; 1413 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1414 return ERROR_CODE_SUCCESS; 1415 } 1416 1417 static uint8_t avrcp_set_current_player_application_setting_value(uint16_t avrcp_cid, uint8_t attribute_id, uint8_t attribute_value){ 1418 avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid); 1419 if (!connection){ 1420 log_error("avrcp_get_capabilities: could not find a connection."); 1421 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1422 } 1423 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1424 connection->state = AVCTP_W2_SEND_COMMAND; 1425 1426 connection->transaction_label++; 1427 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1428 connection->command_type = AVRCP_CTYPE_CONTROL; 1429 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1430 connection->subunit_id = AVRCP_SUBUNIT_ID; 1431 int pos = 0; 1432 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 1433 pos += 3; 1434 connection->cmd_operands[pos++] = AVRCP_PDU_ID_SetPlayerApplicationSettingValue; // PDU ID 1435 connection->cmd_operands[pos++] = 0; 1436 // Parameter Length 1437 big_endian_store_16(connection->cmd_operands, pos, 3); 1438 pos += 2; 1439 connection->cmd_operands[pos++] = 2; 1440 connection->cmd_operands_length = pos; 1441 connection->cmd_operands[pos++] = attribute_id; 1442 connection->cmd_operands[pos++] = attribute_value; 1443 connection->cmd_operands_length = pos; 1444 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1445 return ERROR_CODE_SUCCESS; 1446 } 1447 1448 uint8_t avrcp_set_shuffle_mode(uint16_t avrcp_cid, avrcp_shuffle_mode_t mode){ 1449 if (mode < AVRCP_SHUFFLE_MODE_OFF || mode > AVRCP_SHUFFLE_MODE_GROUP) return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; 1450 return avrcp_set_current_player_application_setting_value(avrcp_cid, 0x03, mode); 1451 } 1452 1453 uint8_t avrcp_set_repeat_mode(uint16_t avrcp_cid, avrcp_repeat_mode_t mode){ 1454 if (mode < AVRCP_REPEAT_MODE_OFF || mode > AVRCP_REPEAT_MODE_GROUP) return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; 1455 return avrcp_set_current_player_application_setting_value(avrcp_cid, 0x02, mode); 1456 } 1457 1458 uint8_t avrcp_disconnect(uint16_t avrcp_cid){ 1459 avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid); 1460 if (!connection){ 1461 log_error("avrcp_get_capabilities: could not find a connection."); 1462 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1463 } 1464 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1465 l2cap_disconnect(connection->l2cap_signaling_cid, 0); 1466 return ERROR_CODE_SUCCESS; 1467 }