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