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_controller.c" 39 40 #include <stdint.h> 41 #include <string.h> 42 #include <inttypes.h> 43 44 #include "btstack.h" 45 #include "classic/avrcp.h" 46 #include "classic/avrcp_controller.h" 47 48 #define AVRCP_CMD_BUFFER_SIZE 30 49 50 // made public in avrcp_controller.h 51 avrcp_context_t avrcp_controller_context; 52 static uint16_t transaction_id_counter = 0; 53 54 static uint8_t avrcp_controller_get_next_transaction_label(void){ 55 transaction_id_counter++; 56 if (transaction_id_counter == 16){ 57 transaction_id_counter = 1; 58 } 59 return transaction_id_counter; 60 } 61 62 static uint16_t avrcp_get_max_payload_size_for_packet_type(avrcp_packet_type_t packet_type){ 63 switch (packet_type){ 64 case AVRCP_SINGLE_PACKET: 65 return AVRCP_CMD_BUFFER_SIZE - 3; 66 case AVRCP_START_PACKET: 67 return AVRCP_CMD_BUFFER_SIZE - 4; 68 case AVRCP_CONTINUE_PACKET: 69 case AVRCP_END_PACKET: 70 return AVRCP_CMD_BUFFER_SIZE - 1; 71 default: 72 btstack_assert(false); 73 return 0; 74 } 75 } 76 77 static int avrcp_controller_supports_browsing(uint16_t controller_supported_features){ 78 return controller_supported_features & AVRCP_FEATURE_MASK_BROWSING; 79 } 80 81 static void avrcp_controller_emit_notification_for_event_id(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id, avrcp_command_type_t ctype, const uint8_t * payload){ 82 switch (event_id){ 83 case AVRCP_NOTIFICATION_EVENT_PLAYBACK_POS_CHANGED:{ 84 uint32_t song_position = big_endian_read_32(payload, 0); 85 uint16_t offset = 0; 86 uint8_t event[10]; 87 event[offset++] = HCI_EVENT_AVRCP_META; 88 event[offset++] = sizeof(event) - 2; 89 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_PLAYBACK_POS_CHANGED; 90 little_endian_store_16(event, offset, avrcp_cid); 91 offset += 2; 92 event[offset++] = ctype; 93 little_endian_store_32(event, offset, song_position); 94 offset += 4; 95 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 96 break; 97 } 98 case AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED:{ 99 uint16_t offset = 0; 100 uint8_t event[7]; 101 event[offset++] = HCI_EVENT_AVRCP_META; 102 event[offset++] = sizeof(event) - 2; 103 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_PLAYBACK_STATUS_CHANGED; 104 little_endian_store_16(event, offset, avrcp_cid); 105 offset += 2; 106 event[offset++] = ctype; 107 event[offset++] = payload[0]; 108 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 109 break; 110 } 111 case AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED:{ 112 uint16_t offset = 0; 113 uint8_t event[6]; 114 event[offset++] = HCI_EVENT_AVRCP_META; 115 event[offset++] = sizeof(event) - 2; 116 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_TRACK_CHANGED; 117 little_endian_store_16(event, offset, avrcp_cid); 118 offset += 2; 119 event[offset++] = ctype; 120 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 121 break; 122 } 123 case AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED:{ 124 uint16_t offset = 0; 125 uint8_t event[6]; 126 event[offset++] = HCI_EVENT_AVRCP_META; 127 event[offset++] = sizeof(event) - 2; 128 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_NOW_PLAYING_CONTENT_CHANGED; 129 little_endian_store_16(event, offset, avrcp_cid); 130 offset += 2; 131 event[offset++] = ctype; 132 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 133 break; 134 } 135 case AVRCP_NOTIFICATION_EVENT_AVAILABLE_PLAYERS_CHANGED:{ 136 uint16_t offset = 0; 137 uint8_t event[6]; 138 event[offset++] = HCI_EVENT_AVRCP_META; 139 event[offset++] = sizeof(event) - 2; 140 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_AVAILABLE_PLAYERS_CHANGED; 141 little_endian_store_16(event, offset, avrcp_cid); 142 offset += 2; 143 event[offset++] = ctype; 144 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 145 break; 146 } 147 case AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED:{ 148 uint16_t offset = 0; 149 uint8_t event[7]; 150 event[offset++] = HCI_EVENT_AVRCP_META; 151 event[offset++] = sizeof(event) - 2; 152 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED; 153 little_endian_store_16(event, offset, avrcp_cid); 154 offset += 2; 155 event[offset++] = ctype; 156 event[offset++] = payload[0] & 0x7F; 157 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 158 break; 159 } 160 case AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED:{ 161 uint8_t event[8]; 162 uint16_t offset = 0; 163 uint16_t uuid = big_endian_read_16(payload, 0); 164 event[offset++] = HCI_EVENT_AVRCP_META; 165 event[offset++] = sizeof(event) - 2; 166 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_EVENT_UIDS_CHANGED; 167 little_endian_store_16(event, offset, avrcp_cid); 168 offset += 2; 169 event[offset++] = ctype; 170 little_endian_store_16(event, offset, uuid); 171 offset += 2; 172 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 173 break; 174 } 175 176 case AVRCP_NOTIFICATION_EVENT_TRACK_REACHED_END:{ 177 uint16_t offset = 0; 178 uint8_t event[6]; 179 event[offset++] = HCI_EVENT_AVRCP_META; 180 event[offset++] = sizeof(event) - 2; 181 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_EVENT_TRACK_REACHED_END; 182 little_endian_store_16(event, offset, avrcp_cid); 183 offset += 2; 184 event[offset++] = ctype; 185 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 186 break; 187 } 188 case AVRCP_NOTIFICATION_EVENT_TRACK_REACHED_START:{ 189 uint16_t offset = 0; 190 uint8_t event[6]; 191 event[offset++] = HCI_EVENT_AVRCP_META; 192 event[offset++] = sizeof(event) - 2; 193 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_EVENT_TRACK_REACHED_START; 194 little_endian_store_16(event, offset, avrcp_cid); 195 offset += 2; 196 event[offset++] = ctype; 197 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 198 break; 199 } 200 case AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED:{ 201 uint16_t offset = 0; 202 uint8_t event[7]; 203 event[offset++] = HCI_EVENT_AVRCP_META; 204 event[offset++] = sizeof(event) - 2; 205 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_EVENT_BATT_STATUS_CHANGED; 206 little_endian_store_16(event, offset, avrcp_cid); 207 offset += 2; 208 event[offset++] = ctype; 209 event[offset++] = payload[0]; 210 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 211 break; 212 } 213 214 case AVRCP_NOTIFICATION_EVENT_SYSTEM_STATUS_CHANGED:{ 215 uint16_t offset = 0; 216 uint8_t event[7]; 217 event[offset++] = HCI_EVENT_AVRCP_META; 218 event[offset++] = sizeof(event) - 2; 219 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_EVENT_SYSTEM_STATUS_CHANGED; 220 little_endian_store_16(event, offset, avrcp_cid); 221 offset += 2; 222 event[offset++] = ctype; 223 event[offset++] = payload[0]; 224 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 225 break; 226 } 227 228 case AVRCP_NOTIFICATION_EVENT_PLAYER_APPLICATION_SETTING_CHANGED: 229 default: 230 log_info("avrcp: not implemented"); 231 break; 232 } 233 } 234 235 static void avrcp_controller_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){ 236 btstack_assert(callback != NULL); 237 238 uint8_t event[8]; 239 int pos = 0; 240 event[pos++] = HCI_EVENT_AVRCP_META; 241 event[pos++] = sizeof(event) - 2; 242 event[pos++] = AVRCP_SUBEVENT_SHUFFLE_AND_REPEAT_MODE; 243 little_endian_store_16(event, pos, avrcp_cid); 244 pos += 2; 245 event[pos++] = ctype; 246 event[pos++] = repeat_mode; 247 event[pos++] = shuffle_mode; 248 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 249 } 250 251 static void avrcp_controller_emit_now_playing_info_event_done(btstack_packet_handler_t callback, uint16_t avrcp_cid, uint8_t ctype, uint8_t status){ 252 uint8_t event[7]; 253 int pos = 0; 254 event[pos++] = HCI_EVENT_AVRCP_META; 255 event[pos++] = sizeof(event) - 2; 256 event[pos++] = AVRCP_SUBEVENT_NOW_PLAYING_INFO_DONE; 257 little_endian_store_16(event, pos, avrcp_cid); 258 pos += 2; 259 event[pos++] = ctype; 260 event[pos++] = status; 261 // printf_hexdump(event, pos); 262 (*callback)(HCI_EVENT_PACKET, 0, event, pos); 263 } 264 265 static void avrcp_controller_emit_now_playing_info_event(btstack_packet_handler_t callback, uint16_t avrcp_cid, uint8_t ctype, avrcp_media_attribute_id_t attr_id, uint8_t * value, uint16_t value_len){ 266 uint8_t event[HCI_EVENT_BUFFER_SIZE]; 267 int pos = 0; 268 event[pos++] = HCI_EVENT_AVRCP_META; 269 // reserve one byte for subevent type and data len 270 int data_len_pos = pos; 271 pos++; 272 int subevent_type_pos = pos; 273 pos++; 274 little_endian_store_16(event, pos, avrcp_cid); 275 pos += 2; 276 event[pos++] = ctype; 277 278 switch (attr_id){ 279 case AVRCP_MEDIA_ATTR_TITLE: 280 event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_TITLE_INFO; 281 event[pos++] = value_len; 282 (void)memcpy(event + pos, value, value_len); 283 break; 284 case AVRCP_MEDIA_ATTR_ARTIST: 285 event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_ARTIST_INFO; 286 event[pos++] = value_len; 287 (void)memcpy(event + pos, value, value_len); 288 break; 289 case AVRCP_MEDIA_ATTR_ALBUM: 290 event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_ALBUM_INFO; 291 event[pos++] = value_len; 292 (void)memcpy(event + pos, value, value_len); 293 break; 294 case AVRCP_MEDIA_ATTR_GENRE: 295 event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_GENRE_INFO; 296 event[pos++] = value_len; 297 (void)memcpy(event + pos, value, value_len); 298 break; 299 case AVRCP_MEDIA_ATTR_SONG_LENGTH_MS: 300 event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_SONG_LENGTH_MS_INFO; 301 if (value){ 302 little_endian_store_32(event, pos, btstack_atoi((char *)value)); 303 } else { 304 little_endian_store_32(event, pos, 0); 305 } 306 pos += 4; 307 break; 308 case AVRCP_MEDIA_ATTR_TRACK: 309 event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_TRACK_INFO; 310 if (value){ 311 event[pos++] = btstack_atoi((char *)value); 312 } else { 313 event[pos++] = 0; 314 } 315 break; 316 case AVRCP_MEDIA_ATTR_TOTAL_NUM_ITEMS: 317 event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_TOTAL_TRACKS_INFO; 318 if (value){ 319 event[pos++] = btstack_atoi((char *)value); 320 } else { 321 event[pos++] = 0; 322 } 323 break; 324 default: 325 break; 326 } 327 event[data_len_pos] = pos - 2; 328 (*callback)(HCI_EVENT_PACKET, 0, event, pos); 329 } 330 331 static void avrcp_controller_emit_operation_status(btstack_packet_handler_t callback, uint8_t subevent, uint16_t avrcp_cid, uint8_t ctype, uint8_t operation_id){ 332 btstack_assert(callback != NULL); 333 334 uint8_t event[7]; 335 int pos = 0; 336 event[pos++] = HCI_EVENT_AVRCP_META; 337 event[pos++] = sizeof(event) - 2; 338 event[pos++] = subevent; 339 little_endian_store_16(event, pos, avrcp_cid); 340 pos += 2; 341 event[pos++] = ctype; 342 event[pos++] = operation_id; 343 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 344 } 345 346 static void avrcp_parser_reset(avrcp_connection_t * connection){ 347 connection->list_offset = 0; 348 connection->num_attributes = 0; 349 connection->num_parsed_attributes = 0; 350 connection->parser_attribute_header_pos = 0; 351 connection->num_received_fragments = 0; 352 connection->parser_state = AVRCP_PARSER_GET_ATTRIBUTE_HEADER; 353 } 354 355 static void avrcp_parser_process_byte(uint8_t byte, avrcp_connection_t * connection, avrcp_command_type_t ctype){ 356 uint16_t attribute_total_value_len; 357 uint32_t attribute_id; 358 // printf("avrcp_parser_process_byte: %02x, state %02x\n", byte, connection->parser_state); 359 switch(connection->parser_state){ 360 case AVRCP_PARSER_GET_ATTRIBUTE_HEADER: 361 connection->parser_attribute_header[connection->parser_attribute_header_pos++] = byte; 362 connection->list_offset++; 363 364 if (connection->parser_attribute_header_pos < AVRCP_ATTRIBUTE_HEADER_LEN) return; 365 366 attribute_total_value_len = big_endian_read_16(connection->parser_attribute_header, 6); 367 connection->attribute_value_len = btstack_min(attribute_total_value_len, AVRCP_MAX_ATTRIBUTTE_SIZE); 368 if (connection->attribute_value_len > 0){ 369 // get ready for attribute value 370 connection->parser_state = AVRCP_PARSER_GET_ATTRIBUTE_VALUE; 371 return; 372 } 373 374 // emit empty attribute 375 attribute_id = big_endian_read_32(connection->parser_attribute_header, 0); 376 avrcp_controller_emit_now_playing_info_event(avrcp_controller_context.avrcp_callback, connection->avrcp_cid, ctype, (avrcp_media_attribute_id_t) attribute_id, connection->attribute_value, connection->attribute_value_len); 377 378 // done, see below 379 break; 380 381 case AVRCP_PARSER_GET_ATTRIBUTE_VALUE: 382 connection->attribute_value[connection->attribute_value_offset++] = byte; 383 connection->list_offset++; 384 385 if (connection->attribute_value_offset < connection->attribute_value_len) return; 386 387 // emit (potentially partial) attribute 388 attribute_id = big_endian_read_32(connection->parser_attribute_header, 0); 389 avrcp_controller_emit_now_playing_info_event(avrcp_controller_context.avrcp_callback, connection->avrcp_cid, ctype, (avrcp_media_attribute_id_t) attribute_id, connection->attribute_value, connection->attribute_value_len); 390 391 attribute_total_value_len = big_endian_read_16(connection->parser_attribute_header, 6); 392 if (connection->attribute_value_offset < attribute_total_value_len){ 393 // ignore rest of attribute 394 connection->parser_state = AVRCP_PARSER_IGNORE_REST_OF_ATTRIBUTE_VALUE; 395 return; 396 } 397 398 // done, see below 399 break; 400 401 case AVRCP_PARSER_IGNORE_REST_OF_ATTRIBUTE_VALUE: 402 connection->attribute_value_offset++; 403 connection->list_offset++; 404 405 attribute_total_value_len = big_endian_read_16(connection->parser_attribute_header, 6); 406 if (connection->attribute_value_offset < attribute_total_value_len) return; 407 408 // done, see below 409 break; 410 411 default: 412 return; 413 } 414 415 // attribute fully read, check if more to come 416 if (connection->list_offset < connection->list_size){ 417 // more to come, reset parser 418 connection->parser_state = AVRCP_PARSER_GET_ATTRIBUTE_HEADER; 419 connection->parser_attribute_header_pos = 0; 420 connection->attribute_value_offset = 0; 421 } else { 422 // fully done 423 avrcp_parser_reset(connection); 424 avrcp_controller_emit_now_playing_info_event_done(avrcp_controller_context.avrcp_callback, connection->avrcp_cid, ctype, 0); 425 } 426 } 427 428 static void avrcp_controller_parse_and_emit_element_attrs(uint8_t * packet, uint16_t num_bytes_to_read, avrcp_connection_t * connection, avrcp_command_type_t ctype){ 429 int i; 430 for (i=0;i<num_bytes_to_read;i++){ 431 avrcp_parser_process_byte(packet[i], connection, ctype); 432 } 433 } 434 435 436 static int avrcp_send_cmd(avrcp_connection_t * connection, avrcp_packet_type_t packet_type){ 437 uint8_t command[AVRCP_CMD_BUFFER_SIZE]; 438 uint16_t pos = 0; 439 440 // non-fragmented: transport header (1) + PID (2) 441 // fragmented: transport header (1) + num packets (1) + PID (2) 442 443 // transport header : transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier) 444 command[pos++] = (connection->transaction_label << 4) | (packet_type << 2) | (AVRCP_COMMAND_FRAME << 1) | 0; 445 446 if (packet_type == AVRCP_START_PACKET){ 447 // num packets: (3 bytes overhead (PID, num packets) + command) / (MTU - transport header). 448 // to get number of packets using integer division, we subtract 1 from the data e.g. len = 5, packet size 5 => need 1 packet 449 command[pos++] = ((connection->cmd_operands_fragmented_len + 3 - 1) / (AVRCP_CMD_BUFFER_SIZE - 1)) + 1; 450 } 451 452 if ((packet_type == AVRCP_SINGLE_PACKET) || (packet_type == AVRCP_START_PACKET)){ 453 // Profile IDentifier (PID) 454 command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8; 455 command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF; 456 457 // command_type 458 command[pos++] = connection->command_type; 459 // subunit_type | subunit ID 460 command[pos++] = (connection->subunit_type << 3) | connection->subunit_id; 461 // opcode 462 command[pos++] = (uint8_t)connection->command_opcode; 463 } 464 465 if (packet_type == AVRCP_SINGLE_PACKET){ 466 // operands 467 (void)memcpy(command + pos, connection->cmd_operands, 468 connection->cmd_operands_length); 469 pos += connection->cmd_operands_length; 470 } else { 471 uint16_t bytes_free = AVRCP_CMD_BUFFER_SIZE - pos; 472 uint16_t bytes_to_store = connection->cmd_operands_fragmented_len-connection->cmd_operands_fragmented_pos; 473 uint16_t bytes_to_copy = btstack_min(bytes_to_store, bytes_free); 474 (void)memcpy(command + pos, 475 &connection->cmd_operands_fragmented_buffer[connection->cmd_operands_fragmented_pos], 476 bytes_to_copy); 477 pos += bytes_to_copy; 478 connection->cmd_operands_fragmented_pos += bytes_to_copy; 479 } 480 481 return l2cap_send(connection->l2cap_signaling_cid, command, pos); 482 } 483 484 static int avrcp_send_register_notification(avrcp_connection_t * connection, uint8_t event_id){ 485 uint8_t command[18]; 486 uint16_t pos = 0; 487 // transport header : transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier) 488 connection->transaction_label = avrcp_controller_get_next_transaction_label(); 489 command[pos++] = (connection->transaction_label << 4) | (AVRCP_SINGLE_PACKET << 2) | (AVRCP_COMMAND_FRAME << 1) | 0; 490 491 command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8; 492 command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF; 493 command[pos++] = AVRCP_CTYPE_NOTIFY; 494 command[pos++] = (AVRCP_SUBUNIT_TYPE_PANEL << 3) | AVRCP_SUBUNIT_ID; 495 command[pos++] = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 496 497 big_endian_store_24(command, pos, BT_SIG_COMPANY_ID); 498 pos += 3; 499 command[pos++] = AVRCP_PDU_ID_REGISTER_NOTIFICATION; 500 command[pos++] = 0; // reserved(upper 6) | packet_type -> 0 501 big_endian_store_16(command, pos, 5); // parameter length 502 pos += 2; 503 command[pos++] = event_id; 504 big_endian_store_32(command, pos, 1); // send notification on playback position every second, for other notifications it is ignored 505 pos += 4; 506 return l2cap_send(connection->l2cap_signaling_cid, command, pos); 507 } 508 509 static void avrcp_press_and_hold_timeout_handler(btstack_timer_source_t * timer){ 510 UNUSED(timer); 511 avrcp_connection_t * connection = (avrcp_connection_t*) btstack_run_loop_get_timer_context(timer); 512 btstack_run_loop_set_timer(&connection->press_and_hold_cmd_timer, 2000); // 2 seconds timeout 513 btstack_run_loop_add_timer(&connection->press_and_hold_cmd_timer); 514 connection->state = AVCTP_W2_SEND_PRESS_COMMAND; 515 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 516 } 517 518 static void avrcp_press_and_hold_timer_start(avrcp_connection_t * connection){ 519 btstack_run_loop_remove_timer(&connection->press_and_hold_cmd_timer); 520 btstack_run_loop_set_timer_handler(&connection->press_and_hold_cmd_timer, avrcp_press_and_hold_timeout_handler); 521 btstack_run_loop_set_timer_context(&connection->press_and_hold_cmd_timer, connection); 522 btstack_run_loop_set_timer(&connection->press_and_hold_cmd_timer, 2000); // 2 seconds timeout 523 btstack_run_loop_add_timer(&connection->press_and_hold_cmd_timer); 524 } 525 526 static void avrcp_press_and_hold_timer_stop(avrcp_connection_t * connection){ 527 connection->continuous_fast_forward_cmd = 0; 528 btstack_run_loop_remove_timer(&connection->press_and_hold_cmd_timer); 529 } 530 531 532 static uint8_t avrcp_controller_request_pass_through_release_control_cmd(avrcp_connection_t * connection){ 533 connection->state = AVCTP_W2_SEND_RELEASE_COMMAND; 534 if (connection->continuous_fast_forward_cmd){ 535 avrcp_press_and_hold_timer_stop(connection); 536 } 537 connection->cmd_operands[0] = 0x80 | connection->cmd_operands[0]; 538 connection->transaction_label = avrcp_controller_get_next_transaction_label(); 539 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 540 return ERROR_CODE_SUCCESS; 541 } 542 543 static inline uint8_t avrcp_controller_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){ 544 log_info("Send command %d", opid); 545 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid); 546 if (!connection){ 547 log_error("Could not find a connection. avrcp cid 0x%02x", avrcp_cid); 548 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 549 } 550 551 if (connection->state != AVCTP_CONNECTION_OPENED){ 552 log_error("Connection in wrong state %d, expected %d. avrcp cid 0x%02x", connection->state, AVCTP_CONNECTION_OPENED, avrcp_cid); 553 return ERROR_CODE_COMMAND_DISALLOWED; 554 } 555 connection->state = AVCTP_W2_SEND_PRESS_COMMAND; 556 connection->command_opcode = AVRCP_CMD_OPCODE_PASS_THROUGH; 557 connection->command_type = AVRCP_CTYPE_CONTROL; 558 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 559 connection->subunit_id = AVRCP_SUBUNIT_ID; 560 connection->cmd_operands_length = 0; 561 562 connection->continuous_fast_forward_cmd = continuous_fast_forward_cmd; 563 connection->cmd_operands_length = 2; 564 connection->cmd_operands[0] = opid; 565 if (playback_speed > 0){ 566 connection->cmd_operands[2] = playback_speed; 567 connection->cmd_operands_length++; 568 } 569 connection->cmd_operands[1] = connection->cmd_operands_length - 2; 570 571 if (connection->continuous_fast_forward_cmd){ 572 avrcp_press_and_hold_timer_start(connection); 573 } 574 575 connection->transaction_label = avrcp_controller_get_next_transaction_label(); 576 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 577 return ERROR_CODE_SUCCESS; 578 } 579 580 static uint8_t request_single_pass_through_press_control_cmd(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint16_t playback_speed){ 581 return avrcp_controller_request_pass_through_press_control_cmd(avrcp_cid, opid, playback_speed, 0); 582 } 583 584 static uint8_t request_continuous_pass_through_press_control_cmd(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint16_t playback_speed){ 585 return avrcp_controller_request_pass_through_press_control_cmd(avrcp_cid, opid, playback_speed, 1); 586 } 587 588 static int avrcp_controller_register_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t event_id){ 589 if (connection->notifications_to_deregister & (1 << event_id)) return 0; 590 if (connection->notifications_enabled & (1 << event_id)) return 0; 591 if (connection->notifications_to_register & (1 << event_id)) return 0; 592 connection->notifications_to_register |= (1 << event_id); 593 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 594 return 1; 595 } 596 597 static uint8_t avrcp_controller_request_abort_continuation(avrcp_connection_t * connection){ 598 connection->state = AVCTP_W2_SEND_COMMAND; 599 connection->transaction_label = avrcp_controller_get_next_transaction_label(); 600 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 601 connection->command_type = AVRCP_CTYPE_CONTROL; 602 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 603 connection->subunit_id = AVRCP_SUBUNIT_ID; 604 int pos = 0; 605 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 606 pos += 3; 607 connection->cmd_operands[pos++] = AVRCP_PDU_ID_REQUEST_ABORT_CONTINUING_RESPONSE; // PDU ID 608 connection->cmd_operands[pos++] = 0; 609 // Parameter Length 610 connection->cmd_operands_length = 8; 611 big_endian_store_16(connection->cmd_operands, pos, 1); 612 pos += 2; 613 connection->cmd_operands[pos++] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES; 614 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 615 return ERROR_CODE_SUCCESS; 616 } 617 618 619 static uint8_t avrcp_controller_request_continue_response(avrcp_connection_t * connection){ 620 connection->state = AVCTP_W2_SEND_COMMAND; 621 connection->transaction_label = avrcp_controller_get_next_transaction_label(); 622 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 623 connection->command_type = AVRCP_CTYPE_CONTROL; 624 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 625 connection->subunit_id = AVRCP_SUBUNIT_ID; 626 int pos = 0; 627 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 628 pos += 3; 629 connection->cmd_operands[pos++] = AVRCP_PDU_ID_REQUEST_CONTINUING_RESPONSE; // PDU ID 630 connection->cmd_operands[pos++] = 0; 631 // Parameter Length 632 connection->cmd_operands_length = 8; 633 big_endian_store_16(connection->cmd_operands, pos, 1); 634 pos += 2; 635 connection->cmd_operands[pos++] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES; 636 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 637 return ERROR_CODE_SUCCESS; 638 } 639 640 static void avrcp_controller_handle_notification(avrcp_connection_t * connection, avrcp_command_type_t ctype, uint8_t * payload){ 641 uint16_t pos = 0; 642 avrcp_notification_event_id_t event_id = (avrcp_notification_event_id_t) payload[pos++]; 643 uint16_t event_mask = (1 << event_id); 644 uint16_t reset_event_mask = ~event_mask; 645 switch (ctype){ 646 case AVRCP_CTYPE_RESPONSE_INTERIM: 647 // register as enabled 648 connection->notifications_enabled |= event_mask; 649 break; 650 case AVRCP_CTYPE_RESPONSE_CHANGED_STABLE: 651 // received change, event is considered deregistered 652 // we are re-enabling it automatically, if it is not 653 // explicitly disabled 654 connection->notifications_enabled &= reset_event_mask; 655 if (! (connection->notifications_to_deregister & event_mask)){ 656 avrcp_controller_register_notification(connection, event_id); 657 } else { 658 connection->notifications_to_deregister &= reset_event_mask; 659 } 660 break; 661 default: 662 connection->notifications_to_register &= reset_event_mask; 663 connection->notifications_enabled &= reset_event_mask; 664 connection->notifications_to_deregister &= reset_event_mask; 665 break; 666 } 667 668 avrcp_controller_emit_notification_for_event_id(connection->avrcp_cid, event_id, ctype, payload+pos); 669 } 670 671 static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connection_t * connection, uint8_t *packet, uint16_t size){ 672 if (size < 6u) return; 673 674 uint16_t pos = 3; 675 uint8_t pdu_id; 676 677 avrcp_frame_type_t frame_type = (avrcp_frame_type_t)((packet[0] >> 1) & 0x01); 678 if (frame_type != AVRCP_RESPONSE_FRAME) return; 679 680 avrcp_packet_type_t packet_type = (avrcp_packet_type_t)((packet[0] >> 2) & 0x03); 681 switch (packet_type){ 682 case AVRCP_SINGLE_PACKET: 683 break; 684 default: 685 log_info("Fragmentation is not supported"); 686 return; 687 } 688 689 avrcp_command_type_t ctype = (avrcp_command_type_t) packet[pos++]; 690 691 #ifdef ENABLE_LOG_INFO 692 uint8_t byte_value = packet[pos]; 693 avrcp_subunit_type_t subunit_type = (avrcp_subunit_type_t) (byte_value >> 3); 694 avrcp_subunit_type_t subunit_id = (avrcp_subunit_type_t) (byte_value & 0x07); 695 #endif 696 pos++; 697 698 uint8_t opcode = packet[pos++]; 699 uint16_t param_length; 700 701 switch (opcode){ 702 case AVRCP_CMD_OPCODE_SUBUNIT_INFO:{ 703 if (connection->state != AVCTP_W2_RECEIVE_RESPONSE) return; 704 connection->state = AVCTP_CONNECTION_OPENED; 705 706 #ifdef ENABLE_LOG_INFO 707 // page, extention code (1) 708 pos++; 709 uint8_t unit_type = packet[pos] >> 3; 710 uint8_t max_subunit_ID = packet[pos] & 0x07; 711 log_info("SUBUNIT INFO response: ctype 0x%02x (0C), subunit_type 0x%02x (1F), subunit_id 0x%02x (07), opcode 0x%02x (30), unit_type 0x%02x, max_subunit_ID %d", ctype, subunit_type, subunit_id, opcode, unit_type, max_subunit_ID); 712 #endif 713 break; 714 } 715 case AVRCP_CMD_OPCODE_UNIT_INFO:{ 716 if (connection->state != AVCTP_W2_RECEIVE_RESPONSE) return; 717 connection->state = AVCTP_CONNECTION_OPENED; 718 719 #ifdef ENABLE_LOG_INFO 720 // byte value 7 (1) 721 pos++; 722 uint8_t unit_type = packet[pos] >> 3; 723 uint8_t unit = packet[pos] & 0x07; 724 pos++; 725 uint32_t company_id = big_endian_read_24(packet, pos); 726 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%06" PRIx32, 727 ctype, subunit_type, subunit_id, opcode, unit_type, unit, company_id); 728 #endif 729 break; 730 } 731 case AVRCP_CMD_OPCODE_VENDOR_DEPENDENT: 732 // Company ID (3) 733 pos += 3; 734 pdu_id = packet[pos++]; 735 // packet type (1) 736 pos++; 737 param_length = big_endian_read_16(packet, pos); 738 pos += 2; 739 log_info("operands length %d, remaining size %d", param_length, size - pos); 740 741 if ((size - pos) < param_length) { 742 log_error("Wrong packet size %d < %d", size - pos, param_length); 743 return; 744 }; 745 746 // handle asynchronous notifications, without changing state 747 if (pdu_id == AVRCP_PDU_ID_REGISTER_NOTIFICATION){ 748 avrcp_controller_handle_notification(connection, ctype, packet+pos); 749 break; 750 } 751 752 if (connection->state != AVCTP_W2_RECEIVE_RESPONSE){ 753 log_info("AVRCP_CMD_OPCODE_VENDOR_DEPENDENT state %d", connection->state); 754 return; 755 } 756 connection->state = AVCTP_CONNECTION_OPENED; 757 758 log_info("VENDOR DEPENDENT response: pdu id 0x%02x, param_length %d, status %s", pdu_id, param_length, avrcp_ctype2str(ctype)); 759 switch (pdu_id){ 760 case AVRCP_PDU_ID_GET_CURRENT_PLAYER_APPLICATION_SETTING_VALUE:{ 761 uint8_t num_attributes = packet[pos++]; 762 int i; 763 avrcp_repeat_mode_t repeat_mode = AVRCP_REPEAT_MODE_INVALID; 764 avrcp_shuffle_mode_t shuffle_mode = AVRCP_SHUFFLE_MODE_INVALID; 765 for (i = 0; i < num_attributes; i++){ 766 uint8_t attribute_id = packet[pos++]; 767 uint8_t value = packet[pos++]; 768 switch (attribute_id){ 769 case 0x02: 770 repeat_mode = (avrcp_repeat_mode_t) value; 771 break; 772 case 0x03: 773 shuffle_mode = (avrcp_shuffle_mode_t) value; 774 break; 775 default: 776 break; 777 } 778 } 779 avrcp_controller_emit_repeat_and_shuffle_mode(avrcp_controller_context.avrcp_callback, connection->avrcp_cid, ctype, repeat_mode, shuffle_mode); 780 break; 781 } 782 783 case AVRCP_PDU_ID_SET_PLAYER_APPLICATION_SETTING_VALUE:{ 784 uint16_t offset = 0; 785 uint8_t event[6]; 786 event[offset++] = HCI_EVENT_AVRCP_META; 787 event[offset++] = sizeof(event) - 2; 788 event[offset++] = AVRCP_SUBEVENT_PLAYER_APPLICATION_VALUE_RESPONSE; 789 little_endian_store_16(event, offset, connection->avrcp_cid); 790 offset += 2; 791 event[offset++] = ctype; 792 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 793 break; 794 } 795 796 case AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME:{ 797 uint16_t offset = 0; 798 uint8_t event[7]; 799 event[offset++] = HCI_EVENT_AVRCP_META; 800 event[offset++] = sizeof(event) - 2; 801 event[offset++] = AVRCP_SUBEVENT_SET_ABSOLUTE_VOLUME_RESPONSE; 802 little_endian_store_16(event, offset, connection->avrcp_cid); 803 offset += 2; 804 event[offset++] = ctype; 805 event[offset++] = packet[pos++]; 806 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 807 break; 808 } 809 810 case AVRCP_PDU_ID_GET_CAPABILITIES:{ 811 avrcp_capability_id_t capability_id = (avrcp_capability_id_t) packet[pos++]; 812 uint8_t capability_count = packet[pos++]; 813 uint16_t i; 814 uint16_t offset = 0; 815 uint8_t event[10]; 816 817 switch (capability_id){ 818 819 case AVRCP_CAPABILITY_ID_COMPANY: 820 for (i = 0; i < capability_count; i++){ 821 uint32_t company_id = big_endian_read_24(packet, pos); 822 pos += 3; 823 log_info(" 0x%06" PRIx32 ", ", company_id); 824 825 offset = 0; 826 event[offset++] = HCI_EVENT_AVRCP_META; 827 event[offset++] = sizeof(event) - 2; 828 event[offset++] = AVRCP_SUBEVENT_GET_CAPABILITY_COMPANY_ID; 829 little_endian_store_16(event, offset, connection->avrcp_cid); 830 offset += 2; 831 event[offset++] = ctype; 832 event[offset++] = 0; 833 little_endian_store_24(event, offset, company_id); 834 offset += 3; 835 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, offset); 836 break; 837 } 838 839 offset = 0; 840 event[offset++] = HCI_EVENT_AVRCP_META; 841 event[offset++] = sizeof(event) - 2; 842 event[offset++] = AVRCP_SUBEVENT_GET_CAPABILITY_COMPANY_ID_DONE; 843 little_endian_store_16(event, offset, connection->avrcp_cid); 844 offset += 2; 845 event[offset++] = ctype; 846 event[offset++] = 0; 847 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, offset); 848 break; 849 850 case AVRCP_CAPABILITY_ID_EVENT: 851 for (i = 0; i < capability_count; i++){ 852 uint8_t event_id = packet[pos++]; 853 log_info(" 0x%02x %s", event_id, avrcp_event2str(event_id)); 854 855 offset = 0; 856 event[offset++] = HCI_EVENT_AVRCP_META; 857 event[offset++] = sizeof(event) - 2; 858 event[offset++] = AVRCP_SUBEVENT_GET_CAPABILITY_EVENT_ID; 859 little_endian_store_16(event, offset, connection->avrcp_cid); 860 offset += 2; 861 event[offset++] = ctype; 862 event[offset++] = 0; 863 event[offset++] = event_id; 864 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, offset); 865 } 866 867 offset = 0; 868 event[offset++] = HCI_EVENT_AVRCP_META; 869 event[offset++] = sizeof(event) - 2; 870 event[offset++] = AVRCP_SUBEVENT_GET_CAPABILITY_EVENT_ID_DONE; 871 little_endian_store_16(event, offset, connection->avrcp_cid); 872 offset += 2; 873 event[offset++] = ctype; 874 event[offset++] = 0; 875 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 876 break; 877 878 default: 879 btstack_assert(false); 880 break; 881 } 882 break; 883 } 884 885 case AVRCP_PDU_ID_GET_PLAY_STATUS:{ 886 uint32_t song_length = big_endian_read_32(packet, pos); 887 pos += 4; 888 uint32_t song_position = big_endian_read_32(packet, pos); 889 pos += 4; 890 uint8_t play_status = packet[pos]; 891 892 uint8_t event[15]; 893 int offset = 0; 894 event[offset++] = HCI_EVENT_AVRCP_META; 895 event[offset++] = sizeof(event) - 2; 896 event[offset++] = AVRCP_SUBEVENT_PLAY_STATUS; 897 little_endian_store_16(event, offset, connection->avrcp_cid); 898 offset += 2; 899 event[offset++] = ctype; 900 little_endian_store_32(event, offset, song_length); 901 offset += 4; 902 little_endian_store_32(event, offset, song_position); 903 offset += 4; 904 event[offset++] = play_status; 905 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 906 break; 907 } 908 909 case AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES:{ 910 switch (packet_type){ 911 case AVRCP_START_PACKET: 912 case AVRCP_SINGLE_PACKET: 913 avrcp_parser_reset(connection); 914 connection->list_size = param_length; 915 connection->num_attributes = packet[pos++]; 916 917 avrcp_controller_parse_and_emit_element_attrs(packet+pos, size-pos, connection, ctype); 918 919 if (packet_type == AVRCP_START_PACKET){ 920 avrcp_controller_request_continue_response(connection); 921 } 922 break; 923 case AVRCP_CONTINUE_PACKET: 924 case AVRCP_END_PACKET: 925 connection->num_received_fragments++; 926 if (connection->num_received_fragments < connection->max_num_fragments){ 927 avrcp_controller_parse_and_emit_element_attrs(packet+pos, size-pos, connection, ctype); 928 if (packet_type == AVRCP_CONTINUE_PACKET){ 929 avrcp_controller_request_continue_response(connection); 930 } 931 } else { 932 avrcp_controller_request_abort_continuation(connection); 933 avrcp_controller_emit_now_playing_info_event_done(avrcp_controller_context.avrcp_callback, connection->avrcp_cid, ctype, 1); 934 avrcp_parser_reset(connection); 935 } 936 break; 937 default: 938 // TODO check 939 btstack_assert(false); 940 break; 941 } 942 } 943 default: 944 break; 945 } 946 break; 947 case AVRCP_CMD_OPCODE_PASS_THROUGH:{ 948 uint8_t operation_id = packet[pos++]; 949 switch (connection->state){ 950 case AVCTP_W2_RECEIVE_PRESS_RESPONSE: 951 if (connection->continuous_fast_forward_cmd){ 952 connection->state = AVCTP_W4_STOP; 953 } else { 954 connection->state = AVCTP_W2_SEND_RELEASE_COMMAND; 955 } 956 break; 957 case AVCTP_W2_RECEIVE_RESPONSE: 958 connection->state = AVCTP_CONNECTION_OPENED; 959 break; 960 default: 961 break; 962 } 963 if (connection->state == AVCTP_W4_STOP){ 964 avrcp_controller_emit_operation_status(avrcp_controller_context.avrcp_callback, AVRCP_SUBEVENT_OPERATION_START, connection->avrcp_cid, ctype, operation_id); 965 } 966 if (connection->state == AVCTP_CONNECTION_OPENED) { 967 // RELEASE response 968 operation_id = operation_id & 0x7F; 969 avrcp_controller_emit_operation_status(avrcp_controller_context.avrcp_callback, AVRCP_SUBEVENT_OPERATION_COMPLETE, connection->avrcp_cid, ctype, operation_id); 970 } 971 if (connection->state == AVCTP_W2_SEND_RELEASE_COMMAND){ 972 // PRESS response 973 avrcp_controller_request_pass_through_release_control_cmd(connection); 974 } 975 break; 976 } 977 default: 978 break; 979 } 980 981 // trigger pending notification reqistrations 982 if ((connection->state == AVCTP_CONNECTION_OPENED) && connection->notifications_to_register){ 983 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 984 } 985 } 986 987 static void avrcp_controller_handle_can_send_now(avrcp_connection_t * connection){ 988 switch (connection->state){ 989 case AVCTP_W2_SEND_PRESS_COMMAND: 990 connection->state = AVCTP_W2_RECEIVE_PRESS_RESPONSE; 991 avrcp_send_cmd(connection, AVRCP_SINGLE_PACKET); 992 return; 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, AVRCP_SINGLE_PACKET); 997 return; 998 case AVCTP_W2_SEND_FRAGMENTED_COMMAND: 999 if (connection->cmd_operands_fragmented_pos == 0){ 1000 avrcp_send_cmd(connection, AVRCP_START_PACKET); 1001 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1002 } else { 1003 if ((connection->cmd_operands_fragmented_len - connection->cmd_operands_fragmented_pos) > avrcp_get_max_payload_size_for_packet_type(AVRCP_CONTINUE_PACKET)){ 1004 avrcp_send_cmd(connection, AVRCP_CONTINUE_PACKET); 1005 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1006 } else { 1007 connection->state = AVCTP_W2_RECEIVE_RESPONSE; 1008 avrcp_send_cmd(connection, AVRCP_END_PACKET); 1009 } 1010 } 1011 return; 1012 default: 1013 break; 1014 } 1015 // send register notification if queued 1016 if (connection->notifications_to_register != 0){ 1017 uint8_t event_id; 1018 for (event_id = 1; event_id <= AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED; event_id++){ 1019 if (connection->notifications_to_register & (1<<event_id)){ 1020 connection->notifications_to_register &= ~ (1 << event_id); 1021 avrcp_send_register_notification(connection, event_id); 1022 return; 1023 } 1024 } 1025 } 1026 } 1027 1028 static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 1029 avrcp_connection_t * connection; 1030 1031 switch (packet_type) { 1032 case L2CAP_DATA_PACKET: 1033 connection = avrcp_get_connection_for_l2cap_signaling_cid_for_role(AVRCP_CONTROLLER, channel); 1034 avrcp_handle_l2cap_data_packet_for_signaling_connection(connection, packet, size); 1035 break; 1036 1037 case HCI_EVENT_PACKET: 1038 switch (hci_event_packet_get_type(packet)){ 1039 case L2CAP_EVENT_CAN_SEND_NOW: 1040 connection = avrcp_get_connection_for_l2cap_signaling_cid_for_role(AVRCP_CONTROLLER, channel); 1041 avrcp_controller_handle_can_send_now(connection); 1042 break; 1043 default: 1044 break; 1045 } 1046 default: 1047 break; 1048 } 1049 } 1050 1051 void avrcp_controller_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint16_t supported_features, const char * service_name, const char * service_provider_name){ 1052 avrcp_create_sdp_record(1, service, service_record_handle, avrcp_controller_supports_browsing(supported_features), supported_features, service_name, service_provider_name); 1053 } 1054 1055 void avrcp_controller_init(void){ 1056 avrcp_controller_context.role = AVRCP_CONTROLLER; 1057 avrcp_controller_context.packet_handler = avrcp_controller_packet_handler; 1058 avrcp_register_controller_packet_handler(&avrcp_controller_packet_handler); 1059 } 1060 1061 void avrcp_controller_register_packet_handler(btstack_packet_handler_t callback){ 1062 btstack_assert(callback != NULL); 1063 avrcp_controller_context.avrcp_callback = callback; 1064 } 1065 1066 1067 uint8_t avrcp_controller_play(uint16_t avrcp_cid){ 1068 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PLAY, 0); 1069 } 1070 1071 uint8_t avrcp_controller_stop(uint16_t avrcp_cid){ 1072 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_STOP, 0); 1073 } 1074 1075 uint8_t avrcp_controller_pause(uint16_t avrcp_cid){ 1076 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PAUSE, 0); 1077 } 1078 1079 uint8_t avrcp_controller_forward(uint16_t avrcp_cid){ 1080 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FORWARD, 0); 1081 } 1082 1083 uint8_t avrcp_controller_backward(uint16_t avrcp_cid){ 1084 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_BACKWARD, 0); 1085 } 1086 1087 uint8_t avrcp_controller_volume_up(uint16_t avrcp_cid){ 1088 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_UP, 0); 1089 } 1090 1091 uint8_t avrcp_controller_volume_down(uint16_t avrcp_cid){ 1092 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_DOWN, 0); 1093 } 1094 1095 uint8_t avrcp_controller_mute(uint16_t avrcp_cid){ 1096 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_MUTE, 0); 1097 } 1098 1099 uint8_t avrcp_controller_skip(uint16_t avrcp_cid){ 1100 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_SKIP, 0); 1101 } 1102 1103 uint8_t avrcp_controller_fast_forward(uint16_t avrcp_cid){ 1104 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FAST_FORWARD, 0); 1105 } 1106 1107 uint8_t avrcp_controller_rewind(uint16_t avrcp_cid){ 1108 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_REWIND, 0); 1109 } 1110 1111 /* start continuous cmds */ 1112 1113 uint8_t avrcp_controller_press_and_hold_play(uint16_t avrcp_cid){ 1114 return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PLAY, 0); 1115 } 1116 uint8_t avrcp_controller_press_and_hold_stop(uint16_t avrcp_cid){ 1117 return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_STOP, 0); 1118 } 1119 uint8_t avrcp_controller_press_and_hold_pause(uint16_t avrcp_cid){ 1120 return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PAUSE, 0); 1121 } 1122 uint8_t avrcp_controller_press_and_hold_forward(uint16_t avrcp_cid){ 1123 return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FORWARD, 0); 1124 } 1125 uint8_t avrcp_controller_press_and_hold_backward(uint16_t avrcp_cid){ 1126 return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_BACKWARD, 0); 1127 } 1128 uint8_t avrcp_controller_press_and_hold_fast_forward(uint16_t avrcp_cid){ 1129 return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FAST_FORWARD, 0); 1130 } 1131 uint8_t avrcp_controller_press_and_hold_rewind(uint16_t avrcp_cid){ 1132 return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_REWIND, 0); 1133 } 1134 uint8_t avrcp_controller_press_and_hold_volume_up(uint16_t avrcp_cid){ 1135 return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_UP, 0); 1136 } 1137 uint8_t avrcp_controller_press_and_hold_volume_down(uint16_t avrcp_cid){ 1138 return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_DOWN, 0); 1139 } 1140 uint8_t avrcp_controller_press_and_hold_mute(uint16_t avrcp_cid){ 1141 return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_MUTE, 0); 1142 } 1143 1144 /* stop continuous cmds */ 1145 uint8_t avrcp_controller_release_press_and_hold_cmd(uint16_t avrcp_cid){ 1146 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid); 1147 if (!connection){ 1148 log_error("avrcp_stop_play: could not find a connection."); 1149 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1150 } 1151 if (connection->state != AVCTP_W4_STOP) return ERROR_CODE_COMMAND_DISALLOWED; 1152 return avrcp_controller_request_pass_through_release_control_cmd(connection); 1153 } 1154 1155 uint8_t avrcp_controller_enable_notification(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id){ 1156 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid); 1157 if (!connection){ 1158 log_error("avrcp_get_play_status: could not find a connection."); 1159 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1160 } 1161 avrcp_controller_register_notification(connection, event_id); 1162 return ERROR_CODE_SUCCESS; 1163 } 1164 1165 uint8_t avrcp_controller_disable_notification(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id){ 1166 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid); 1167 if (!connection){ 1168 log_error("avrcp_get_play_status: could not find a connection."); 1169 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1170 } 1171 connection->notifications_to_deregister |= (1 << event_id); 1172 return ERROR_CODE_SUCCESS; 1173 } 1174 1175 uint8_t avrcp_controller_unit_info(uint16_t avrcp_cid){ 1176 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid); 1177 if (!connection){ 1178 log_error("avrcp_unit_info: could not find a connection."); 1179 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1180 } 1181 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1182 connection->state = AVCTP_W2_SEND_COMMAND; 1183 1184 connection->transaction_label = avrcp_controller_get_next_transaction_label(); 1185 connection->command_opcode = AVRCP_CMD_OPCODE_UNIT_INFO; 1186 connection->command_type = AVRCP_CTYPE_STATUS; 1187 connection->subunit_type = AVRCP_SUBUNIT_TYPE_UNIT; //vendor unique 1188 connection->subunit_id = AVRCP_SUBUNIT_ID_IGNORE; 1189 memset(connection->cmd_operands, 0xFF, connection->cmd_operands_length); 1190 connection->cmd_operands_length = 5; 1191 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1192 return ERROR_CODE_SUCCESS; 1193 } 1194 1195 uint8_t avrcp_controller_subunit_info(uint16_t avrcp_cid){ 1196 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid); 1197 if (!connection){ 1198 log_error("avrcp_unit_info: could not find a connection."); 1199 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1200 } 1201 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1202 connection->state = AVCTP_W2_SEND_COMMAND; 1203 1204 connection->transaction_label = avrcp_controller_get_next_transaction_label(); 1205 connection->command_opcode = AVRCP_CMD_OPCODE_SUBUNIT_INFO; 1206 connection->command_type = AVRCP_CTYPE_STATUS; 1207 connection->subunit_type = AVRCP_SUBUNIT_TYPE_UNIT; //vendor unique 1208 connection->subunit_id = AVRCP_SUBUNIT_ID_IGNORE; 1209 memset(connection->cmd_operands, 0xFF, connection->cmd_operands_length); 1210 connection->cmd_operands[0] = 7; // page: 0, extention_code: 7 1211 connection->cmd_operands_length = 5; 1212 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1213 return ERROR_CODE_SUCCESS; 1214 } 1215 1216 static uint8_t avrcp_controller_get_capabilities(uint16_t avrcp_cid, uint8_t capability_id){ 1217 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid); 1218 if (!connection){ 1219 log_error("avrcp_get_capabilities: could not find a connection."); 1220 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1221 } 1222 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1223 connection->state = AVCTP_W2_SEND_COMMAND; 1224 1225 connection->transaction_label = avrcp_controller_get_next_transaction_label(); 1226 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1227 connection->command_type = AVRCP_CTYPE_STATUS; 1228 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1229 connection->subunit_id = AVRCP_SUBUNIT_ID; 1230 big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID); 1231 connection->cmd_operands[3] = AVRCP_PDU_ID_GET_CAPABILITIES; // PDU ID 1232 connection->cmd_operands[4] = 0; 1233 big_endian_store_16(connection->cmd_operands, 5, 1); // parameter length 1234 connection->cmd_operands[7] = capability_id; // capability ID 1235 connection->cmd_operands_length = 8; 1236 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1237 return ERROR_CODE_SUCCESS; 1238 } 1239 1240 uint8_t avrcp_controller_get_supported_company_ids(uint16_t avrcp_cid){ 1241 return avrcp_controller_get_capabilities(avrcp_cid, AVRCP_CAPABILITY_ID_COMPANY); 1242 } 1243 1244 uint8_t avrcp_controller_get_supported_events(uint16_t avrcp_cid){ 1245 return avrcp_controller_get_capabilities(avrcp_cid, AVRCP_CAPABILITY_ID_EVENT); 1246 } 1247 1248 uint8_t avrcp_controller_get_play_status(uint16_t avrcp_cid){ 1249 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid); 1250 if (!connection){ 1251 log_error("avrcp_get_play_status: could not find a connection."); 1252 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1253 } 1254 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1255 connection->state = AVCTP_W2_SEND_COMMAND; 1256 connection->transaction_label = avrcp_controller_get_next_transaction_label(); 1257 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1258 connection->command_type = AVRCP_CTYPE_STATUS; 1259 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1260 connection->subunit_id = AVRCP_SUBUNIT_ID; 1261 big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID); 1262 connection->cmd_operands[3] = AVRCP_PDU_ID_GET_PLAY_STATUS; 1263 connection->cmd_operands[4] = 0; // reserved(upper 6) | packet_type -> 0 1264 big_endian_store_16(connection->cmd_operands, 5, 0); // parameter length 1265 connection->cmd_operands_length = 7; 1266 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1267 return ERROR_CODE_SUCCESS; 1268 } 1269 1270 uint8_t avrcp_controller_set_addressed_player(uint16_t avrcp_cid, uint16_t addressed_player_id){ 1271 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid); 1272 if (!connection){ 1273 log_error("avrcp_get_capabilities: could not find a connection."); 1274 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1275 } 1276 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1277 connection->state = AVCTP_W2_SEND_COMMAND; 1278 1279 connection->transaction_label = avrcp_controller_get_next_transaction_label(); 1280 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1281 connection->command_type = AVRCP_CTYPE_CONTROL; 1282 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1283 connection->subunit_id = AVRCP_SUBUNIT_ID; 1284 int pos = 0; 1285 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 1286 pos += 3; 1287 connection->cmd_operands[pos++] = AVRCP_PDU_ID_SET_ADDRESSED_PLAYER; // PDU ID 1288 connection->cmd_operands[pos++] = 0; 1289 1290 // Parameter Length 1291 big_endian_store_16(connection->cmd_operands, pos, 2); 1292 pos += 2; 1293 1294 big_endian_store_16(connection->cmd_operands, pos, addressed_player_id); 1295 pos += 2; 1296 1297 connection->cmd_operands_length = pos; 1298 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1299 return ERROR_CODE_SUCCESS; 1300 } 1301 1302 uint8_t avrcp_controller_get_now_playing_info(uint16_t avrcp_cid){ 1303 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid); 1304 if (!connection){ 1305 log_error("avrcp_get_capabilities: could not find a connection."); 1306 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1307 } 1308 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1309 connection->state = AVCTP_W2_SEND_COMMAND; 1310 1311 connection->transaction_label = avrcp_controller_get_next_transaction_label(); 1312 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1313 connection->command_type = AVRCP_CTYPE_STATUS; 1314 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1315 connection->subunit_id = AVRCP_SUBUNIT_ID; 1316 int pos = 0; 1317 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 1318 pos += 3; 1319 connection->cmd_operands[pos++] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES; // PDU ID 1320 connection->cmd_operands[pos++] = 0; 1321 1322 // Parameter Length 1323 big_endian_store_16(connection->cmd_operands, pos, 9); 1324 pos += 2; 1325 1326 // write 8 bytes value 1327 memset(connection->cmd_operands + pos, 0, 8); // identifier: PLAYING 1328 pos += 8; 1329 1330 connection->cmd_operands[pos++] = 0; // attribute count, if 0 get all attributes 1331 // every attribute is 4 bytes long 1332 1333 connection->cmd_operands_length = pos; 1334 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1335 return ERROR_CODE_SUCCESS; 1336 } 1337 1338 uint8_t avrcp_controller_set_absolute_volume(uint16_t avrcp_cid, uint8_t volume){ 1339 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid); 1340 if (!connection){ 1341 log_error("avrcp_get_capabilities: could not find a connection."); 1342 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1343 } 1344 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1345 connection->state = AVCTP_W2_SEND_COMMAND; 1346 1347 connection->transaction_label = avrcp_controller_get_next_transaction_label(); 1348 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1349 connection->command_type = AVRCP_CTYPE_CONTROL; 1350 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1351 connection->subunit_id = AVRCP_SUBUNIT_ID; 1352 int pos = 0; 1353 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 1354 pos += 3; 1355 connection->cmd_operands[pos++] = AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME; // PDU ID 1356 connection->cmd_operands[pos++] = 0; 1357 1358 // Parameter Length 1359 big_endian_store_16(connection->cmd_operands, pos, 1); 1360 pos += 2; 1361 connection->cmd_operands[pos++] = volume; 1362 1363 connection->cmd_operands_length = pos; 1364 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1365 return ERROR_CODE_SUCCESS; 1366 } 1367 1368 uint8_t avrcp_controller_query_shuffle_and_repeat_modes(uint16_t avrcp_cid){ 1369 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid); 1370 if (!connection){ 1371 log_error("avrcp_get_capabilities: could not find a connection."); 1372 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1373 } 1374 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1375 connection->state = AVCTP_W2_SEND_COMMAND; 1376 1377 connection->transaction_label = avrcp_controller_get_next_transaction_label(); 1378 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1379 connection->command_type = AVRCP_CTYPE_STATUS; 1380 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1381 connection->subunit_id = AVRCP_SUBUNIT_ID; 1382 big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID); 1383 connection->cmd_operands[3] = AVRCP_PDU_ID_GET_CURRENT_PLAYER_APPLICATION_SETTING_VALUE; // PDU ID 1384 connection->cmd_operands[4] = 0; 1385 big_endian_store_16(connection->cmd_operands, 5, 5); // parameter length 1386 connection->cmd_operands[7] = 4; // NumPlayerApplicationSettingAttributeID 1387 // PlayerApplicationSettingAttributeID1 AVRCP Spec, Appendix F, 133 1388 connection->cmd_operands[8] = 0x01; // equalizer (1-OFF, 2-ON) 1389 connection->cmd_operands[9] = 0x02; // repeat (1-off, 2-single track, 3-all tracks, 4-group repeat) 1390 connection->cmd_operands[10] = 0x03; // shuffle (1-off, 2-all tracks, 3-group shuffle) 1391 connection->cmd_operands[11] = 0x04; // scan (1-off, 2-all tracks, 3-group scan) 1392 connection->cmd_operands_length = 12; 1393 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1394 return ERROR_CODE_SUCCESS; 1395 } 1396 1397 static uint8_t avrcp_controller_set_current_player_application_setting_value(uint16_t avrcp_cid, uint8_t attr_id, uint8_t attr_value){ 1398 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid); 1399 if (!connection){ 1400 log_error("avrcp_get_capabilities: could not find a connection."); 1401 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1402 } 1403 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1404 connection->state = AVCTP_W2_SEND_COMMAND; 1405 1406 connection->transaction_label = avrcp_controller_get_next_transaction_label(); 1407 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1408 connection->command_type = AVRCP_CTYPE_CONTROL; 1409 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1410 connection->subunit_id = AVRCP_SUBUNIT_ID; 1411 int pos = 0; 1412 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 1413 pos += 3; 1414 connection->cmd_operands[pos++] = AVRCP_PDU_ID_SET_PLAYER_APPLICATION_SETTING_VALUE; // PDU ID 1415 connection->cmd_operands[pos++] = 0; 1416 // Parameter Length 1417 big_endian_store_16(connection->cmd_operands, pos, 3); 1418 pos += 2; 1419 connection->cmd_operands[pos++] = 2; 1420 connection->cmd_operands_length = pos; 1421 connection->cmd_operands[pos++] = attr_id; 1422 connection->cmd_operands[pos++] = attr_value; 1423 connection->cmd_operands_length = pos; 1424 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1425 return ERROR_CODE_SUCCESS; 1426 } 1427 1428 uint8_t avrcp_controller_set_shuffle_mode(uint16_t avrcp_cid, avrcp_shuffle_mode_t mode){ 1429 if ((mode < AVRCP_SHUFFLE_MODE_OFF) || (mode > AVRCP_SHUFFLE_MODE_GROUP)) return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; 1430 return avrcp_controller_set_current_player_application_setting_value(avrcp_cid, 0x03, mode); 1431 } 1432 1433 uint8_t avrcp_controller_set_repeat_mode(uint16_t avrcp_cid, avrcp_repeat_mode_t mode){ 1434 if ((mode < AVRCP_REPEAT_MODE_OFF) || (mode > AVRCP_REPEAT_MODE_GROUP)) return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; 1435 return avrcp_controller_set_current_player_application_setting_value(avrcp_cid, 0x02, mode); 1436 } 1437 1438 uint8_t avrcp_controller_play_item_for_scope(uint16_t avrcp_cid, uint8_t * uid, uint16_t uid_counter, avrcp_browsing_scope_t scope){ 1439 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid); 1440 if (!connection){ 1441 log_error("Could not find a connection with cid 0%02x.", avrcp_cid); 1442 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1443 } 1444 if (connection->state != AVCTP_CONNECTION_OPENED){ 1445 log_error("Connection in wrong state, expected %d, received %d", AVCTP_CONNECTION_OPENED, connection->state); 1446 return ERROR_CODE_COMMAND_DISALLOWED; 1447 } 1448 connection->state = AVCTP_W2_SEND_COMMAND; 1449 1450 connection->transaction_label = avrcp_controller_get_next_transaction_label(); 1451 connection->command_type = AVRCP_CTYPE_CONTROL; 1452 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1453 connection->subunit_id = AVRCP_SUBUNIT_ID; 1454 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1455 int pos = 0; 1456 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 1457 pos += 3; 1458 connection->cmd_operands[pos++] = AVRCP_PDU_ID_PLAY_ITEM; // PDU ID 1459 // reserved 1460 connection->cmd_operands[pos++] = 0; 1461 // Parameter Length 1462 big_endian_store_16(connection->cmd_operands, pos, 11); 1463 pos += 2; 1464 connection->cmd_operands[pos++] = scope; 1465 memset(&connection->cmd_operands[pos], 0, 8); 1466 if (uid){ 1467 (void)memcpy(&connection->cmd_operands[pos], uid, 8); 1468 } 1469 pos += 8; 1470 big_endian_store_16(connection->cmd_operands, pos, uid_counter); 1471 pos += 2; 1472 connection->cmd_operands_length = pos; 1473 1474 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1475 return ERROR_CODE_SUCCESS; 1476 } 1477 1478 uint8_t avrcp_controller_add_item_from_scope_to_now_playing_list(uint16_t avrcp_cid, uint8_t * uid, uint16_t uid_counter, avrcp_browsing_scope_t scope){ 1479 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid); 1480 if (!connection){ 1481 log_error("Could not find a connection with cid 0%02x.", avrcp_cid); 1482 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1483 } 1484 if (connection->state != AVCTP_CONNECTION_OPENED){ 1485 log_error("Connection in wrong state, expected %d, received %d", AVCTP_CONNECTION_OPENED, connection->state); 1486 return ERROR_CODE_COMMAND_DISALLOWED; 1487 } 1488 connection->state = AVCTP_W2_SEND_COMMAND; 1489 1490 connection->transaction_label = avrcp_controller_get_next_transaction_label(); 1491 connection->command_type = AVRCP_CTYPE_CONTROL; 1492 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1493 connection->subunit_id = AVRCP_SUBUNIT_ID; 1494 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1495 int pos = 0; 1496 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 1497 pos += 3; 1498 connection->cmd_operands[pos++] = AVRCP_PDU_ID_ADD_TO_NOW_PLAYING; // PDU ID 1499 // reserved 1500 connection->cmd_operands[pos++] = 0; 1501 // Parameter Length 1502 big_endian_store_16(connection->cmd_operands, pos, 11); 1503 pos += 2; 1504 connection->cmd_operands[pos++] = scope; 1505 memset(&connection->cmd_operands[pos], 0, 8); 1506 if (uid){ 1507 (void)memcpy(&connection->cmd_operands[pos], uid, 8); 1508 } 1509 pos += 8; 1510 big_endian_store_16(connection->cmd_operands, pos, uid_counter); 1511 pos += 2; 1512 connection->cmd_operands_length = pos; 1513 1514 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1515 return ERROR_CODE_SUCCESS; 1516 } 1517 1518 uint8_t avrcp_controller_set_max_num_fragments(uint16_t avrcp_cid, uint8_t max_num_fragments){ 1519 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid); 1520 if (!connection){ 1521 log_error("avrcp_controller_play_item: could not find a connection."); 1522 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1523 } 1524 connection->max_num_fragments = max_num_fragments; 1525 return ERROR_CODE_SUCCESS; 1526 } 1527 1528 uint8_t avrcp_controller_send_custom_command(uint16_t avrcp_cid, avrcp_command_type_t command_type, avrcp_subunit_type_t subunit_type, avrcp_subunit_id_t subunit_id, avrcp_command_opcode_t command_opcode, const uint8_t * command_buffer, uint16_t command_len){ 1529 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid); 1530 if (!connection){ 1531 log_error("avrcp_controller_play_item: could not find a connection."); 1532 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1533 } 1534 1535 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1536 connection->state = AVCTP_W2_SEND_FRAGMENTED_COMMAND; 1537 1538 connection->transaction_label = avrcp_controller_get_next_transaction_label(); 1539 connection->command_opcode = command_opcode; 1540 connection->command_type = command_type; 1541 connection->subunit_type = subunit_type; 1542 connection->subunit_id = subunit_id; 1543 connection->cmd_operands_fragmented_buffer = command_buffer; 1544 connection->cmd_operands_fragmented_pos = 0; 1545 connection->cmd_operands_fragmented_len = command_len; 1546 1547 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1548 return ERROR_CODE_SUCCESS; 1549 } 1550