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 static int avrcp_send_cmd(uint16_t cid, avrcp_connection_t * connection){ 160 uint8_t command[30]; 161 int pos = 0; 162 // transport header 163 // Transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier) 164 command[pos++] = (connection->transaction_label << 4) | (AVRCP_SINGLE_PACKET << 2) | (AVRCP_COMMAND_FRAME << 1) | 0; 165 // Profile IDentifier (PID) 166 command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8; 167 command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF; 168 169 // command_type 170 command[pos++] = connection->command_type; 171 // subunit_type | subunit ID 172 command[pos++] = (connection->subunit_type << 3) | connection->subunit_id; 173 // opcode 174 command[pos++] = (uint8_t)connection->command_opcode; 175 // operands 176 memcpy(command+pos, connection->cmd_operands, connection->cmd_operands_length); 177 pos += connection->cmd_operands_length; 178 179 return l2cap_send(cid, command, pos); 180 } 181 182 static int avrcp_register_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t event_id){ 183 if (connection->notifications_to_deregister & (1 << event_id)) return 0; 184 if (connection->notifications_enabled & (1 << event_id)) return 0; 185 if (connection->notifications_to_register & (1 << event_id)) return 0; 186 connection->notifications_to_register |= (1 << event_id); 187 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 188 return 1; 189 } 190 191 static void avrcp_prepare_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t event_id){ 192 connection->transaction_label++; 193 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 194 connection->command_type = AVRCP_CTYPE_NOTIFY; 195 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 196 connection->subunit_id = AVRCP_SUBUNIT_ID; 197 int pos = 0; 198 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 199 pos += 3; 200 connection->cmd_operands[pos++] = AVRCP_PDU_ID_REGISTER_NOTIFICATION; 201 connection->cmd_operands[pos++] = 0; // reserved(upper 6) | packet_type -> 0 202 big_endian_store_16(connection->cmd_operands, pos, 5); // parameter length 203 pos += 2; 204 connection->cmd_operands[pos++] = event_id; 205 big_endian_store_32(connection->cmd_operands, pos, 0); 206 pos += 4; 207 connection->cmd_operands_length = pos; 208 // AVRCP_SPEC_V14.pdf 166 209 // answer page 61 210 } 211 212 213 static void avrcp_parser_reset(avrcp_connection_t * connection){ 214 connection->list_offset = 0; 215 connection->num_attributes = 0; 216 connection->num_parsed_attributes = 0; 217 connection->parser_attribute_header_pos = 0; 218 connection->parser_state = AVRCP_PARSER_IDLE; 219 } 220 221 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){ 222 uint8_t event[7]; 223 int pos = 0; 224 event[pos++] = HCI_EVENT_AVRCP_META; 225 event[pos++] = sizeof(event) - 2; 226 event[pos++] = AVRCP_SUBEVENT_NOW_PLAYING_INFO_DONE; 227 little_endian_store_16(event, pos, avrcp_cid); 228 pos += 2; 229 event[pos++] = ctype; 230 event[pos++] = status; 231 // printf_hexdump(event, pos); 232 (*callback)(HCI_EVENT_PACKET, 0, event, pos); 233 } 234 235 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){ 236 uint8_t event[HCI_EVENT_BUFFER_SIZE]; 237 int pos = 0; 238 event[pos++] = HCI_EVENT_AVRCP_META; 239 // reserve one byte for subevent type and data len 240 int data_len_pos = pos; 241 pos++; 242 int subevent_type_pos = pos; 243 pos++; 244 little_endian_store_16(event, pos, avrcp_cid); 245 pos += 2; 246 event[pos++] = ctype; 247 248 switch (attr_id){ 249 case AVRCP_MEDIA_ATTR_TITLE: 250 event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_TITLE_INFO; 251 event[pos++] = value_len; 252 memcpy(event+pos, value, value_len); 253 break; 254 case AVRCP_MEDIA_ATTR_ARTIST: 255 event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_ARTIST_INFO; 256 event[pos++] = value_len; 257 memcpy(event+pos, value, value_len); 258 break; 259 case AVRCP_MEDIA_ATTR_ALBUM: 260 event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_ALBUM_INFO; 261 event[pos++] = value_len; 262 memcpy(event+pos, value, value_len); 263 break; 264 case AVRCP_MEDIA_ATTR_GENRE: 265 event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_GENRE_INFO; 266 event[pos++] = value_len; 267 memcpy(event+pos, value, value_len); 268 break; 269 case AVRCP_MEDIA_ATTR_SONG_LENGTH_MS: 270 event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_SONG_LENGTH_MS_INFO; 271 if (value){ 272 little_endian_store_32(event, pos, btstack_atoi((char *)value)); 273 } else { 274 little_endian_store_32(event, pos, 0); 275 } 276 pos += 4; 277 break; 278 case AVRCP_MEDIA_ATTR_TRACK: 279 event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_TRACK_INFO; 280 if (value){ 281 event[pos++] = btstack_atoi((char *)value); 282 } else { 283 event[pos++] = 0; 284 } 285 break; 286 case AVRCP_MEDIA_ATTR_TOTAL_TRACKS: 287 event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_TOTAL_TRACKS_INFO; 288 if (value){ 289 event[pos++] = btstack_atoi((char *)value); 290 } else { 291 event[pos++] = 0; 292 } 293 break; 294 default: 295 break; 296 } 297 event[data_len_pos] = pos - 2; 298 // printf("send attr len %d, value %s\n", value_len, value); 299 (*callback)(HCI_EVENT_PACKET, 0, event, pos); 300 } 301 302 static void avrcp_parser_process_byte(uint8_t byte, avrcp_connection_t * connection, avrcp_command_type_t ctype){ 303 switch(connection->parser_state){ 304 case AVRCP_PARSER_GET_ATTRIBUTE_HEADER: 305 if (connection->parser_attribute_header_pos < AVRCP_ATTRIBUTE_HEADER_LEN) { 306 connection->parser_attribute_header[connection->parser_attribute_header_pos++] = byte; 307 connection->list_offset++; 308 break; 309 } 310 connection->attribute_value_len = btstack_min(big_endian_read_16(connection->parser_attribute_header, 6), AVRCP_MAX_ATTRIBUTTE_SIZE ); 311 // printf(" attr id %d, len to read %d, total len %d \n", big_endian_read_32(connection->parser_attribute_header, 0), connection->attribute_value_len, big_endian_read_16(connection->parser_attribute_header, 6)); 312 connection->parser_state = AVRCP_PARSER_GET_ATTRIBUTE_VALUE; 313 break; 314 case AVRCP_PARSER_GET_ATTRIBUTE_VALUE:{ 315 if (connection->attribute_value_offset < connection->attribute_value_len){ 316 connection->attribute_value[connection->attribute_value_offset++] = byte; 317 connection->list_offset++; 318 break; 319 } 320 // TODO emit event 321 uint32_t attribute_id = big_endian_read_32(connection->parser_attribute_header, 0); 322 if (attribute_id > AVRCP_MEDIA_ATTR_NONE && attribute_id <= AVRCP_MEDIA_ATTR_SONG_LENGTH_MS){ 323 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); 324 } 325 326 if (connection->attribute_value_offset < big_endian_read_16(connection->parser_attribute_header, 6)){ 327 // printf("parse until end of valuE, and ignore it\n"); 328 connection->parser_state = AVRCP_PARSER_IGNORE_ATTRIBUTE_VALUE; 329 break; 330 } 331 332 if (connection->list_offset == connection->list_size){ 333 avrcp_parser_reset(connection); 334 avrcp_controller_emit_now_playing_info_event_done(avrcp_controller_context.avrcp_callback, connection->avrcp_cid, ctype, 0); 335 break; 336 } 337 338 connection->parser_state = AVRCP_PARSER_GET_ATTRIBUTE_HEADER; 339 connection->parser_attribute_header_pos = 0; 340 break; 341 } 342 case AVRCP_PARSER_IGNORE_ATTRIBUTE_VALUE: 343 if (connection->attribute_value_offset < big_endian_read_16(connection->parser_attribute_header, 6)){ 344 connection->list_offset++; 345 connection->attribute_value_offset++; 346 break; 347 } 348 // printf("read %d, total %d\n", connection->attribute_value_offset, big_endian_read_16(connection->parser_attribute_header, 6)); 349 350 if (connection->list_offset == connection->list_size){ 351 avrcp_parser_reset(connection); 352 avrcp_controller_emit_now_playing_info_event_done(avrcp_controller_context.avrcp_callback, connection->avrcp_cid, ctype, 0); 353 break; 354 } 355 connection->parser_state = AVRCP_PARSER_GET_ATTRIBUTE_HEADER; 356 connection->parser_attribute_header_pos = 0; 357 break; 358 default: 359 break; 360 } 361 } 362 363 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){ 364 int i; 365 for (i=0;i<num_bytes_to_read;i++){ 366 avrcp_parser_process_byte(packet[i], connection, ctype); 367 } 368 } 369 370 static uint8_t avrcp_controller_request_abort_continuation(avrcp_connection_t * connection){ 371 connection->state = AVCTP_W2_SEND_COMMAND; 372 connection->transaction_label++; 373 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 374 connection->command_type = AVRCP_CTYPE_CONTROL; 375 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 376 connection->subunit_id = AVRCP_SUBUNIT_ID; 377 int pos = 0; 378 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 379 pos += 3; 380 connection->cmd_operands[pos++] = AVRCP_PDU_ID_REQUEST_ABORT_CONTINUING_RESPONSE; // PDU ID 381 connection->cmd_operands[pos++] = 0; 382 // Parameter Length 383 connection->cmd_operands_length = 8; 384 big_endian_store_16(connection->cmd_operands, pos, 1); 385 pos += 2; 386 connection->cmd_operands[pos++] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES; 387 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 388 return ERROR_CODE_SUCCESS; 389 } 390 391 392 static uint8_t avrcp_controller_request_continue_response(avrcp_connection_t * connection){ 393 connection->state = AVCTP_W2_SEND_COMMAND; 394 connection->transaction_label++; 395 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 396 connection->command_type = AVRCP_CTYPE_CONTROL; 397 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 398 connection->subunit_id = AVRCP_SUBUNIT_ID; 399 int pos = 0; 400 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 401 pos += 3; 402 connection->cmd_operands[pos++] = AVRCP_PDU_ID_REQUEST_CONTINUING_RESPONSE; // PDU ID 403 connection->cmd_operands[pos++] = 0; 404 // Parameter Length 405 connection->cmd_operands_length = 8; 406 big_endian_store_16(connection->cmd_operands, pos, 1); 407 pos += 2; 408 connection->cmd_operands[pos++] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES; 409 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 410 return ERROR_CODE_SUCCESS; 411 } 412 413 static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connection_t * connection, uint8_t *packet, uint16_t size){ 414 uint8_t operands[20]; 415 uint8_t opcode; 416 int pos = 3; 417 // uint8_t transport_header = packet[0]; 418 // uint8_t transaction_label = transport_header >> 4; 419 // uint8_t packet_type = (transport_header & 0x0F) >> 2; 420 // uint8_t frame_type = (transport_header & 0x03) >> 1; 421 // uint8_t ipid = transport_header & 0x01; 422 // uint8_t byte_value = packet[2]; 423 // uint16_t pid = (byte_value << 8) | packet[2]; 424 425 avrcp_command_type_t ctype = (avrcp_command_type_t) packet[pos++]; 426 uint8_t byte_value = packet[pos++]; 427 avrcp_subunit_type_t subunit_type = (avrcp_subunit_type_t) (byte_value >> 3); 428 avrcp_subunit_type_t subunit_id = (avrcp_subunit_type_t) (byte_value & 0x07); 429 opcode = packet[pos++]; 430 431 // printf(" Transport header 0x%02x (transaction_label %d, packet_type %d, frame_type %d, ipid %d), pid 0x%4x\n", 432 // transport_header, transaction_label, packet_type, frame_type, ipid, pid); 433 // // printf_hexdump(packet+pos, size-pos); 434 435 uint8_t pdu_id; 436 uint16_t param_length; 437 switch (avrcp_cmd_opcode(packet,size)){ 438 case AVRCP_CMD_OPCODE_UNIT_INFO:{ 439 if (connection->state != AVCTP_W2_RECEIVE_RESPONSE) return; 440 connection->state = AVCTP_CONNECTION_OPENED; 441 442 // operands: 443 memcpy(operands, packet+pos, 5); 444 uint8_t unit_type = operands[1] >> 3; 445 uint8_t unit = operands[1] & 0x07; 446 uint32_t company_id = operands[2] << 16 | operands[3] << 8 | operands[4]; 447 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, 448 ctype, subunit_type, subunit_id, opcode, unit_type, unit, company_id ); 449 break; 450 } 451 case AVRCP_CMD_OPCODE_VENDOR_DEPENDENT: 452 if (size - pos < 7) { 453 log_error("avrcp: wrong packet size"); 454 return; 455 }; 456 // operands: 457 memcpy(operands, packet+pos, 7); 458 pos += 7; 459 // uint32_t company_id = operands[0] << 16 | operands[1] << 8 | operands[2]; 460 pdu_id = operands[3]; 461 462 if (connection->state != AVCTP_W2_RECEIVE_RESPONSE && pdu_id != AVRCP_PDU_ID_REGISTER_NOTIFICATION){ 463 log_info("AVRCP_CMD_OPCODE_VENDOR_DEPENDENT state %d", connection->state); 464 return; 465 } 466 connection->state = AVCTP_CONNECTION_OPENED; 467 468 469 // uint8_t unit_type = operands[4] >> 3; 470 // uint8_t unit = operands[4] & 0x07; 471 param_length = big_endian_read_16(operands, 5); 472 473 // 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", 474 // ctype, subunit_type, subunit_id, opcode, unit_type, unit, company_id ); 475 476 // if (ctype == AVRCP_CTYPE_RESPONSE_INTERIM) return; 477 log_info(" VENDOR DEPENDENT response: pdu id 0x%02x, param_length %d, status %s", pdu_id, param_length, avrcp_ctype2str(ctype)); 478 switch (pdu_id){ 479 case AVRCP_PDU_ID_GetCurrentPlayerApplicationSettingValue:{ 480 uint8_t num_attributes = packet[pos++]; 481 int i; 482 avrcp_repeat_mode_t repeat_mode = AVRCP_REPEAT_MODE_INVALID; 483 avrcp_shuffle_mode_t shuffle_mode = AVRCP_SHUFFLE_MODE_INVALID; 484 for (i = 0; i < num_attributes; i++){ 485 uint8_t attribute_id = packet[pos++]; 486 uint8_t value = packet[pos++]; 487 switch (attribute_id){ 488 case 0x02: 489 repeat_mode = (avrcp_repeat_mode_t) value; 490 break; 491 case 0x03: 492 shuffle_mode = (avrcp_shuffle_mode_t) value; 493 break; 494 default: 495 break; 496 } 497 } 498 avrcp_emit_repeat_and_shuffle_mode(avrcp_controller_context.avrcp_callback, connection->avrcp_cid, ctype, repeat_mode, shuffle_mode); 499 break; 500 } 501 case AVRCP_PDU_ID_SetPlayerApplicationSettingValue:{ 502 uint8_t event[6]; 503 int offset = 0; 504 event[offset++] = HCI_EVENT_AVRCP_META; 505 event[offset++] = sizeof(event) - 2; 506 event[offset++] = AVRCP_SUBEVENT_PLAYER_APPLICATION_VALUE_RESPONSE; 507 little_endian_store_16(event, offset, connection->avrcp_cid); 508 offset += 2; 509 event[offset++] = ctype; 510 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 511 break; 512 } 513 case AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME:{ 514 uint8_t event[7]; 515 int offset = 0; 516 event[offset++] = HCI_EVENT_AVRCP_META; 517 event[offset++] = sizeof(event) - 2; 518 event[offset++] = AVRCP_SUBEVENT_SET_ABSOLUTE_VOLUME_RESPONSE; 519 little_endian_store_16(event, offset, connection->avrcp_cid); 520 offset += 2; 521 event[offset++] = ctype; 522 event[offset++] = packet[pos++]; 523 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 524 break; 525 } 526 case AVRCP_PDU_ID_GET_CAPABILITIES:{ 527 avrcp_capability_id_t capability_id = (avrcp_capability_id_t) packet[pos++]; 528 uint8_t capability_count = packet[pos++]; 529 int i; 530 switch (capability_id){ 531 case AVRCP_CAPABILITY_ID_COMPANY: 532 // log_info("Supported companies %d: ", capability_count); 533 for (i = 0; i < capability_count; i++){ 534 uint32_t company_id = big_endian_read_24(packet, pos); 535 pos += 3; 536 log_info(" 0x%06" PRIx32 ", ", company_id); 537 } 538 break; 539 case AVRCP_CAPABILITY_ID_EVENT: 540 // log_info("Supported events %d: ", capability_count); 541 for (i = 0; i < capability_count; i++){ 542 uint8_t event_id = packet[pos++]; 543 log_info(" 0x%02x %s", event_id, avrcp_event2str(event_id)); 544 } 545 break; 546 } 547 break; 548 } 549 case AVRCP_PDU_ID_GET_PLAY_STATUS:{ 550 uint32_t song_length = big_endian_read_32(packet, pos); 551 pos += 4; 552 uint32_t song_position = big_endian_read_32(packet, pos); 553 pos += 4; 554 uint8_t play_status = packet[pos]; 555 // log_info(" GET_PLAY_STATUS length 0x%04X, position 0x%04X, status %s", song_length, song_position, avrcp_play_status2str(play_status)); 556 557 uint8_t event[15]; 558 int offset = 0; 559 event[offset++] = HCI_EVENT_AVRCP_META; 560 event[offset++] = sizeof(event) - 2; 561 event[offset++] = AVRCP_SUBEVENT_PLAY_STATUS; 562 little_endian_store_16(event, offset, connection->avrcp_cid); 563 offset += 2; 564 event[offset++] = ctype; 565 little_endian_store_32(event, offset, song_length); 566 offset += 4; 567 little_endian_store_32(event, offset, song_position); 568 offset += 4; 569 event[offset++] = play_status; 570 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 571 break; 572 } 573 case AVRCP_PDU_ID_REGISTER_NOTIFICATION:{ 574 avrcp_notification_event_id_t event_id = (avrcp_notification_event_id_t) packet[pos++]; 575 uint16_t event_mask = (1 << event_id); 576 uint16_t reset_event_mask = ~event_mask; 577 switch (ctype){ 578 case AVRCP_CTYPE_RESPONSE_INTERIM: 579 // register as enabled 580 connection->notifications_enabled |= event_mask; 581 // printf("INTERIM notifications_enabled 0x%2x, notifications_to_register 0x%2x\n", connection->notifications_enabled, connection->notifications_to_register); 582 break; 583 case AVRCP_CTYPE_RESPONSE_CHANGED_STABLE: 584 // received change, event is considered deregistered 585 // we are re-enabling it automatically, if it is not 586 // explicitly disabled 587 connection->notifications_enabled &= reset_event_mask; 588 if (! (connection->notifications_to_deregister & event_mask)){ 589 avrcp_register_notification(connection, event_id); 590 // printf("CHANGED_STABLE notifications_enabled 0x%2x, notifications_to_register 0x%2x\n", connection->notifications_enabled, connection->notifications_to_register); 591 } else { 592 connection->notifications_to_deregister &= reset_event_mask; 593 } 594 break; 595 default: 596 connection->notifications_to_register &= reset_event_mask; 597 connection->notifications_enabled &= reset_event_mask; 598 connection->notifications_to_deregister &= reset_event_mask; 599 break; 600 } 601 602 switch (event_id){ 603 case AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED:{ 604 uint8_t event[7]; 605 int offset = 0; 606 event[offset++] = HCI_EVENT_AVRCP_META; 607 event[offset++] = sizeof(event) - 2; 608 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_PLAYBACK_STATUS_CHANGED; 609 little_endian_store_16(event, offset, connection->avrcp_cid); 610 offset += 2; 611 event[offset++] = ctype; 612 event[offset++] = packet[pos]; 613 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 614 break; 615 } 616 case AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED:{ 617 uint8_t event[6]; 618 int offset = 0; 619 event[offset++] = HCI_EVENT_AVRCP_META; 620 event[offset++] = sizeof(event) - 2; 621 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_TRACK_CHANGED; 622 little_endian_store_16(event, offset, connection->avrcp_cid); 623 offset += 2; 624 event[offset++] = ctype; 625 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 626 break; 627 } 628 case AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED:{ 629 uint8_t event[6]; 630 int offset = 0; 631 event[offset++] = HCI_EVENT_AVRCP_META; 632 event[offset++] = sizeof(event) - 2; 633 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_NOW_PLAYING_CONTENT_CHANGED; 634 little_endian_store_16(event, offset, connection->avrcp_cid); 635 offset += 2; 636 event[offset++] = ctype; 637 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 638 break; 639 } 640 case AVRCP_NOTIFICATION_EVENT_AVAILABLE_PLAYERS_CHANGED:{ 641 uint8_t event[6]; 642 int offset = 0; 643 event[offset++] = HCI_EVENT_AVRCP_META; 644 event[offset++] = sizeof(event) - 2; 645 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_AVAILABLE_PLAYERS_CHANGED; 646 little_endian_store_16(event, offset, connection->avrcp_cid); 647 offset += 2; 648 event[offset++] = ctype; 649 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 650 break; 651 } 652 case AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED:{ 653 uint8_t event[7]; 654 int offset = 0; 655 event[offset++] = HCI_EVENT_AVRCP_META; 656 event[offset++] = sizeof(event) - 2; 657 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED; 658 little_endian_store_16(event, offset, connection->avrcp_cid); 659 offset += 2; 660 event[offset++] = ctype; 661 event[offset++] = packet[pos++] & 0x7F; 662 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 663 break; 664 } 665 // case AVRCP_NOTIFICATION_EVENT_PLAYER_APPLICATION_SETTING_CHANGED:{ 666 // uint8_t num_PlayerApplicationSettingAttributes = packet[pos++]; 667 // int i; 668 // for (i = 0; i < num_PlayerApplicationSettingAttributes; i++){ 669 // uint8_t PlayerApplicationSetting_AttributeID = packet[pos++]; 670 // uint8_t PlayerApplicationSettingValueID = packet[pos++]; 671 // } 672 // break; 673 // } 674 // case AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED: 675 // uint16_t player_id = big_endian_read_16(packet, pos); 676 // pos += 2; 677 // uint16_t uid_counter = big_endian_read_16(packet, pos); 678 // pos += 2; 679 // break; 680 // case AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED: 681 // uint16_t uid_counter = big_endian_read_16(packet, pos); 682 // pos += 2; 683 // break; 684 default: 685 log_info("avrcp: not implemented"); 686 break; 687 } 688 if (connection->notifications_to_register != 0){ 689 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 690 } 691 break; 692 } 693 694 case AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES:{ 695 avrcp_packet_type_t packet_type = operands[4] & 0x03; 696 switch (packet_type){ 697 case AVRCP_START_PACKET: 698 case AVRCP_SINGLE_PACKET: 699 avrcp_parser_reset(connection); 700 connection->list_size = param_length; 701 connection->num_attributes = packet[pos++]; 702 // 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); 703 connection->parser_state = AVRCP_PARSER_GET_ATTRIBUTE_HEADER; 704 avrcp_source_parse_and_emit_element_attrs(packet+pos, size-pos, connection, ctype); 705 706 if (packet_type == AVRCP_START_PACKET){ 707 if (connection->num_attributes == 1 && connection->parser_state == AVRCP_PARSER_IGNORE_ATTRIBUTE_VALUE){ 708 avrcp_controller_request_abort_continuation(connection); 709 } else { 710 avrcp_controller_request_continue_response(connection); 711 } 712 } 713 break; 714 case AVRCP_CONTINUE_PACKET: 715 avrcp_source_parse_and_emit_element_attrs(packet+pos, size-pos, connection, ctype); 716 avrcp_controller_request_continue_response(connection); 717 break; 718 case AVRCP_END_PACKET: 719 avrcp_source_parse_and_emit_element_attrs(packet+pos, size-pos, connection, ctype); 720 break; 721 } 722 } 723 default: 724 break; 725 } 726 break; 727 case AVRCP_CMD_OPCODE_PASS_THROUGH:{ 728 // 0x80 | connection->cmd_operands[0] 729 uint8_t operation_id = packet[pos++]; 730 switch (connection->state){ 731 case AVCTP_W2_RECEIVE_PRESS_RESPONSE: 732 if (connection->continuous_fast_forward_cmd){ 733 connection->state = AVCTP_W4_STOP; 734 } else { 735 connection->state = AVCTP_W2_SEND_RELEASE_COMMAND; 736 } 737 break; 738 case AVCTP_W2_RECEIVE_RESPONSE: 739 connection->state = AVCTP_CONNECTION_OPENED; 740 break; 741 default: 742 // check for notifications? move state transition down 743 // log_info("AVRCP_CMD_OPCODE_PASS_THROUGH state %d\n", connection->state); 744 break; 745 } 746 if (connection->state == AVCTP_W4_STOP){ 747 avrcp_emit_operation_status(avrcp_controller_context.avrcp_callback, AVRCP_SUBEVENT_OPERATION_START, connection->avrcp_cid, ctype, operation_id); 748 } 749 if (connection->state == AVCTP_CONNECTION_OPENED) { 750 // RELEASE response 751 operation_id = operation_id & 0x7F; 752 avrcp_emit_operation_status(avrcp_controller_context.avrcp_callback, AVRCP_SUBEVENT_OPERATION_COMPLETE, connection->avrcp_cid, ctype, operation_id); 753 } 754 if (connection->state == AVCTP_W2_SEND_RELEASE_COMMAND){ 755 // PRESS response 756 request_pass_through_release_control_cmd(connection); 757 } 758 break; 759 } 760 default: 761 break; 762 } 763 } 764 765 static void avrcp_controller_handle_can_send_now(avrcp_connection_t * connection){ 766 int i; 767 switch (connection->state){ 768 case AVCTP_W2_SEND_PRESS_COMMAND: 769 connection->state = AVCTP_W2_RECEIVE_PRESS_RESPONSE; 770 avrcp_send_cmd(connection->l2cap_signaling_cid, connection); 771 break; 772 case AVCTP_W2_SEND_COMMAND: 773 case AVCTP_W2_SEND_RELEASE_COMMAND: 774 connection->state = AVCTP_W2_RECEIVE_RESPONSE; 775 avrcp_send_cmd(connection->l2cap_signaling_cid, connection); 776 break; 777 case AVCTP_CONNECTION_OPENED: 778 if (connection->notifications_to_register != 0){ 779 for (i = 1; i <= AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED; i++){ 780 if (connection->notifications_to_register & (1<<i)){ 781 connection->notifications_to_register &= ~ (1 << i); 782 avrcp_prepare_notification(connection, (avrcp_notification_event_id_t) i); 783 connection->state = AVCTP_W2_RECEIVE_RESPONSE; 784 avrcp_send_cmd(connection->l2cap_signaling_cid, connection); 785 return; 786 } 787 } 788 } 789 return; 790 default: 791 return; 792 } 793 } 794 795 static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 796 avrcp_connection_t * connection; 797 798 switch (packet_type) { 799 case L2CAP_DATA_PACKET: 800 connection = get_avrcp_connection_for_l2cap_signaling_cid(channel, &avrcp_controller_context); 801 if (!connection) break; 802 avrcp_handle_l2cap_data_packet_for_signaling_connection(connection, packet, size); 803 break; 804 case HCI_EVENT_PACKET: 805 switch (hci_event_packet_get_type(packet)){ 806 case L2CAP_EVENT_CAN_SEND_NOW: 807 connection = get_avrcp_connection_for_l2cap_signaling_cid(channel, &avrcp_controller_context); 808 if (!connection) break; 809 avrcp_controller_handle_can_send_now(connection); 810 break; 811 default: 812 avrcp_packet_handler(packet_type, channel, packet, size, &avrcp_controller_context); 813 break; 814 } 815 default: 816 break; 817 } 818 } 819 820 void avrcp_controller_init(void){ 821 avrcp_controller_context.role = AVRCP_CONTROLLER; 822 avrcp_controller_context.connections = NULL; 823 avrcp_controller_context.packet_handler = avrcp_controller_packet_handler; 824 l2cap_register_service(&avrcp_controller_packet_handler, BLUETOOTH_PROTOCOL_AVCTP, 0xffff, LEVEL_0); 825 } 826 827 void avrcp_controller_register_packet_handler(btstack_packet_handler_t callback){ 828 if (callback == NULL){ 829 log_error("avrcp_register_packet_handler called with NULL callback"); 830 return; 831 } 832 avrcp_controller_context.avrcp_callback = callback; 833 } 834 835 uint8_t avrcp_controller_connect(bd_addr_t bd_addr, uint16_t * avrcp_cid){ 836 return avrcp_connect(bd_addr, &avrcp_controller_context, avrcp_cid); 837 } 838 839 uint8_t avrcp_controller_unit_info(uint16_t avrcp_cid){ 840 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 841 if (!connection){ 842 log_error("avrcp_unit_info: could not find a connection."); 843 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 844 } 845 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 846 connection->state = AVCTP_W2_SEND_COMMAND; 847 848 connection->transaction_label++; 849 connection->command_opcode = AVRCP_CMD_OPCODE_UNIT_INFO; 850 connection->command_type = AVRCP_CTYPE_STATUS; 851 connection->subunit_type = AVRCP_SUBUNIT_TYPE_UNIT; //vendor unique 852 connection->subunit_id = AVRCP_SUBUNIT_ID_IGNORE; 853 memset(connection->cmd_operands, 0xFF, connection->cmd_operands_length); 854 connection->cmd_operands_length = 5; 855 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 856 return ERROR_CODE_SUCCESS; 857 } 858 859 static uint8_t avrcp_controller_get_capabilities(uint16_t avrcp_cid, uint8_t capability_id){ 860 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 861 if (!connection){ 862 log_error("avrcp_get_capabilities: could not find a connection."); 863 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 864 } 865 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 866 connection->state = AVCTP_W2_SEND_COMMAND; 867 868 connection->transaction_label++; 869 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 870 connection->command_type = AVRCP_CTYPE_STATUS; 871 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 872 connection->subunit_id = AVRCP_SUBUNIT_ID; 873 big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID); 874 connection->cmd_operands[3] = AVRCP_PDU_ID_GET_CAPABILITIES; // PDU ID 875 connection->cmd_operands[4] = 0; 876 big_endian_store_16(connection->cmd_operands, 5, 1); // parameter length 877 connection->cmd_operands[7] = capability_id; // capability ID 878 connection->cmd_operands_length = 8; 879 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 880 return ERROR_CODE_SUCCESS; 881 } 882 883 uint8_t avrcp_controller_get_supported_company_ids(uint16_t avrcp_cid){ 884 return avrcp_controller_get_capabilities(avrcp_cid, AVRCP_CAPABILITY_ID_COMPANY); 885 } 886 887 uint8_t avrcp_controller_get_supported_events(uint16_t avrcp_cid){ 888 return avrcp_controller_get_capabilities(avrcp_cid, AVRCP_CAPABILITY_ID_EVENT); 889 } 890 891 892 uint8_t avrcp_controller_play(uint16_t avrcp_cid){ 893 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PLAY, 0); 894 } 895 896 uint8_t avrcp_controller_stop(uint16_t avrcp_cid){ 897 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_STOP, 0); 898 } 899 900 uint8_t avrcp_controller_pause(uint16_t avrcp_cid){ 901 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PAUSE, 0); 902 } 903 904 uint8_t avrcp_controller_forward(uint16_t avrcp_cid){ 905 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FORWARD, 0); 906 } 907 908 uint8_t avrcp_controller_backward(uint16_t avrcp_cid){ 909 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_BACKWARD, 0); 910 } 911 912 uint8_t avrcp_controller_start_rewind(uint16_t avrcp_cid){ 913 return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_REWIND, 0); 914 } 915 916 uint8_t avrcp_controller_volume_up(uint16_t avrcp_cid){ 917 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_UP, 0); 918 } 919 920 uint8_t avrcp_controller_volume_down(uint16_t avrcp_cid){ 921 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_DOWN, 0); 922 } 923 924 uint8_t avrcp_controller_mute(uint16_t avrcp_cid){ 925 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_MUTE, 0); 926 } 927 928 uint8_t avrcp_controller_skip(uint16_t avrcp_cid){ 929 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_SKIP, 0); 930 } 931 932 uint8_t avrcp_controller_stop_rewind(uint16_t avrcp_cid){ 933 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 934 if (!connection){ 935 log_error("avrcp_stop_rewind: could not find a connection."); 936 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 937 } 938 if (connection->state != AVCTP_W4_STOP) return ERROR_CODE_COMMAND_DISALLOWED; 939 return request_pass_through_release_control_cmd(connection); 940 } 941 942 uint8_t avrcp_controller_start_fast_forward(uint16_t avrcp_cid){ 943 return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FAST_FORWARD, 0); 944 } 945 946 uint8_t avrcp_controller_fast_forward(uint16_t avrcp_cid){ 947 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FAST_FORWARD, 0); 948 } 949 950 uint8_t avrcp_controller_rewind(uint16_t avrcp_cid){ 951 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_REWIND, 0); 952 } 953 954 955 uint8_t avrcp_controller_stop_fast_forward(uint16_t avrcp_cid){ 956 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 957 if (!connection){ 958 log_error("avrcp_stop_fast_forward: could not find a connection."); 959 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 960 } 961 if (connection->state != AVCTP_W4_STOP) return ERROR_CODE_COMMAND_DISALLOWED; 962 return request_pass_through_release_control_cmd(connection); 963 } 964 965 uint8_t avrcp_controller_get_play_status(uint16_t avrcp_cid){ 966 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 967 if (!connection){ 968 log_error("avrcp_get_play_status: could not find a connection."); 969 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 970 } 971 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 972 connection->state = AVCTP_W2_SEND_COMMAND; 973 connection->transaction_label++; 974 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 975 connection->command_type = AVRCP_CTYPE_STATUS; 976 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 977 connection->subunit_id = AVRCP_SUBUNIT_ID; 978 big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID); 979 connection->cmd_operands[3] = AVRCP_PDU_ID_GET_PLAY_STATUS; 980 connection->cmd_operands[4] = 0; // reserved(upper 6) | packet_type -> 0 981 big_endian_store_16(connection->cmd_operands, 5, 0); // parameter length 982 connection->cmd_operands_length = 7; 983 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 984 return ERROR_CODE_SUCCESS; 985 } 986 987 uint8_t avrcp_controller_enable_notification(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id){ 988 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 989 if (!connection){ 990 log_error("avrcp_get_play_status: could not find a connection."); 991 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 992 } 993 avrcp_register_notification(connection, event_id); 994 return ERROR_CODE_SUCCESS; 995 } 996 997 uint8_t avrcp_controller_disable_notification(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id){ 998 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 999 if (!connection){ 1000 log_error("avrcp_get_play_status: could not find a connection."); 1001 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1002 } 1003 connection->notifications_to_deregister |= (1 << event_id); 1004 return ERROR_CODE_SUCCESS; 1005 } 1006 1007 1008 uint8_t avrcp_controller_get_now_playing_info(uint16_t avrcp_cid){ 1009 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 1010 if (!connection){ 1011 log_error("avrcp_get_capabilities: could not find a connection."); 1012 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1013 } 1014 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1015 connection->state = AVCTP_W2_SEND_COMMAND; 1016 1017 connection->transaction_label++; 1018 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1019 connection->command_type = AVRCP_CTYPE_STATUS; 1020 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1021 connection->subunit_id = AVRCP_SUBUNIT_ID; 1022 int pos = 0; 1023 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 1024 pos += 3; 1025 connection->cmd_operands[pos++] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES; // PDU ID 1026 connection->cmd_operands[pos++] = 0; 1027 1028 // Parameter Length 1029 big_endian_store_16(connection->cmd_operands, pos, 9); 1030 pos += 2; 1031 1032 // write 8 bytes value 1033 memset(connection->cmd_operands + pos, 0, 8); // identifier: PLAYING 1034 pos += 8; 1035 1036 connection->cmd_operands[pos++] = 0; // attribute count, if 0 get all attributes 1037 // every attribute is 4 bytes long 1038 1039 connection->cmd_operands_length = pos; 1040 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1041 return ERROR_CODE_SUCCESS; 1042 } 1043 1044 uint8_t avrcp_controller_set_absolute_volume(uint16_t avrcp_cid, uint8_t volume){ 1045 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 1046 if (!connection){ 1047 log_error("avrcp_get_capabilities: could not find a connection."); 1048 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1049 } 1050 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1051 connection->state = AVCTP_W2_SEND_COMMAND; 1052 1053 connection->transaction_label++; 1054 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1055 connection->command_type = AVRCP_CTYPE_CONTROL; 1056 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1057 connection->subunit_id = AVRCP_SUBUNIT_ID; 1058 int pos = 0; 1059 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 1060 pos += 3; 1061 connection->cmd_operands[pos++] = AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME; // PDU ID 1062 connection->cmd_operands[pos++] = 0; 1063 1064 // Parameter Length 1065 big_endian_store_16(connection->cmd_operands, pos, 1); 1066 pos += 2; 1067 connection->cmd_operands[pos++] = volume; 1068 1069 connection->cmd_operands_length = pos; 1070 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1071 return ERROR_CODE_SUCCESS; 1072 } 1073 1074 uint8_t avrcp_controller_query_shuffle_and_repeat_modes(uint16_t avrcp_cid){ 1075 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 1076 if (!connection){ 1077 log_error("avrcp_get_capabilities: could not find a connection."); 1078 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1079 } 1080 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1081 connection->state = AVCTP_W2_SEND_COMMAND; 1082 1083 connection->transaction_label++; 1084 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1085 connection->command_type = AVRCP_CTYPE_STATUS; 1086 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1087 connection->subunit_id = AVRCP_SUBUNIT_ID; 1088 big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID); 1089 connection->cmd_operands[3] = AVRCP_PDU_ID_GetCurrentPlayerApplicationSettingValue; // PDU ID 1090 connection->cmd_operands[4] = 0; 1091 big_endian_store_16(connection->cmd_operands, 5, 5); // parameter length 1092 connection->cmd_operands[7] = 4; // NumPlayerApplicationSettingAttributeID 1093 // PlayerApplicationSettingAttributeID1 AVRCP Spec, Appendix F, 133 1094 connection->cmd_operands[8] = 0x01; // equalizer (1-OFF, 2-ON) 1095 connection->cmd_operands[9] = 0x02; // repeat (1-off, 2-single track, 3-all tracks, 4-group repeat) 1096 connection->cmd_operands[10] = 0x03; // shuffle (1-off, 2-all tracks, 3-group shuffle) 1097 connection->cmd_operands[11] = 0x04; // scan (1-off, 2-all tracks, 3-group scan) 1098 connection->cmd_operands_length = 12; 1099 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1100 return ERROR_CODE_SUCCESS; 1101 } 1102 1103 static uint8_t avrcp_controller_set_current_player_application_setting_value(uint16_t avrcp_cid, uint8_t attr_id, uint8_t attr_value){ 1104 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 1105 if (!connection){ 1106 log_error("avrcp_get_capabilities: could not find a connection."); 1107 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1108 } 1109 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1110 connection->state = AVCTP_W2_SEND_COMMAND; 1111 1112 connection->transaction_label++; 1113 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1114 connection->command_type = AVRCP_CTYPE_CONTROL; 1115 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1116 connection->subunit_id = AVRCP_SUBUNIT_ID; 1117 int pos = 0; 1118 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 1119 pos += 3; 1120 connection->cmd_operands[pos++] = AVRCP_PDU_ID_SetPlayerApplicationSettingValue; // PDU ID 1121 connection->cmd_operands[pos++] = 0; 1122 // Parameter Length 1123 big_endian_store_16(connection->cmd_operands, pos, 3); 1124 pos += 2; 1125 connection->cmd_operands[pos++] = 2; 1126 connection->cmd_operands_length = pos; 1127 connection->cmd_operands[pos++] = attr_id; 1128 connection->cmd_operands[pos++] = attr_value; 1129 connection->cmd_operands_length = pos; 1130 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1131 return ERROR_CODE_SUCCESS; 1132 } 1133 1134 uint8_t avrcp_controller_set_shuffle_mode(uint16_t avrcp_cid, avrcp_shuffle_mode_t mode){ 1135 if (mode < AVRCP_SHUFFLE_MODE_OFF || mode > AVRCP_SHUFFLE_MODE_GROUP) return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; 1136 return avrcp_controller_set_current_player_application_setting_value(avrcp_cid, 0x03, mode); 1137 } 1138 1139 uint8_t avrcp_controller_set_repeat_mode(uint16_t avrcp_cid, avrcp_repeat_mode_t mode){ 1140 if (mode < AVRCP_REPEAT_MODE_OFF || mode > AVRCP_REPEAT_MODE_GROUP) return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; 1141 return avrcp_controller_set_current_player_application_setting_value(avrcp_cid, 0x02, mode); 1142 } 1143 1144 uint8_t avrcp_controller_disconnect(uint16_t avrcp_cid){ 1145 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 1146 if (!connection){ 1147 log_error("avrcp_get_capabilities: could not find a connection."); 1148 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1149 } 1150 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1151 l2cap_disconnect(connection->l2cap_signaling_cid, 0); 1152 return ERROR_CODE_SUCCESS; 1153 } 1154