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