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