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 } 605 } 606 event[1] = pos - 2; 607 // printf_hexdump(event, pos); 608 (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, pos); 609 break; 610 } 611 default: 612 break; 613 } 614 break; 615 case AVRCP_CMD_OPCODE_PASS_THROUGH:{ 616 // 0x80 | connection->cmd_operands[0] 617 uint8_t operation_id = packet[pos++]; 618 switch (connection->state){ 619 case AVCTP_W2_RECEIVE_PRESS_RESPONSE: 620 if (connection->continuous_fast_forward_cmd){ 621 connection->state = AVCTP_W4_STOP; 622 } else { 623 connection->state = AVCTP_W2_SEND_RELEASE_COMMAND; 624 } 625 break; 626 case AVCTP_W2_RECEIVE_RESPONSE: 627 connection->state = AVCTP_CONNECTION_OPENED; 628 break; 629 default: 630 // check for notifications? move state transition down 631 // log_info("AVRCP_CMD_OPCODE_PASS_THROUGH state %d\n", connection->state); 632 break; 633 } 634 if (connection->state == AVCTP_W4_STOP){ 635 avrcp_emit_operation_status(avrcp_controller_context.avrcp_callback, AVRCP_SUBEVENT_OPERATION_START, connection->avrcp_cid, ctype, operation_id); 636 } 637 if (connection->state == AVCTP_CONNECTION_OPENED) { 638 // RELEASE response 639 operation_id = operation_id & 0x7F; 640 avrcp_emit_operation_status(avrcp_controller_context.avrcp_callback, AVRCP_SUBEVENT_OPERATION_COMPLETE, connection->avrcp_cid, ctype, operation_id); 641 } 642 if (connection->state == AVCTP_W2_SEND_RELEASE_COMMAND){ 643 // PRESS response 644 request_pass_through_release_control_cmd(connection); 645 } 646 break; 647 } 648 default: 649 break; 650 } 651 } 652 653 static void avrcp_controller_handle_can_send_now(avrcp_connection_t * connection){ 654 int i; 655 switch (connection->state){ 656 case AVCTP_W2_SEND_PRESS_COMMAND: 657 connection->state = AVCTP_W2_RECEIVE_PRESS_RESPONSE; 658 avrcp_send_cmd(connection->l2cap_signaling_cid, connection); 659 break; 660 case AVCTP_W2_SEND_COMMAND: 661 case AVCTP_W2_SEND_RELEASE_COMMAND: 662 connection->state = AVCTP_W2_RECEIVE_RESPONSE; 663 avrcp_send_cmd(connection->l2cap_signaling_cid, connection); 664 break; 665 case AVCTP_CONNECTION_OPENED: 666 if (connection->notifications_to_register != 0){ 667 for (i = 1; i <= AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED; i++){ 668 if (connection->notifications_to_register & (1<<i)){ 669 connection->notifications_to_register &= ~ (1 << i); 670 avrcp_prepare_notification(connection, (avrcp_notification_event_id_t) i); 671 connection->state = AVCTP_W2_RECEIVE_RESPONSE; 672 avrcp_send_cmd(connection->l2cap_signaling_cid, connection); 673 return; 674 } 675 } 676 } 677 return; 678 default: 679 return; 680 } 681 } 682 683 static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 684 avrcp_connection_t * connection; 685 686 switch (packet_type) { 687 case L2CAP_DATA_PACKET: 688 connection = get_avrcp_connection_for_l2cap_signaling_cid(channel, &avrcp_controller_context); 689 if (!connection) break; 690 avrcp_handle_l2cap_data_packet_for_signaling_connection(connection, packet, size); 691 break; 692 case HCI_EVENT_PACKET: 693 switch (hci_event_packet_get_type(packet)){ 694 case L2CAP_EVENT_CAN_SEND_NOW: 695 connection = get_avrcp_connection_for_l2cap_signaling_cid(channel, &avrcp_controller_context); 696 if (!connection) break; 697 avrcp_controller_handle_can_send_now(connection); 698 break; 699 default: 700 avrcp_packet_handler(packet_type, channel, packet, size, &avrcp_controller_context); 701 break; 702 } 703 default: 704 break; 705 } 706 } 707 708 void avrcp_controller_init(void){ 709 avrcp_controller_context.role = AVRCP_CONTROLLER; 710 avrcp_controller_context.connections = NULL; 711 avrcp_controller_context.packet_handler = avrcp_controller_packet_handler; 712 l2cap_register_service(&avrcp_controller_packet_handler, BLUETOOTH_PROTOCOL_AVCTP, 0xffff, LEVEL_0); 713 } 714 715 void avrcp_controller_register_packet_handler(btstack_packet_handler_t callback){ 716 if (callback == NULL){ 717 log_error("avrcp_register_packet_handler called with NULL callback"); 718 return; 719 } 720 avrcp_controller_context.avrcp_callback = callback; 721 } 722 723 uint8_t avrcp_controller_connect(bd_addr_t bd_addr, uint16_t * avrcp_cid){ 724 return avrcp_connect(bd_addr, &avrcp_controller_context, avrcp_cid); 725 } 726 727 uint8_t avrcp_controller_unit_info(uint16_t avrcp_cid){ 728 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 729 if (!connection){ 730 log_error("avrcp_unit_info: could not find a connection."); 731 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 732 } 733 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 734 connection->state = AVCTP_W2_SEND_COMMAND; 735 736 connection->transaction_label++; 737 connection->command_opcode = AVRCP_CMD_OPCODE_UNIT_INFO; 738 connection->command_type = AVRCP_CTYPE_STATUS; 739 connection->subunit_type = AVRCP_SUBUNIT_TYPE_UNIT; //vendor unique 740 connection->subunit_id = AVRCP_SUBUNIT_ID_IGNORE; 741 memset(connection->cmd_operands, 0xFF, connection->cmd_operands_length); 742 connection->cmd_operands_length = 5; 743 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 744 return ERROR_CODE_SUCCESS; 745 } 746 747 static uint8_t avrcp_controller_get_capabilities(uint16_t avrcp_cid, uint8_t capability_id){ 748 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 749 if (!connection){ 750 log_error("avrcp_get_capabilities: could not find a connection."); 751 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 752 } 753 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 754 connection->state = AVCTP_W2_SEND_COMMAND; 755 756 connection->transaction_label++; 757 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 758 connection->command_type = AVRCP_CTYPE_STATUS; 759 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 760 connection->subunit_id = AVRCP_SUBUNIT_ID; 761 big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID); 762 connection->cmd_operands[3] = AVRCP_PDU_ID_GET_CAPABILITIES; // PDU ID 763 connection->cmd_operands[4] = 0; 764 big_endian_store_16(connection->cmd_operands, 5, 1); // parameter length 765 connection->cmd_operands[7] = capability_id; // capability ID 766 connection->cmd_operands_length = 8; 767 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 768 return ERROR_CODE_SUCCESS; 769 } 770 771 uint8_t avrcp_controller_get_supported_company_ids(uint16_t avrcp_cid){ 772 return avrcp_controller_get_capabilities(avrcp_cid, AVRCP_CAPABILITY_ID_COMPANY); 773 } 774 775 uint8_t avrcp_controller_get_supported_events(uint16_t avrcp_cid){ 776 return avrcp_controller_get_capabilities(avrcp_cid, AVRCP_CAPABILITY_ID_EVENT); 777 } 778 779 780 uint8_t avrcp_controller_play(uint16_t avrcp_cid){ 781 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PLAY, 0); 782 } 783 784 uint8_t avrcp_controller_stop(uint16_t avrcp_cid){ 785 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_STOP, 0); 786 } 787 788 uint8_t avrcp_controller_pause(uint16_t avrcp_cid){ 789 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PAUSE, 0); 790 } 791 792 uint8_t avrcp_controller_forward(uint16_t avrcp_cid){ 793 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FORWARD, 0); 794 } 795 796 uint8_t avrcp_controller_backward(uint16_t avrcp_cid){ 797 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_BACKWARD, 0); 798 } 799 800 uint8_t avrcp_controller_start_rewind(uint16_t avrcp_cid){ 801 return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_REWIND, 0); 802 } 803 804 uint8_t avrcp_controller_volume_up(uint16_t avrcp_cid){ 805 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_UP, 0); 806 } 807 808 uint8_t avrcp_controller_volume_down(uint16_t avrcp_cid){ 809 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_DOWN, 0); 810 } 811 812 uint8_t avrcp_controller_mute(uint16_t avrcp_cid){ 813 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_MUTE, 0); 814 } 815 816 uint8_t avrcp_controller_skip(uint16_t avrcp_cid){ 817 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_SKIP, 0); 818 } 819 820 uint8_t avrcp_controller_stop_rewind(uint16_t avrcp_cid){ 821 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 822 if (!connection){ 823 log_error("avrcp_stop_rewind: could not find a connection."); 824 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 825 } 826 if (connection->state != AVCTP_W4_STOP) return ERROR_CODE_COMMAND_DISALLOWED; 827 return request_pass_through_release_control_cmd(connection); 828 } 829 830 uint8_t avrcp_controller_start_fast_forward(uint16_t avrcp_cid){ 831 return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FAST_FORWARD, 0); 832 } 833 834 uint8_t avrcp_controller_fast_forward(uint16_t avrcp_cid){ 835 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FAST_FORWARD, 0); 836 } 837 838 uint8_t avrcp_controller_rewind(uint16_t avrcp_cid){ 839 return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_REWIND, 0); 840 } 841 842 843 uint8_t avrcp_controller_stop_fast_forward(uint16_t avrcp_cid){ 844 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 845 if (!connection){ 846 log_error("avrcp_stop_fast_forward: could not find a connection."); 847 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 848 } 849 if (connection->state != AVCTP_W4_STOP) return ERROR_CODE_COMMAND_DISALLOWED; 850 return request_pass_through_release_control_cmd(connection); 851 } 852 853 uint8_t avrcp_controller_get_play_status(uint16_t avrcp_cid){ 854 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 855 if (!connection){ 856 log_error("avrcp_get_play_status: could not find a connection."); 857 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 858 } 859 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 860 connection->state = AVCTP_W2_SEND_COMMAND; 861 connection->transaction_label++; 862 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 863 connection->command_type = AVRCP_CTYPE_STATUS; 864 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 865 connection->subunit_id = AVRCP_SUBUNIT_ID; 866 big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID); 867 connection->cmd_operands[3] = AVRCP_PDU_ID_GET_PLAY_STATUS; 868 connection->cmd_operands[4] = 0; // reserved(upper 6) | packet_type -> 0 869 big_endian_store_16(connection->cmd_operands, 5, 0); // parameter length 870 connection->cmd_operands_length = 7; 871 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 872 return ERROR_CODE_SUCCESS; 873 } 874 875 uint8_t avrcp_controller_enable_notification(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id){ 876 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 877 if (!connection){ 878 log_error("avrcp_get_play_status: could not find a connection."); 879 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 880 } 881 avrcp_register_notification(connection, event_id); 882 return ERROR_CODE_SUCCESS; 883 } 884 885 uint8_t avrcp_controller_disable_notification(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id){ 886 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 887 if (!connection){ 888 log_error("avrcp_get_play_status: could not find a connection."); 889 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 890 } 891 connection->notifications_to_deregister |= (1 << event_id); 892 return ERROR_CODE_SUCCESS; 893 } 894 895 uint8_t avrcp_controller_get_now_playing_info(uint16_t avrcp_cid){ 896 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 897 if (!connection){ 898 log_error("avrcp_get_capabilities: could not find a connection."); 899 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 900 } 901 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 902 connection->state = AVCTP_W2_SEND_COMMAND; 903 904 connection->transaction_label++; 905 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 906 connection->command_type = AVRCP_CTYPE_STATUS; 907 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 908 connection->subunit_id = AVRCP_SUBUNIT_ID; 909 int pos = 0; 910 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 911 pos += 3; 912 connection->cmd_operands[pos++] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES; // PDU ID 913 connection->cmd_operands[pos++] = 0; 914 915 // Parameter Length 916 big_endian_store_16(connection->cmd_operands, pos, 9); 917 pos += 2; 918 919 // write 8 bytes value 920 memset(connection->cmd_operands + pos, 0, 8); // identifier: PLAYING 921 pos += 8; 922 923 connection->cmd_operands[pos++] = 0; // attribute count, if 0 get all attributes 924 // every attribute is 4 bytes long 925 926 connection->cmd_operands_length = pos; 927 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 928 return ERROR_CODE_SUCCESS; 929 } 930 931 uint8_t avrcp_controller_set_absolute_volume(uint16_t avrcp_cid, uint8_t volume){ 932 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 933 if (!connection){ 934 log_error("avrcp_get_capabilities: could not find a connection."); 935 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 936 } 937 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 938 connection->state = AVCTP_W2_SEND_COMMAND; 939 940 connection->transaction_label++; 941 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 942 connection->command_type = AVRCP_CTYPE_CONTROL; 943 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 944 connection->subunit_id = AVRCP_SUBUNIT_ID; 945 int pos = 0; 946 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 947 pos += 3; 948 connection->cmd_operands[pos++] = AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME; // PDU ID 949 connection->cmd_operands[pos++] = 0; 950 951 // Parameter Length 952 big_endian_store_16(connection->cmd_operands, pos, 1); 953 pos += 2; 954 connection->cmd_operands[pos++] = volume; 955 956 connection->cmd_operands_length = pos; 957 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 958 return ERROR_CODE_SUCCESS; 959 } 960 961 uint8_t avrcp_controller_query_shuffle_and_repeat_modes(uint16_t avrcp_cid){ 962 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 963 if (!connection){ 964 log_error("avrcp_get_capabilities: could not find a connection."); 965 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 966 } 967 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 968 connection->state = AVCTP_W2_SEND_COMMAND; 969 970 connection->transaction_label++; 971 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 972 connection->command_type = AVRCP_CTYPE_STATUS; 973 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 974 connection->subunit_id = AVRCP_SUBUNIT_ID; 975 big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID); 976 connection->cmd_operands[3] = AVRCP_PDU_ID_GetCurrentPlayerApplicationSettingValue; // PDU ID 977 connection->cmd_operands[4] = 0; 978 big_endian_store_16(connection->cmd_operands, 5, 5); // parameter length 979 connection->cmd_operands[7] = 4; // NumPlayerApplicationSettingAttributeID 980 // PlayerApplicationSettingAttributeID1 AVRCP Spec, Appendix F, 133 981 connection->cmd_operands[8] = 0x01; // equalizer (1-OFF, 2-ON) 982 connection->cmd_operands[9] = 0x02; // repeat (1-off, 2-single track, 3-all tracks, 4-group repeat) 983 connection->cmd_operands[10] = 0x03; // shuffle (1-off, 2-all tracks, 3-group shuffle) 984 connection->cmd_operands[11] = 0x04; // scan (1-off, 2-all tracks, 3-group scan) 985 connection->cmd_operands_length = 12; 986 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 987 return ERROR_CODE_SUCCESS; 988 } 989 990 static uint8_t avrcp_controller_set_current_player_application_setting_value(uint16_t avrcp_cid, uint8_t attr_id, uint8_t attr_value){ 991 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 992 if (!connection){ 993 log_error("avrcp_get_capabilities: could not find a connection."); 994 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 995 } 996 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 997 connection->state = AVCTP_W2_SEND_COMMAND; 998 999 connection->transaction_label++; 1000 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1001 connection->command_type = AVRCP_CTYPE_CONTROL; 1002 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1003 connection->subunit_id = AVRCP_SUBUNIT_ID; 1004 int pos = 0; 1005 big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID); 1006 pos += 3; 1007 connection->cmd_operands[pos++] = AVRCP_PDU_ID_SetPlayerApplicationSettingValue; // PDU ID 1008 connection->cmd_operands[pos++] = 0; 1009 // Parameter Length 1010 big_endian_store_16(connection->cmd_operands, pos, 3); 1011 pos += 2; 1012 connection->cmd_operands[pos++] = 2; 1013 connection->cmd_operands_length = pos; 1014 connection->cmd_operands[pos++] = attr_id; 1015 connection->cmd_operands[pos++] = attr_value; 1016 connection->cmd_operands_length = pos; 1017 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1018 return ERROR_CODE_SUCCESS; 1019 } 1020 1021 uint8_t avrcp_controller_set_shuffle_mode(uint16_t avrcp_cid, avrcp_shuffle_mode_t mode){ 1022 if (mode < AVRCP_SHUFFLE_MODE_OFF || mode > AVRCP_SHUFFLE_MODE_GROUP) return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; 1023 return avrcp_controller_set_current_player_application_setting_value(avrcp_cid, 0x03, mode); 1024 } 1025 1026 uint8_t avrcp_controller_set_repeat_mode(uint16_t avrcp_cid, avrcp_repeat_mode_t mode){ 1027 if (mode < AVRCP_REPEAT_MODE_OFF || mode > AVRCP_REPEAT_MODE_GROUP) return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; 1028 return avrcp_controller_set_current_player_application_setting_value(avrcp_cid, 0x02, mode); 1029 } 1030 1031 uint8_t avrcp_controller_disconnect(uint16_t avrcp_cid){ 1032 avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context); 1033 if (!connection){ 1034 log_error("avrcp_get_capabilities: could not find a connection."); 1035 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1036 } 1037 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1038 l2cap_disconnect(connection->l2cap_signaling_cid, 0); 1039 return ERROR_CODE_SUCCESS; 1040 }