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 static avrcp_context_t avrcp_controller_context; 51 52 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){ 53 avrcp_create_sdp_record(1, service, service_record_handle, browsing, supported_features, service_name, service_provider_name); 54 } 55 56 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){ 57 if (!callback) return; 58 uint8_t event[8]; 59 int pos = 0; 60 event[pos++] = HCI_EVENT_AVRCP_META; 61 event[pos++] = sizeof(event) - 2; 62 event[pos++] = AVRCP_SUBEVENT_SHUFFLE_AND_REPEAT_MODE; 63 little_endian_store_16(event, pos, avrcp_cid); 64 pos += 2; 65 event[pos++] = ctype; 66 event[pos++] = repeat_mode; 67 event[pos++] = shuffle_mode; 68 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 69 } 70 71 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){ 72 if (!callback) return; 73 uint8_t event[7]; 74 int pos = 0; 75 event[pos++] = HCI_EVENT_AVRCP_META; 76 event[pos++] = sizeof(event) - 2; 77 event[pos++] = subevent; 78 little_endian_store_16(event, pos, avrcp_cid); 79 pos += 2; 80 event[pos++] = ctype; 81 event[pos++] = operation_id; 82 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 83 } 84 85 static void avrcp_press_and_hold_timeout_handler(btstack_timer_source_t * timer){ 86 UNUSED(timer); 87 avrcp_connection_t * connection = btstack_run_loop_get_timer_context(timer); 88 btstack_run_loop_set_timer(&connection->press_and_hold_cmd_timer, 2000); // 2 seconds timeout 89 btstack_run_loop_add_timer(&connection->press_and_hold_cmd_timer); 90 connection->state = AVCTP_W2_SEND_PRESS_COMMAND; 91 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 92 } 93 94 static void avrcp_press_and_hold_timer_start(avrcp_connection_t * connection){ 95 btstack_run_loop_remove_timer(&connection->press_and_hold_cmd_timer); 96 btstack_run_loop_set_timer_handler(&connection->press_and_hold_cmd_timer, avrcp_press_and_hold_timeout_handler); 97 btstack_run_loop_set_timer_context(&connection->press_and_hold_cmd_timer, connection); 98 btstack_run_loop_set_timer(&connection->press_and_hold_cmd_timer, 2000); // 2 seconds timeout 99 btstack_run_loop_add_timer(&connection->press_and_hold_cmd_timer); 100 } 101 102 static void avrcp_press_and_hold_timer_stop(avrcp_connection_t * connection){ 103 connection->continuous_fast_forward_cmd = 0; 104 btstack_run_loop_remove_timer(&connection->press_and_hold_cmd_timer); 105 } 106 107 static uint8_t request_pass_through_release_control_cmd(avrcp_connection_t * connection){ 108 connection->state = AVCTP_W2_SEND_RELEASE_COMMAND; 109 if (connection->continuous_fast_forward_cmd){ 110 avrcp_press_and_hold_timer_stop(connection); 111 } 112 connection->cmd_operands[0] = 0x80 | connection->cmd_operands[0]; 113 connection->transaction_label++; 114 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 115 return ERROR_CODE_SUCCESS; 116 } 117 118 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){ 119 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, context); 120 if (!connection){ 121 log_error("avrcp: could not find a connection."); 122 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 123 } 124 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 125 connection->state = AVCTP_W2_SEND_PRESS_COMMAND; 126 connection->command_opcode = AVRCP_CMD_OPCODE_PASS_THROUGH; 127 connection->command_type = AVRCP_CTYPE_CONTROL; 128 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 129 connection->subunit_id = AVRCP_SUBUNIT_ID; 130 connection->cmd_operands_length = 0; 131 132 connection->continuous_fast_forward_cmd = continuous_fast_forward_cmd; 133 connection->cmd_operands_length = 2; 134 connection->cmd_operands[0] = opid; 135 if (playback_speed > 0){ 136 connection->cmd_operands[2] = playback_speed; 137 connection->cmd_operands_length++; 138 } 139 connection->cmd_operands[1] = connection->cmd_operands_length - 2; 140 141 if (connection->continuous_fast_forward_cmd){ 142 avrcp_press_and_hold_timer_start(connection); 143 } 144 145 connection->transaction_label++; 146 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 147 return ERROR_CODE_SUCCESS; 148 } 149 150 static uint8_t request_single_pass_through_press_control_cmd(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint16_t playback_speed){ 151 return request_pass_through_press_control_cmd(avrcp_cid, opid, playback_speed, 0, &avrcp_controller_context); 152 } 153 154 static uint8_t request_continuous_pass_through_press_control_cmd(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint16_t playback_speed){ 155 return request_pass_through_press_control_cmd(avrcp_cid, opid, playback_speed, 1, &avrcp_controller_context); 156 } 157 158 static int avrcp_send_cmd(uint16_t cid, avrcp_connection_t * connection){ 159 uint8_t command[30]; 160 int pos = 0; 161 // transport header 162 // Transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier) 163 command[pos++] = (connection->transaction_label << 4) | (AVRCP_SINGLE_PACKET << 2) | (AVRCP_COMMAND_FRAME << 1) | 0; 164 // Profile IDentifier (PID) 165 command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8; 166 command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF; 167 168 // command_type 169 command[pos++] = connection->command_type; 170 // subunit_type | subunit ID 171 command[pos++] = (connection->subunit_type << 3) | connection->subunit_id; 172 // opcode 173 command[pos++] = (uint8_t)connection->command_opcode; 174 // operands 175 memcpy(command+pos, connection->cmd_operands, connection->cmd_operands_length); 176 pos += connection->cmd_operands_length; 177 178 return l2cap_send(cid, command, pos); 179 } 180 181 static int avrcp_register_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t event_id){ 182 if (connection->notifications_to_deregister & (1 << event_id)) return 0; 183 if (connection->notifications_enabled & (1 << event_id)) return 0; 184 if (connection->notifications_to_register & (1 << event_id)) return 0; 185 connection->notifications_to_register |= (1 << event_id); 186 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 187 return 1; 188 } 189 190 static void avrcp_prepare_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t event_id){ 191 connection->transaction_label++; 192 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 193 connection->command_type = AVRCP_CTYPE_NOTIFY; 194 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 195 connection->subunit_id = AVRCP_SUBUNIT_ID; 196 int pos = 0; 197 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 198 pos += 3; 199 connection->cmd_operands[pos++] = AVRCP_PDU_ID_REGISTER_NOTIFICATION; 200 connection->cmd_operands[pos++] = 0; // reserved(upper 6) | packet_type -> 0 201 big_endian_store_16(connection->cmd_operands, pos, 5); // parameter length 202 pos += 2; 203 connection->cmd_operands[pos++] = event_id; 204 big_endian_store_32(connection->cmd_operands, pos, 0); 205 pos += 4; 206 connection->cmd_operands_length = pos; 207 // AVRCP_SPEC_V14.pdf 166 208 // answer page 61 209 } 210 211 static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connection_t * connection, uint8_t *packet, uint16_t size){ 212 uint8_t operands[20]; 213 uint8_t opcode; 214 int pos = 3; 215 // uint8_t transport_header = packet[0]; 216 // uint8_t transaction_label = transport_header >> 4; 217 // uint8_t packet_type = (transport_header & 0x0F) >> 2; 218 // uint8_t frame_type = (transport_header & 0x03) >> 1; 219 // uint8_t ipid = transport_header & 0x01; 220 // uint8_t byte_value = packet[2]; 221 // uint16_t pid = (byte_value << 8) | packet[2]; 222 223 avrcp_command_type_t ctype = (avrcp_command_type_t) packet[pos++]; 224 uint8_t byte_value = packet[pos++]; 225 avrcp_subunit_type_t subunit_type = (avrcp_subunit_type_t) (byte_value >> 3); 226 avrcp_subunit_type_t subunit_id = (avrcp_subunit_type_t) (byte_value & 0x07); 227 opcode = packet[pos++]; 228 229 // printf(" Transport header 0x%02x (transaction_label %d, packet_type %d, frame_type %d, ipid %d), pid 0x%4x\n", 230 // transport_header, transaction_label, packet_type, frame_type, ipid, pid); 231 // // printf_hexdump(packet+pos, size-pos); 232 233 uint8_t pdu_id; 234 uint16_t param_length; 235 switch (avrcp_cmd_opcode(packet,size)){ 236 case AVRCP_CMD_OPCODE_UNIT_INFO:{ 237 if (connection->state != AVCTP_W2_RECEIVE_RESPONSE) return; 238 connection->state = AVCTP_CONNECTION_OPENED; 239 240 // operands: 241 memcpy(operands, packet+pos, 5); 242 uint8_t unit_type = operands[1] >> 3; 243 uint8_t unit = operands[1] & 0x07; 244 uint32_t company_id = operands[2] << 16 | operands[3] << 8 | operands[4]; 245 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, 246 ctype, subunit_type, subunit_id, opcode, unit_type, unit, company_id ); 247 break; 248 } 249 case AVRCP_CMD_OPCODE_VENDOR_DEPENDENT: 250 if (size - pos < 7) { 251 log_error("avrcp: wrong packet size"); 252 return; 253 }; 254 // operands: 255 memcpy(operands, packet+pos, 7); 256 pos += 7; 257 // uint32_t company_id = operands[0] << 16 | operands[1] << 8 | operands[2]; 258 pdu_id = operands[3]; 259 260 if (connection->state != AVCTP_W2_RECEIVE_RESPONSE && pdu_id != AVRCP_PDU_ID_REGISTER_NOTIFICATION){ 261 log_info("AVRCP_CMD_OPCODE_VENDOR_DEPENDENT state %d", connection->state); 262 return; 263 } 264 connection->state = AVCTP_CONNECTION_OPENED; 265 266 267 // uint8_t unit_type = operands[4] >> 3; 268 // uint8_t unit = operands[4] & 0x07; 269 param_length = big_endian_read_16(operands, 5); 270 271 // 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", 272 // ctype, subunit_type, subunit_id, opcode, unit_type, unit, company_id ); 273 274 // if (ctype == AVRCP_CTYPE_RESPONSE_INTERIM) return; 275 log_info(" VENDOR DEPENDENT response: pdu id 0x%02x, param_length %d, status %s", pdu_id, param_length, avrcp_ctype2str(ctype)); 276 switch (pdu_id){ 277 case AVRCP_PDU_ID_GetCurrentPlayerApplicationSettingValue:{ 278 uint8_t num_attributes = packet[pos++]; 279 int i; 280 avrcp_repeat_mode_t repeat_mode = AVRCP_REPEAT_MODE_INVALID; 281 avrcp_shuffle_mode_t shuffle_mode = AVRCP_SHUFFLE_MODE_INVALID; 282 for (i = 0; i < num_attributes; i++){ 283 uint8_t attribute_id = packet[pos++]; 284 uint8_t value = packet[pos++]; 285 switch (attribute_id){ 286 case 0x02: 287 repeat_mode = (avrcp_repeat_mode_t) value; 288 break; 289 case 0x03: 290 shuffle_mode = (avrcp_shuffle_mode_t) value; 291 break; 292 default: 293 break; 294 } 295 } 296 avrcp_emit_repeat_and_shuffle_mode(avrcp_controller_context.avrcp_callback, connection->avrcp_cid, ctype, repeat_mode, shuffle_mode); 297 break; 298 } 299 case AVRCP_PDU_ID_SetPlayerApplicationSettingValue:{ 300 uint8_t event[6]; 301 int offset = 0; 302 event[offset++] = HCI_EVENT_AVRCP_META; 303 event[offset++] = sizeof(event) - 2; 304 event[offset++] = AVRCP_SUBEVENT_PLAYER_APPLICATION_VALUE_RESPONSE; 305 little_endian_store_16(event, offset, connection->avrcp_cid); 306 offset += 2; 307 event[offset++] = ctype; 308 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 309 break; 310 } 311 case AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME:{ 312 uint8_t event[7]; 313 int offset = 0; 314 event[offset++] = HCI_EVENT_AVRCP_META; 315 event[offset++] = sizeof(event) - 2; 316 event[offset++] = AVRCP_SUBEVENT_SET_ABSOLUTE_VOLUME_RESPONSE; 317 little_endian_store_16(event, offset, connection->avrcp_cid); 318 offset += 2; 319 event[offset++] = ctype; 320 event[offset++] = packet[pos++]; 321 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 322 break; 323 } 324 case AVRCP_PDU_ID_GET_CAPABILITIES:{ 325 avrcp_capability_id_t capability_id = (avrcp_capability_id_t) packet[pos++]; 326 uint8_t capability_count = packet[pos++]; 327 int i; 328 switch (capability_id){ 329 case AVRCP_CAPABILITY_ID_COMPANY: 330 // log_info("Supported companies %d: ", capability_count); 331 for (i = 0; i < capability_count; i++){ 332 uint32_t company_id = big_endian_read_24(packet, pos); 333 pos += 3; 334 log_info(" 0x%06" PRIx32 ", ", company_id); 335 } 336 break; 337 case AVRCP_CAPABILITY_ID_EVENT: 338 // log_info("Supported events %d: ", capability_count); 339 for (i = 0; i < capability_count; i++){ 340 uint8_t event_id = packet[pos++]; 341 log_info(" 0x%02x %s", event_id, avrcp_event2str(event_id)); 342 } 343 break; 344 } 345 break; 346 } 347 case AVRCP_PDU_ID_GET_PLAY_STATUS:{ 348 uint32_t song_length = big_endian_read_32(packet, pos); 349 pos += 4; 350 uint32_t song_position = big_endian_read_32(packet, pos); 351 pos += 4; 352 uint8_t play_status = packet[pos]; 353 // log_info(" GET_PLAY_STATUS length 0x%04X, position 0x%04X, status %s", song_length, song_position, avrcp_play_status2str(play_status)); 354 355 uint8_t event[15]; 356 int offset = 0; 357 event[offset++] = HCI_EVENT_AVRCP_META; 358 event[offset++] = sizeof(event) - 2; 359 event[offset++] = AVRCP_SUBEVENT_PLAY_STATUS; 360 little_endian_store_16(event, offset, connection->avrcp_cid); 361 offset += 2; 362 event[offset++] = ctype; 363 little_endian_store_32(event, offset, song_length); 364 offset += 4; 365 little_endian_store_32(event, offset, song_position); 366 offset += 4; 367 event[offset++] = play_status; 368 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 369 break; 370 } 371 case AVRCP_PDU_ID_REGISTER_NOTIFICATION:{ 372 avrcp_notification_event_id_t event_id = (avrcp_notification_event_id_t) packet[pos++]; 373 uint16_t event_mask = (1 << event_id); 374 uint16_t reset_event_mask = ~event_mask; 375 switch (ctype){ 376 case AVRCP_CTYPE_RESPONSE_INTERIM: 377 // register as enabled 378 connection->notifications_enabled |= event_mask; 379 // printf("INTERIM notifications_enabled 0x%2x, notifications_to_register 0x%2x\n", connection->notifications_enabled, connection->notifications_to_register); 380 break; 381 case AVRCP_CTYPE_RESPONSE_CHANGED_STABLE: 382 // received change, event is considered deregistered 383 // we are re-enabling it automatically, if it is not 384 // explicitly disabled 385 connection->notifications_enabled &= reset_event_mask; 386 if (! (connection->notifications_to_deregister & event_mask)){ 387 avrcp_register_notification(connection, event_id); 388 // printf("CHANGED_STABLE notifications_enabled 0x%2x, notifications_to_register 0x%2x\n", connection->notifications_enabled, connection->notifications_to_register); 389 } else { 390 connection->notifications_to_deregister &= reset_event_mask; 391 } 392 break; 393 default: 394 connection->notifications_to_register &= reset_event_mask; 395 connection->notifications_enabled &= reset_event_mask; 396 connection->notifications_to_deregister &= reset_event_mask; 397 break; 398 } 399 400 switch (event_id){ 401 case AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED:{ 402 uint8_t event[7]; 403 int offset = 0; 404 event[offset++] = HCI_EVENT_AVRCP_META; 405 event[offset++] = sizeof(event) - 2; 406 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_PLAYBACK_STATUS_CHANGED; 407 little_endian_store_16(event, offset, connection->avrcp_cid); 408 offset += 2; 409 event[offset++] = ctype; 410 event[offset++] = packet[pos]; 411 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 412 break; 413 } 414 case AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED:{ 415 uint8_t event[6]; 416 int offset = 0; 417 event[offset++] = HCI_EVENT_AVRCP_META; 418 event[offset++] = sizeof(event) - 2; 419 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_TRACK_CHANGED; 420 little_endian_store_16(event, offset, connection->avrcp_cid); 421 offset += 2; 422 event[offset++] = ctype; 423 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 424 break; 425 } 426 case AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED:{ 427 uint8_t event[6]; 428 int offset = 0; 429 event[offset++] = HCI_EVENT_AVRCP_META; 430 event[offset++] = sizeof(event) - 2; 431 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_NOW_PLAYING_CONTENT_CHANGED; 432 little_endian_store_16(event, offset, connection->avrcp_cid); 433 offset += 2; 434 event[offset++] = ctype; 435 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 436 break; 437 } 438 case AVRCP_NOTIFICATION_EVENT_AVAILABLE_PLAYERS_CHANGED:{ 439 uint8_t event[6]; 440 int offset = 0; 441 event[offset++] = HCI_EVENT_AVRCP_META; 442 event[offset++] = sizeof(event) - 2; 443 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_AVAILABLE_PLAYERS_CHANGED; 444 little_endian_store_16(event, offset, connection->avrcp_cid); 445 offset += 2; 446 event[offset++] = ctype; 447 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 448 break; 449 } 450 case AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED:{ 451 uint8_t event[7]; 452 int offset = 0; 453 event[offset++] = HCI_EVENT_AVRCP_META; 454 event[offset++] = sizeof(event) - 2; 455 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED; 456 little_endian_store_16(event, offset, connection->avrcp_cid); 457 offset += 2; 458 event[offset++] = ctype; 459 event[offset++] = packet[pos++] & 0x7F; 460 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 461 break; 462 } 463 // case AVRCP_NOTIFICATION_EVENT_PLAYER_APPLICATION_SETTING_CHANGED:{ 464 // uint8_t num_PlayerApplicationSettingAttributes = packet[pos++]; 465 // int i; 466 // for (i = 0; i < num_PlayerApplicationSettingAttributes; i++){ 467 // uint8_t PlayerApplicationSetting_AttributeID = packet[pos++]; 468 // uint8_t PlayerApplicationSettingValueID = packet[pos++]; 469 // } 470 // break; 471 // } 472 // case AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED: 473 // uint16_t player_id = big_endian_read_16(packet, pos); 474 // pos += 2; 475 // uint16_t uid_counter = big_endian_read_16(packet, pos); 476 // pos += 2; 477 // break; 478 // case AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED: 479 // uint16_t uid_counter = big_endian_read_16(packet, pos); 480 // pos += 2; 481 // break; 482 default: 483 log_info("avrcp: not implemented"); 484 break; 485 } 486 if (connection->notifications_to_register != 0){ 487 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 488 } 489 break; 490 } 491 492 case AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES:{ 493 uint8_t num_attributes = packet[pos++]; 494 unsigned int i; 495 struct item { 496 uint16_t len; 497 uint8_t * value; 498 } items[AVRCP_MEDIA_ATTR_COUNT]; 499 memset(items, 0, sizeof(items)); 500 501 uint16_t string_attributes_len = 0; 502 uint8_t num_string_attributes = 0; 503 uint16_t total_event_payload_for_string_attributes = HCI_EVENT_PAYLOAD_SIZE-2; 504 uint16_t max_string_attribute_value_len = 0; 505 if (ctype == AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE || ctype == AVRCP_CTYPE_RESPONSE_CHANGED_STABLE){ 506 for (i = 0; i < num_attributes; i++){ 507 // use local variables to avoid compiler warning 508 uint32_t avrcp_media_attribute_id = big_endian_read_32(packet, pos); 509 avrcp_media_attribute_id_t attr_id = (avrcp_media_attribute_id_t) avrcp_media_attribute_id; 510 pos += 4; 511 // uint16_t character_set = big_endian_read_16(packet, pos); 512 pos += 2; 513 uint16_t attr_value_length = big_endian_read_16(packet, pos); 514 pos += 2; 515 516 // debug - to remove later 517 uint8_t value[100]; 518 uint16_t value_len = sizeof(value) <= attr_value_length? sizeof(value) - 1 : attr_value_length; 519 memcpy(value, packet+pos, value_len); 520 value[value_len] = 0; 521 // printf("Now Playing Info %s: %s \n", attribute2str(attr_id), value); 522 // end debug 523 524 if ((attr_id >= 1) || (attr_id <= AVRCP_MEDIA_ATTR_COUNT)) { 525 items[attr_id-1].len = attr_value_length; 526 items[attr_id-1].value = &packet[pos]; 527 switch (attr_id){ 528 case AVRCP_MEDIA_ATTR_TITLE: 529 case AVRCP_MEDIA_ATTR_ARTIST: 530 case AVRCP_MEDIA_ATTR_ALBUM: 531 case AVRCP_MEDIA_ATTR_GENRE: 532 num_string_attributes++; 533 string_attributes_len += attr_value_length; 534 if (max_string_attribute_value_len < attr_value_length){ 535 max_string_attribute_value_len = attr_value_length; 536 } 537 break; 538 default: 539 break; 540 } 541 } 542 pos += attr_value_length; 543 } 544 } 545 546 // subtract space for fixed fields 547 total_event_payload_for_string_attributes -= 14 + 4; // 4 for '\0' 548 549 // @TODO optimize space by repeatedly decreasing max_string_attribute_value_len until it fits into buffer instead of crude divion 550 uint16_t max_value_len = total_event_payload_for_string_attributes > string_attributes_len? max_string_attribute_value_len : total_event_payload_for_string_attributes/(string_attributes_len+1) - 1; 551 // printf("num_string_attributes %d, string_attributes_len %d, total_event_payload_for_string_attributes %d, max_value_len %d \n", num_string_attributes, string_attributes_len, total_event_payload_for_string_attributes, max_value_len); 552 553 const uint8_t attribute_order[] = { 554 AVRCP_MEDIA_ATTR_TRACK, 555 AVRCP_MEDIA_ATTR_TOTAL_TRACKS, 556 AVRCP_MEDIA_ATTR_SONG_LENGTH, 557 AVRCP_MEDIA_ATTR_TITLE, 558 AVRCP_MEDIA_ATTR_ARTIST, 559 AVRCP_MEDIA_ATTR_ALBUM, 560 AVRCP_MEDIA_ATTR_GENRE 561 }; 562 563 uint8_t event[HCI_EVENT_BUFFER_SIZE]; 564 event[0] = HCI_EVENT_AVRCP_META; 565 pos = 2; 566 event[pos++] = AVRCP_SUBEVENT_NOW_PLAYING_INFO; 567 little_endian_store_16(event, pos, connection->avrcp_cid); 568 pos += 2; 569 event[pos++] = ctype; 570 for (i = 0; i < sizeof(attribute_order); i++){ 571 avrcp_media_attribute_id_t attr_id = (avrcp_media_attribute_id_t) attribute_order[i]; 572 uint16_t value_len = 0; 573 switch (attr_id){ 574 case AVRCP_MEDIA_ATTR_TITLE: 575 case AVRCP_MEDIA_ATTR_ARTIST: 576 case AVRCP_MEDIA_ATTR_ALBUM: 577 case AVRCP_MEDIA_ATTR_GENRE: 578 if (items[attr_id-1].value){ 579 value_len = items[attr_id-1].len <= max_value_len ? items[attr_id-1].len : max_value_len; 580 } 581 event[pos++] = value_len + 1; 582 if (value_len){ 583 memcpy(event+pos, items[attr_id-1].value, value_len); 584 pos += value_len; 585 } 586 event[pos++] = 0; 587 break; 588 case AVRCP_MEDIA_ATTR_SONG_LENGTH: 589 if (items[attr_id-1].value){ 590 little_endian_store_32(event, pos, btstack_atoi((char *)items[attr_id-1].value)); 591 } else { 592 little_endian_store_32(event, pos, 0); 593 } 594 pos += 4; 595 break; 596 case AVRCP_MEDIA_ATTR_TRACK: 597 case AVRCP_MEDIA_ATTR_TOTAL_TRACKS: 598 if (items[attr_id-1].value){ 599 event[pos++] = btstack_atoi((char *)items[attr_id-1].value); 600 } else { 601 event[pos++] = 0; 602 } 603 break; 604 default: 605 break; 606 } 607 } 608 event[1] = pos - 2; 609 // printf_hexdump(event, pos); 610 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, pos); 611 break; 612 } 613 default: 614 break; 615 } 616 break; 617 case AVRCP_CMD_OPCODE_PASS_THROUGH:{ 618 // 0x80 | connection->cmd_operands[0] 619 uint8_t operation_id = packet[pos++]; 620 switch (connection->state){ 621 case AVCTP_W2_RECEIVE_PRESS_RESPONSE: 622 if (connection->continuous_fast_forward_cmd){ 623 connection->state = AVCTP_W4_STOP; 624 } else { 625 connection->state = AVCTP_W2_SEND_RELEASE_COMMAND; 626 } 627 break; 628 case AVCTP_W2_RECEIVE_RESPONSE: 629 connection->state = AVCTP_CONNECTION_OPENED; 630 break; 631 default: 632 // check for notifications? move state transition down 633 // log_info("AVRCP_CMD_OPCODE_PASS_THROUGH state %d\n", connection->state); 634 break; 635 } 636 if (connection->state == AVCTP_W4_STOP){ 637 avrcp_emit_operation_status(avrcp_controller_context.avrcp_callback, AVRCP_SUBEVENT_OPERATION_START, connection->avrcp_cid, ctype, operation_id); 638 } 639 if (connection->state == AVCTP_CONNECTION_OPENED) { 640 // RELEASE response 641 operation_id = operation_id & 0x7F; 642 avrcp_emit_operation_status(avrcp_controller_context.avrcp_callback, AVRCP_SUBEVENT_OPERATION_COMPLETE, connection->avrcp_cid, ctype, operation_id); 643 } 644 if (connection->state == AVCTP_W2_SEND_RELEASE_COMMAND){ 645 // PRESS response 646 request_pass_through_release_control_cmd(connection); 647 } 648 break; 649 } 650 default: 651 break; 652 } 653 } 654 655 static void avrcp_controller_handle_can_send_now(avrcp_connection_t * connection){ 656 int i; 657 switch (connection->state){ 658 case AVCTP_W2_SEND_PRESS_COMMAND: 659 connection->state = AVCTP_W2_RECEIVE_PRESS_RESPONSE; 660 avrcp_send_cmd(connection->l2cap_signaling_cid, connection); 661 break; 662 case AVCTP_W2_SEND_COMMAND: 663 case AVCTP_W2_SEND_RELEASE_COMMAND: 664 connection->state = AVCTP_W2_RECEIVE_RESPONSE; 665 avrcp_send_cmd(connection->l2cap_signaling_cid, connection); 666 break; 667 case AVCTP_CONNECTION_OPENED: 668 if (connection->notifications_to_register != 0){ 669 for (i = 1; i <= AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED; i++){ 670 if (connection->notifications_to_register & (1<<i)){ 671 connection->notifications_to_register &= ~ (1 << i); 672 avrcp_prepare_notification(connection, (avrcp_notification_event_id_t) i); 673 connection->state = AVCTP_W2_RECEIVE_RESPONSE; 674 avrcp_send_cmd(connection->l2cap_signaling_cid, connection); 675 return; 676 } 677 } 678 } 679 return; 680 default: 681 return; 682 } 683 } 684 685 static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 686 avrcp_connection_t * connection; 687 688 switch (packet_type) { 689 case L2CAP_DATA_PACKET: 690 connection = get_avrcp_connection_for_l2cap_signaling_cid(channel, &avrcp_controller_context); 691 if (!connection) break; 692 avrcp_handle_l2cap_data_packet_for_signaling_connection(connection, packet, size); 693 break; 694 case HCI_EVENT_PACKET: 695 switch (hci_event_packet_get_type(packet)){ 696 case L2CAP_EVENT_CAN_SEND_NOW: 697 connection = get_avrcp_connection_for_l2cap_signaling_cid(channel, &avrcp_controller_context); 698 if (!connection) break; 699 avrcp_controller_handle_can_send_now(connection); 700 break; 701 default: 702 avrcp_packet_handler(packet_type, channel, packet, size, &avrcp_controller_context); 703 break; 704 } 705 default: 706 break; 707 } 708 } 709 710 void avrcp_controller_init(void){ 711 avrcp_controller_context.role = AVRCP_CONTROLLER; 712 avrcp_controller_context.connections = NULL; 713 avrcp_controller_context.packet_handler = avrcp_controller_packet_handler; 714 l2cap_register_service(&avrcp_controller_packet_handler, BLUETOOTH_PROTOCOL_AVCTP, 0xffff, LEVEL_0); 715 } 716 717 void avrcp_controller_register_packet_handler(btstack_packet_handler_t callback){ 718 if (callback == NULL){ 719 log_error("avrcp_register_packet_handler called with NULL callback"); 720 return; 721 } 722 avrcp_controller_context.avrcp_callback = callback; 723 } 724 725 uint8_t avrcp_controller_connect(bd_addr_t bd_addr, uint16_t * avrcp_cid){ 726 return avrcp_connect(bd_addr, &avrcp_controller_context, avrcp_cid); 727 } 728 729 uint8_t avrcp_controller_unit_info(uint16_t avrcp_cid){ 730 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 731 if (!connection){ 732 log_error("avrcp_unit_info: could not find a connection."); 733 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 734 } 735 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 736 connection->state = AVCTP_W2_SEND_COMMAND; 737 738 connection->transaction_label++; 739 connection->command_opcode = AVRCP_CMD_OPCODE_UNIT_INFO; 740 connection->command_type = AVRCP_CTYPE_STATUS; 741 connection->subunit_type = AVRCP_SUBUNIT_TYPE_UNIT; //vendor unique 742 connection->subunit_id = AVRCP_SUBUNIT_ID_IGNORE; 743 memset(connection->cmd_operands, 0xFF, connection->cmd_operands_length); 744 connection->cmd_operands_length = 5; 745 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 746 return ERROR_CODE_SUCCESS; 747 } 748 749 static uint8_t avrcp_controller_get_capabilities(uint16_t avrcp_cid, uint8_t capability_id){ 750 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 751 if (!connection){ 752 log_error("avrcp_get_capabilities: could not find a connection."); 753 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 754 } 755 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 756 connection->state = AVCTP_W2_SEND_COMMAND; 757 758 connection->transaction_label++; 759 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 760 connection->command_type = AVRCP_CTYPE_STATUS; 761 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 762 connection->subunit_id = AVRCP_SUBUNIT_ID; 763 big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID); 764 connection->cmd_operands[3] = AVRCP_PDU_ID_GET_CAPABILITIES; // PDU ID 765 connection->cmd_operands[4] = 0; 766 big_endian_store_16(connection->cmd_operands, 5, 1); // parameter length 767 connection->cmd_operands[7] = capability_id; // capability ID 768 connection->cmd_operands_length = 8; 769 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 770 return ERROR_CODE_SUCCESS; 771 } 772 773 uint8_t avrcp_controller_get_supported_company_ids(uint16_t avrcp_cid){ 774 return avrcp_controller_get_capabilities(avrcp_cid, AVRCP_CAPABILITY_ID_COMPANY); 775 } 776 777 uint8_t avrcp_controller_get_supported_events(uint16_t avrcp_cid){ 778 return avrcp_controller_get_capabilities(avrcp_cid, AVRCP_CAPABILITY_ID_EVENT); 779 } 780 781 782 uint8_t avrcp_controller_play(uint16_t avrcp_cid){ 783 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PLAY, 0); 784 } 785 786 uint8_t avrcp_controller_stop(uint16_t avrcp_cid){ 787 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_STOP, 0); 788 } 789 790 uint8_t avrcp_controller_pause(uint16_t avrcp_cid){ 791 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PAUSE, 0); 792 } 793 794 uint8_t avrcp_controller_forward(uint16_t avrcp_cid){ 795 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FORWARD, 0); 796 } 797 798 uint8_t avrcp_controller_backward(uint16_t avrcp_cid){ 799 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_BACKWARD, 0); 800 } 801 802 uint8_t avrcp_controller_start_rewind(uint16_t avrcp_cid){ 803 return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_REWIND, 0); 804 } 805 806 uint8_t avrcp_controller_volume_up(uint16_t avrcp_cid){ 807 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_UP, 0); 808 } 809 810 uint8_t avrcp_controller_volume_down(uint16_t avrcp_cid){ 811 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_DOWN, 0); 812 } 813 814 uint8_t avrcp_controller_mute(uint16_t avrcp_cid){ 815 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_MUTE, 0); 816 } 817 818 uint8_t avrcp_controller_skip(uint16_t avrcp_cid){ 819 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_SKIP, 0); 820 } 821 822 uint8_t avrcp_controller_stop_rewind(uint16_t avrcp_cid){ 823 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 824 if (!connection){ 825 log_error("avrcp_stop_rewind: could not find a connection."); 826 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 827 } 828 if (connection->state != AVCTP_W4_STOP) return ERROR_CODE_COMMAND_DISALLOWED; 829 return request_pass_through_release_control_cmd(connection); 830 } 831 832 uint8_t avrcp_controller_start_fast_forward(uint16_t avrcp_cid){ 833 return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FAST_FORWARD, 0); 834 } 835 836 uint8_t avrcp_controller_fast_forward(uint16_t avrcp_cid){ 837 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FAST_FORWARD, 0); 838 } 839 840 uint8_t avrcp_controller_rewind(uint16_t avrcp_cid){ 841 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_REWIND, 0); 842 } 843 844 845 uint8_t avrcp_controller_stop_fast_forward(uint16_t avrcp_cid){ 846 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 847 if (!connection){ 848 log_error("avrcp_stop_fast_forward: could not find a connection."); 849 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 850 } 851 if (connection->state != AVCTP_W4_STOP) return ERROR_CODE_COMMAND_DISALLOWED; 852 return request_pass_through_release_control_cmd(connection); 853 } 854 855 uint8_t avrcp_controller_get_play_status(uint16_t avrcp_cid){ 856 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 857 if (!connection){ 858 log_error("avrcp_get_play_status: could not find a connection."); 859 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 860 } 861 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 862 connection->state = AVCTP_W2_SEND_COMMAND; 863 connection->transaction_label++; 864 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 865 connection->command_type = AVRCP_CTYPE_STATUS; 866 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 867 connection->subunit_id = AVRCP_SUBUNIT_ID; 868 big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID); 869 connection->cmd_operands[3] = AVRCP_PDU_ID_GET_PLAY_STATUS; 870 connection->cmd_operands[4] = 0; // reserved(upper 6) | packet_type -> 0 871 big_endian_store_16(connection->cmd_operands, 5, 0); // parameter length 872 connection->cmd_operands_length = 7; 873 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 874 return ERROR_CODE_SUCCESS; 875 } 876 877 uint8_t avrcp_controller_enable_notification(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id){ 878 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 879 if (!connection){ 880 log_error("avrcp_get_play_status: could not find a connection."); 881 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 882 } 883 avrcp_register_notification(connection, event_id); 884 return ERROR_CODE_SUCCESS; 885 } 886 887 uint8_t avrcp_controller_disable_notification(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id){ 888 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 889 if (!connection){ 890 log_error("avrcp_get_play_status: could not find a connection."); 891 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 892 } 893 connection->notifications_to_deregister |= (1 << event_id); 894 return ERROR_CODE_SUCCESS; 895 } 896 897 uint8_t avrcp_controller_get_now_playing_info(uint16_t avrcp_cid){ 898 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 899 if (!connection){ 900 log_error("avrcp_get_capabilities: could not find a connection."); 901 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 902 } 903 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 904 connection->state = AVCTP_W2_SEND_COMMAND; 905 906 connection->transaction_label++; 907 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 908 connection->command_type = AVRCP_CTYPE_STATUS; 909 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 910 connection->subunit_id = AVRCP_SUBUNIT_ID; 911 int pos = 0; 912 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 913 pos += 3; 914 connection->cmd_operands[pos++] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES; // PDU ID 915 connection->cmd_operands[pos++] = 0; 916 917 // Parameter Length 918 big_endian_store_16(connection->cmd_operands, pos, 9); 919 pos += 2; 920 921 // write 8 bytes value 922 memset(connection->cmd_operands + pos, 0, 8); // identifier: PLAYING 923 pos += 8; 924 925 connection->cmd_operands[pos++] = 0; // attribute count, if 0 get all attributes 926 // every attribute is 4 bytes long 927 928 connection->cmd_operands_length = pos; 929 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 930 return ERROR_CODE_SUCCESS; 931 } 932 933 uint8_t avrcp_controller_set_absolute_volume(uint16_t avrcp_cid, uint8_t volume){ 934 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 935 if (!connection){ 936 log_error("avrcp_get_capabilities: could not find a connection."); 937 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 938 } 939 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 940 connection->state = AVCTP_W2_SEND_COMMAND; 941 942 connection->transaction_label++; 943 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 944 connection->command_type = AVRCP_CTYPE_CONTROL; 945 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 946 connection->subunit_id = AVRCP_SUBUNIT_ID; 947 int pos = 0; 948 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 949 pos += 3; 950 connection->cmd_operands[pos++] = AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME; // PDU ID 951 connection->cmd_operands[pos++] = 0; 952 953 // Parameter Length 954 big_endian_store_16(connection->cmd_operands, pos, 1); 955 pos += 2; 956 connection->cmd_operands[pos++] = volume; 957 958 connection->cmd_operands_length = pos; 959 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 960 return ERROR_CODE_SUCCESS; 961 } 962 963 uint8_t avrcp_controller_query_shuffle_and_repeat_modes(uint16_t avrcp_cid){ 964 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 965 if (!connection){ 966 log_error("avrcp_get_capabilities: could not find a connection."); 967 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 968 } 969 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 970 connection->state = AVCTP_W2_SEND_COMMAND; 971 972 connection->transaction_label++; 973 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 974 connection->command_type = AVRCP_CTYPE_STATUS; 975 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 976 connection->subunit_id = AVRCP_SUBUNIT_ID; 977 big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID); 978 connection->cmd_operands[3] = AVRCP_PDU_ID_GetCurrentPlayerApplicationSettingValue; // PDU ID 979 connection->cmd_operands[4] = 0; 980 big_endian_store_16(connection->cmd_operands, 5, 5); // parameter length 981 connection->cmd_operands[7] = 4; // NumPlayerApplicationSettingAttributeID 982 // PlayerApplicationSettingAttributeID1 AVRCP Spec, Appendix F, 133 983 connection->cmd_operands[8] = 0x01; // equalizer (1-OFF, 2-ON) 984 connection->cmd_operands[9] = 0x02; // repeat (1-off, 2-single track, 3-all tracks, 4-group repeat) 985 connection->cmd_operands[10] = 0x03; // shuffle (1-off, 2-all tracks, 3-group shuffle) 986 connection->cmd_operands[11] = 0x04; // scan (1-off, 2-all tracks, 3-group scan) 987 connection->cmd_operands_length = 12; 988 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 989 return ERROR_CODE_SUCCESS; 990 } 991 992 static uint8_t avrcp_controller_set_current_player_application_setting_value(uint16_t avrcp_cid, uint8_t attr_id, uint8_t attr_value){ 993 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 994 if (!connection){ 995 log_error("avrcp_get_capabilities: could not find a connection."); 996 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 997 } 998 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 999 connection->state = AVCTP_W2_SEND_COMMAND; 1000 1001 connection->transaction_label++; 1002 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1003 connection->command_type = AVRCP_CTYPE_CONTROL; 1004 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1005 connection->subunit_id = AVRCP_SUBUNIT_ID; 1006 int pos = 0; 1007 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 1008 pos += 3; 1009 connection->cmd_operands[pos++] = AVRCP_PDU_ID_SetPlayerApplicationSettingValue; // PDU ID 1010 connection->cmd_operands[pos++] = 0; 1011 // Parameter Length 1012 big_endian_store_16(connection->cmd_operands, pos, 3); 1013 pos += 2; 1014 connection->cmd_operands[pos++] = 2; 1015 connection->cmd_operands_length = pos; 1016 connection->cmd_operands[pos++] = attr_id; 1017 connection->cmd_operands[pos++] = attr_value; 1018 connection->cmd_operands_length = pos; 1019 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1020 return ERROR_CODE_SUCCESS; 1021 } 1022 1023 uint8_t avrcp_controller_set_shuffle_mode(uint16_t avrcp_cid, avrcp_shuffle_mode_t mode){ 1024 if (mode < AVRCP_SHUFFLE_MODE_OFF || mode > AVRCP_SHUFFLE_MODE_GROUP) return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; 1025 return avrcp_controller_set_current_player_application_setting_value(avrcp_cid, 0x03, mode); 1026 } 1027 1028 uint8_t avrcp_controller_set_repeat_mode(uint16_t avrcp_cid, avrcp_repeat_mode_t mode){ 1029 if (mode < AVRCP_REPEAT_MODE_OFF || mode > AVRCP_REPEAT_MODE_GROUP) return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; 1030 return avrcp_controller_set_current_player_application_setting_value(avrcp_cid, 0x02, mode); 1031 } 1032 1033 uint8_t avrcp_controller_disconnect(uint16_t avrcp_cid){ 1034 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 1035 if (!connection){ 1036 log_error("avrcp_get_capabilities: could not find a connection."); 1037 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1038 } 1039 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1040 l2cap_disconnect(connection->l2cap_signaling_cid, 0); 1041 return ERROR_CODE_SUCCESS; 1042 }