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 BLUEKITCHEN 24 * GMBH 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_target.c" 39 40 #include <stdint.h> 41 #include <stdio.h> 42 #include <string.h> 43 #include <inttypes.h> 44 45 #include "classic/avrcp.h" 46 #include "classic/avrcp_target.h" 47 48 #include "bluetooth_sdp.h" 49 #include "btstack_debug.h" 50 #include "btstack_event.h" 51 #include "btstack_util.h" 52 #include "l2cap.h" 53 54 #define AVRCP_ATTR_HEADER_LEN 8 55 56 static const uint8_t AVRCP_NOTIFICATION_TRACK_SELECTED[] = {0,0,0,0,0,0,0,0}; 57 static const uint8_t AVRCP_NOTIFICATION_TRACK_NOT_SELECTED[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; 58 59 avrcp_context_t avrcp_target_context; 60 61 static int avrcp_target_supports_browsing(uint16_t target_supported_features){ 62 return target_supported_features & AVRCP_FEATURE_MASK_BROWSING; 63 } 64 65 void avrcp_target_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint16_t supported_features, const char * service_name, const char * service_provider_name){ 66 avrcp_create_sdp_record(0, service, service_record_handle, avrcp_target_supports_browsing(supported_features), supported_features, service_name, service_provider_name); 67 } 68 69 static void 70 avrcp_target_emit_operation(btstack_packet_handler_t callback, uint16_t avrcp_cid, avrcp_operation_id_t operation_id, 71 bool button_pressed, uint8_t operands_length, uint8_t operand) { 72 btstack_assert(callback != NULL); 73 74 uint8_t event[9]; 75 int pos = 0; 76 event[pos++] = HCI_EVENT_AVRCP_META; 77 event[pos++] = sizeof(event) - 2; 78 event[pos++] = AVRCP_SUBEVENT_OPERATION; 79 little_endian_store_16(event, pos, avrcp_cid); 80 pos += 2; 81 event[pos++] = operation_id; 82 event[pos++] = button_pressed ? 1 : 0; 83 event[pos++] = operands_length; 84 event[pos++] = operand; 85 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 86 } 87 88 static void avrcp_target_emit_volume_changed(btstack_packet_handler_t callback, uint16_t avrcp_cid, uint8_t absolute_volume){ 89 btstack_assert(callback != NULL); 90 91 uint8_t event[7]; 92 int offset = 0; 93 event[offset++] = HCI_EVENT_AVRCP_META; 94 event[offset++] = sizeof(event) - 2; 95 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED; 96 little_endian_store_16(event, offset, avrcp_cid); 97 offset += 2; 98 event[offset++] = AVRCP_CTYPE_NOTIFY; 99 event[offset++] = absolute_volume; 100 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 101 } 102 103 static void avrcp_target_emit_respond_vendor_dependent_query(btstack_packet_handler_t callback, uint16_t avrcp_cid, uint8_t subevent_id){ 104 btstack_assert(callback != NULL); 105 106 uint8_t event[5]; 107 int pos = 0; 108 event[pos++] = HCI_EVENT_AVRCP_META; 109 event[pos++] = sizeof(event) - 2; 110 event[pos++] = subevent_id; 111 little_endian_store_16(event, pos, avrcp_cid); 112 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 113 } 114 115 // returns number of bytes stored 116 static uint16_t avrcp_target_pack_single_element_header(uint8_t * packet, uint16_t pos, avrcp_media_attribute_id_t attr_id, uint16_t attr_value_size){ 117 btstack_assert(attr_id >= 1); 118 btstack_assert(attr_id <= AVRCP_MEDIA_ATTR_COUNT); 119 120 big_endian_store_32(packet, pos, attr_id); 121 big_endian_store_16(packet, pos+4, RFC2978_CHARSET_MIB_UTF8); 122 big_endian_store_16(packet, pos+6, attr_value_size); 123 return 8; 124 } 125 126 // returns number of bytes stored 127 static uint16_t avrcp_target_pack_single_element_attribute_number(uint8_t * packet, uint16_t pos, avrcp_media_attribute_id_t attr_id, uint32_t value){ 128 uint16_t attr_value_length = sprintf((char *)(packet+pos+8), "%0" PRIu32, value); 129 (void) avrcp_target_pack_single_element_header(packet, pos, attr_id, attr_value_length); 130 return 8 + attr_value_length; 131 } 132 133 // returns number of bytes stored 134 static uint16_t avrcp_target_pack_single_element_attribute_string_fragment(uint8_t * packet, uint16_t pos, avrcp_media_attribute_id_t attr_id, uint8_t * attr_value, uint16_t attr_value_to_copy, uint16_t attr_value_size, bool header){ 135 if (attr_value_size == 0) return 0; 136 uint16_t bytes_stored = 0; 137 if (header){ 138 bytes_stored += avrcp_target_pack_single_element_header(packet, pos, attr_id, attr_value_size); 139 } 140 (void)memcpy(packet + pos + bytes_stored, attr_value, attr_value_to_copy); 141 bytes_stored += attr_value_to_copy; 142 return bytes_stored; 143 } 144 145 static int avrcp_target_abort_continue_response(uint16_t cid, avrcp_connection_t * connection){ 146 uint16_t pos = 0; 147 l2cap_reserve_packet_buffer(); 148 uint8_t * packet = l2cap_get_outgoing_buffer(); 149 150 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 151 connection->command_type = AVRCP_CTYPE_RESPONSE_ACCEPTED; 152 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 153 connection->subunit_id = AVRCP_SUBUNIT_ID; 154 155 packet[pos++] = (connection->transaction_id << 4) | (AVRCP_SINGLE_PACKET << 2) | (AVRCP_RESPONSE_FRAME << 1) | 0; 156 // Profile IDentifier (PID) 157 packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8; 158 packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF; 159 160 // command_type 161 packet[pos++] = connection->command_type; 162 // subunit_type | subunit ID 163 packet[pos++] = (connection->subunit_type << 3) | connection->subunit_id; 164 // opcode 165 packet[pos++] = (uint8_t)connection->command_opcode; 166 167 // company id is 3 bytes long 168 big_endian_store_24(packet, pos, BT_SIG_COMPANY_ID); 169 pos += 3; 170 171 packet[pos++] = AVRCP_PDU_ID_REQUEST_ABORT_CONTINUING_RESPONSE; 172 173 // reserve byte for packet type 174 packet[pos++] = AVRCP_SINGLE_PACKET; 175 big_endian_store_16(packet, pos, 0); 176 pos += 2; 177 return l2cap_send_prepared(cid, pos); 178 } 179 180 static int avrcp_target_send_now_playing_info(uint16_t cid, avrcp_connection_t * connection){ 181 uint16_t pos = 0; 182 l2cap_reserve_packet_buffer(); 183 uint8_t * packet = l2cap_get_outgoing_buffer(); 184 uint16_t size = l2cap_get_remote_mtu_for_local_cid(connection->l2cap_signaling_cid); 185 186 packet[pos++] = (connection->transaction_id << 4) | (AVRCP_SINGLE_PACKET << 2) | (AVRCP_RESPONSE_FRAME << 1) | 0; 187 // Profile IDentifier (PID) 188 packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8; 189 packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF; 190 191 // command_type 192 packet[pos++] = connection->command_type; 193 // subunit_type | subunit ID 194 packet[pos++] = (connection->subunit_type << 3) | connection->subunit_id; 195 // opcode 196 packet[pos++] = (uint8_t)connection->command_opcode; 197 198 // company id is 3 bytes long 199 big_endian_store_24(packet, pos, BT_SIG_COMPANY_ID); 200 pos += 3; 201 202 packet[pos++] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES; 203 204 // reserve byte for packet type 205 uint8_t pos_packet_type = pos; 206 pos++; 207 208 uint16_t playing_info_buffer_len_position = pos; 209 pos += 2; 210 if (connection->next_attr_id == AVRCP_MEDIA_ATTR_NONE){ 211 packet[pos_packet_type] = AVRCP_SINGLE_PACKET; 212 connection->packet_type = AVRCP_SINGLE_PACKET; 213 packet[pos++] = count_set_bits_uint32(connection->now_playing_info_attr_bitmap); 214 connection->next_attr_id = AVRCP_MEDIA_ATTR_ALL; 215 } 216 217 uint8_t fragmented = 0; 218 int num_free_bytes = size - pos - 2; 219 uint8_t MAX_NUMBER_ATTR_LEN = 10; 220 221 while (!fragmented && (num_free_bytes > 0) && (connection->next_attr_id <= AVRCP_MEDIA_ATTR_SONG_LENGTH_MS)){ 222 avrcp_media_attribute_id_t attr_id = connection->next_attr_id; 223 int attr_index = attr_id - 1; 224 225 if (connection->now_playing_info_attr_bitmap & (1 << attr_id)){ 226 int num_written_bytes = 0; 227 int num_bytes_to_write = 0; 228 switch (attr_id){ 229 case AVRCP_MEDIA_ATTR_ALL: 230 case AVRCP_MEDIA_ATTR_NONE: 231 break; 232 case AVRCP_MEDIA_ATTR_TRACK: 233 num_bytes_to_write = AVRCP_ATTR_HEADER_LEN + MAX_NUMBER_ATTR_LEN; 234 if (num_free_bytes >= num_bytes_to_write){ 235 num_written_bytes = avrcp_target_pack_single_element_attribute_number(packet, pos, attr_id, connection->track_nr); 236 break; 237 } 238 fragmented = 1; 239 connection->attribute_value_offset = 0; 240 break; 241 case AVRCP_MEDIA_ATTR_TOTAL_NUM_ITEMS: 242 num_bytes_to_write = AVRCP_ATTR_HEADER_LEN + MAX_NUMBER_ATTR_LEN; 243 if (num_free_bytes >= num_bytes_to_write){ 244 num_written_bytes = avrcp_target_pack_single_element_attribute_number(packet, pos, attr_id, connection->total_tracks); 245 break; 246 } 247 fragmented = 1; 248 connection->attribute_value_offset = 0; 249 break; 250 case AVRCP_MEDIA_ATTR_SONG_LENGTH_MS: 251 num_bytes_to_write = AVRCP_ATTR_HEADER_LEN + MAX_NUMBER_ATTR_LEN; 252 if (num_free_bytes >= num_bytes_to_write){ 253 num_written_bytes = avrcp_target_pack_single_element_attribute_number(packet, pos, attr_id, connection->song_length_ms); 254 break; 255 } 256 fragmented = 1; 257 connection->attribute_value_offset = 0; 258 break; 259 default:{ 260 bool header = connection->attribute_value_offset == 0; 261 uint8_t * attr_value = (uint8_t *) (connection->now_playing_info[attr_index].value + connection->attribute_value_offset); 262 uint16_t attr_value_len = connection->now_playing_info[attr_index].len - connection->attribute_value_offset; 263 264 num_bytes_to_write = attr_value_len + (header * AVRCP_ATTR_HEADER_LEN); 265 if (num_bytes_to_write <= num_free_bytes){ 266 connection->attribute_value_offset = 0; 267 num_written_bytes = num_bytes_to_write; 268 avrcp_target_pack_single_element_attribute_string_fragment(packet, pos, attr_id, attr_value, attr_value_len, connection->now_playing_info[attr_index].len, header); 269 break; 270 } 271 fragmented = 1; 272 num_written_bytes = num_free_bytes; 273 attr_value_len = num_free_bytes - (header * AVRCP_ATTR_HEADER_LEN); 274 avrcp_target_pack_single_element_attribute_string_fragment(packet, pos, attr_id, attr_value, attr_value_len, connection->now_playing_info[attr_index].len, header); 275 connection->attribute_value_offset += attr_value_len; 276 break; 277 } 278 } 279 pos += num_written_bytes; 280 num_free_bytes -= num_written_bytes; 281 } 282 if (!fragmented){ 283 // C++ compatible version of connection->next_attr_id++ 284 connection->next_attr_id = (avrcp_media_attribute_id_t) (((int) connection->next_attr_id) + 1); 285 } 286 } 287 288 if (fragmented){ 289 switch (connection->packet_type){ 290 case AVRCP_SINGLE_PACKET: 291 connection->packet_type = AVRCP_START_PACKET; 292 break; 293 default: 294 connection->packet_type = AVRCP_CONTINUE_PACKET; 295 break; 296 } 297 } else { 298 if (connection->next_attr_id >= AVRCP_MEDIA_ATTR_SONG_LENGTH_MS){ // DONE 299 if (connection->packet_type != AVRCP_SINGLE_PACKET){ 300 connection->packet_type = AVRCP_END_PACKET; 301 } 302 } 303 } 304 packet[pos_packet_type] = connection->packet_type; 305 // store attr value length 306 big_endian_store_16(packet, playing_info_buffer_len_position, pos - playing_info_buffer_len_position - 2); 307 return l2cap_send_prepared(cid, size); 308 } 309 310 311 312 static int avrcp_target_send_response(uint16_t cid, avrcp_connection_t * connection){ 313 int pos = 0; 314 l2cap_reserve_packet_buffer(); 315 uint8_t * packet = l2cap_get_outgoing_buffer(); 316 317 // transport header 318 // Transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier) 319 320 // TODO: check for fragmentation 321 connection->packet_type = AVRCP_SINGLE_PACKET; 322 323 packet[pos++] = (connection->transaction_id << 4) | (connection->packet_type << 2) | (AVRCP_RESPONSE_FRAME << 1) | 0; 324 // Profile IDentifier (PID) 325 packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8; 326 packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF; 327 // command_type 328 packet[pos++] = connection->command_type; 329 // subunit_type | subunit ID 330 packet[pos++] = (connection->subunit_type << 3) | connection->subunit_id; 331 // opcode 332 packet[pos++] = (uint8_t)connection->command_opcode; 333 334 (void)memcpy(packet + pos, connection->cmd_operands, 335 connection->cmd_operands_length); 336 pos += connection->cmd_operands_length; 337 338 return l2cap_send_prepared(cid, pos); 339 } 340 341 static void avrcp_target_response_setup(avrcp_connection_t * connection, avrcp_command_type_t command_type, avrcp_subunit_type_t subunit_type, avrcp_subunit_id_t subunit_id, 342 avrcp_command_opcode_t opcode){ 343 connection->command_type = command_type; 344 connection->subunit_type = subunit_type; 345 connection->subunit_id = subunit_id; 346 connection->command_opcode = opcode; 347 } 348 349 static uint8_t avrcp_target_response_accept(avrcp_connection_t * connection, avrcp_subunit_type_t subunit_type, avrcp_subunit_id_t subunit_id, avrcp_command_opcode_t opcode, avrcp_pdu_id_t pdu_id, uint8_t status){ 350 // AVRCP_CTYPE_RESPONSE_REJECTED 351 avrcp_target_response_setup(connection, AVRCP_CTYPE_RESPONSE_ACCEPTED, subunit_type, subunit_id, opcode); 352 // company id is 3 bytes long 353 int pos = connection->cmd_operands_length; 354 connection->cmd_operands[pos++] = pdu_id; 355 connection->cmd_operands[pos++] = 0; 356 // param length 357 big_endian_store_16(connection->cmd_operands, pos, 1); 358 pos += 2; 359 connection->cmd_operands[pos++] = status; 360 connection->cmd_operands_length = pos; 361 connection->accept_response = 1; 362 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 363 return ERROR_CODE_SUCCESS; 364 } 365 366 static uint8_t avrcp_target_response_reject(avrcp_connection_t * connection, avrcp_subunit_type_t subunit_type, avrcp_subunit_id_t subunit_id, avrcp_command_opcode_t opcode, avrcp_pdu_id_t pdu_id, avrcp_status_code_t status){ 367 // AVRCP_CTYPE_RESPONSE_REJECTED 368 avrcp_target_response_setup(connection, AVRCP_CTYPE_RESPONSE_REJECTED, subunit_type, subunit_id, opcode); 369 // company id is 3 bytes long 370 int pos = connection->cmd_operands_length; 371 connection->cmd_operands[pos++] = pdu_id; 372 connection->cmd_operands[pos++] = 0; 373 // param length 374 big_endian_store_16(connection->cmd_operands, pos, 1); 375 pos += 2; 376 connection->cmd_operands[pos++] = status; 377 connection->cmd_operands_length = pos; 378 connection->state = AVCTP_W2_SEND_RESPONSE; 379 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 380 return ERROR_CODE_SUCCESS; 381 } 382 383 static uint8_t avrcp_target_response_not_implemented(avrcp_connection_t * connection, avrcp_subunit_type_t subunit_type, avrcp_subunit_id_t subunit_id, avrcp_command_opcode_t opcode, avrcp_pdu_id_t pdu_id, uint8_t event_id){ 384 avrcp_target_response_setup(connection, AVRCP_CTYPE_RESPONSE_NOT_IMPLEMENTED, subunit_type, subunit_id, opcode); 385 // company id is 3 bytes long 386 int pos = connection->cmd_operands_length; 387 connection->cmd_operands[pos++] = pdu_id; 388 connection->cmd_operands[pos++] = 0; 389 // param length 390 big_endian_store_16(connection->cmd_operands, pos, 1); 391 pos += 2; 392 connection->cmd_operands[pos++] = event_id; 393 connection->cmd_operands_length = pos; 394 395 connection->state = AVCTP_W2_SEND_RESPONSE; 396 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 397 return ERROR_CODE_SUCCESS; 398 } 399 400 static uint8_t avrcp_target_response_vendor_dependent_interim(avrcp_connection_t * connection, avrcp_pdu_id_t pdu_id, uint8_t event_id, const uint8_t * value, uint16_t value_len){ 401 402 // company id is 3 bytes long 403 int pos = connection->cmd_operands_length; 404 connection->cmd_operands[pos++] = pdu_id; 405 connection->cmd_operands[pos++] = 0; 406 // param length 407 big_endian_store_16(connection->cmd_operands, pos, 1 + value_len); 408 pos += 2; 409 connection->cmd_operands[pos++] = event_id; 410 if (value && (value_len > 0)){ 411 (void)memcpy(connection->cmd_operands + pos, value, value_len); 412 pos += value_len; 413 } 414 connection->cmd_operands_length = pos; 415 connection->state = AVCTP_W2_SEND_RESPONSE; 416 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 417 return ERROR_CODE_SUCCESS; 418 } 419 420 static uint8_t avrcp_target_response_addressed_player_changed_interim(avrcp_connection_t * connection, avrcp_subunit_type_t subunit_type, avrcp_subunit_id_t subunit_id, avrcp_command_opcode_t opcode, avrcp_pdu_id_t pdu_id){ 421 avrcp_target_response_setup(connection, AVRCP_CTYPE_RESPONSE_INTERIM, subunit_type, subunit_id, opcode); 422 423 // company id is 3 bytes long 424 int pos = connection->cmd_operands_length; 425 connection->cmd_operands[pos++] = pdu_id; 426 connection->cmd_operands[pos++] = 0; 427 // param length 428 big_endian_store_16(connection->cmd_operands, pos, 5); 429 pos += 2; 430 connection->cmd_operands[pos++] = AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED; 431 big_endian_read_16( &connection->cmd_operands[pos], connection->addressed_player_id); 432 pos += 2; 433 big_endian_read_16( &connection->cmd_operands[pos], connection->uid_counter); 434 pos += 2; 435 436 connection->cmd_operands_length = pos; 437 connection->state = AVCTP_W2_SEND_RESPONSE; 438 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 439 return ERROR_CODE_SUCCESS; 440 } 441 442 static uint8_t avrcp_target_pass_through_response(uint16_t avrcp_cid, avrcp_command_type_t cmd_type, avrcp_operation_id_t opid, uint8_t operands_length, uint8_t operand){ 443 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 444 if (!connection){ 445 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 446 } 447 avrcp_target_response_setup(connection, cmd_type, AVRCP_SUBUNIT_TYPE_PANEL, AVRCP_SUBUNIT_ID, AVRCP_CMD_OPCODE_PASS_THROUGH); 448 449 int pos = 0; 450 connection->cmd_operands[pos++] = opid; 451 connection->cmd_operands[pos++] = operands_length; 452 if (operands_length == 1){ 453 connection->cmd_operands[pos++] = operand; 454 } 455 connection->cmd_operands_length = pos; 456 457 connection->state = AVCTP_W2_SEND_RESPONSE; 458 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 459 return ERROR_CODE_SUCCESS; 460 } 461 462 uint8_t avrcp_target_operation_rejected(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint8_t operands_length, uint8_t operand){ 463 return avrcp_target_pass_through_response(avrcp_cid, AVRCP_CTYPE_RESPONSE_REJECTED, opid, operands_length, operand); 464 } 465 466 uint8_t avrcp_target_operation_accepted(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint8_t operands_length, uint8_t operand){ 467 return avrcp_target_pass_through_response(avrcp_cid, AVRCP_CTYPE_RESPONSE_ACCEPTED, opid, operands_length, operand); 468 } 469 470 uint8_t avrcp_target_operation_not_implemented(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint8_t operands_length, uint8_t operand){ 471 return avrcp_target_pass_through_response(avrcp_cid, AVRCP_CTYPE_RESPONSE_ACCEPTED, opid, operands_length, operand); 472 } 473 474 uint8_t avrcp_target_set_unit_info(uint16_t avrcp_cid, avrcp_subunit_type_t unit_type, uint32_t company_id){ 475 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 476 if (!connection){ 477 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 478 } 479 connection->unit_type = unit_type; 480 connection->company_id = company_id; 481 return ERROR_CODE_SUCCESS; 482 } 483 484 uint8_t avrcp_target_set_subunit_info(uint16_t avrcp_cid, avrcp_subunit_type_t subunit_type, const uint8_t * subunit_info_data, uint16_t subunit_info_data_size){ 485 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 486 if (!connection){ 487 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 488 } 489 connection->subunit_info_type = subunit_type; 490 connection->subunit_info_data = subunit_info_data; 491 connection->subunit_info_data_size = subunit_info_data_size; 492 return ERROR_CODE_SUCCESS; 493 } 494 495 static uint8_t avrcp_target_unit_info(avrcp_connection_t * connection){ 496 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 497 498 uint8_t unit = 0; 499 connection->command_type = AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE; 500 connection->subunit_type = AVRCP_SUBUNIT_TYPE_UNIT; //vendor unique 501 connection->subunit_id = AVRCP_SUBUNIT_ID_IGNORE; 502 connection->command_opcode = AVRCP_CMD_OPCODE_UNIT_INFO; 503 504 connection->cmd_operands_length = 5; 505 connection->cmd_operands[0] = 0x07; 506 connection->cmd_operands[1] = (connection->unit_type << 4) | unit; 507 // company id is 3 bytes long 508 big_endian_store_32(connection->cmd_operands, 2, connection->company_id); 509 510 connection->state = AVCTP_W2_SEND_RESPONSE; 511 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 512 return ERROR_CODE_SUCCESS; 513 } 514 515 516 static uint8_t avrcp_target_subunit_info(avrcp_connection_t * connection, uint8_t offset){ 517 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 518 if (offset >= 32) return AVRCP_STATUS_INVALID_PARAMETER; 519 520 connection->command_opcode = AVRCP_CMD_OPCODE_SUBUNIT_INFO; 521 connection->command_type = AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE; 522 connection->subunit_type = AVRCP_SUBUNIT_TYPE_UNIT; //vendor unique 523 connection->subunit_id = AVRCP_SUBUNIT_ID_IGNORE; 524 525 uint8_t page = offset / 4; 526 uint8_t extension_code = 7; 527 connection->cmd_operands_length = 5; 528 connection->cmd_operands[0] = (page << 4) | extension_code; 529 530 // mark non-existent entries with 0xff 531 memset(&connection->cmd_operands[1], 0xff, 4); 532 if ((connection->subunit_info_data != NULL) && (offset < connection->subunit_info_data_size)){ 533 uint8_t bytes_to_copy = btstack_min(connection->subunit_info_data_size - offset, 4); 534 memcpy(&connection->cmd_operands[1], &connection->subunit_info_data[offset], bytes_to_copy); 535 } 536 537 connection->state = AVCTP_W2_SEND_RESPONSE; 538 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 539 return ERROR_CODE_SUCCESS; 540 } 541 542 static uint8_t avrcp_prepare_vendor_dependent_response_for_connection(avrcp_connection_t * connection, avrcp_pdu_id_t pdu_id, uint16_t param_length){ 543 if (!connection){ 544 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 545 } 546 if (connection->state != AVCTP_CONNECTION_OPENED){ 547 return ERROR_CODE_COMMAND_DISALLOWED; 548 } 549 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 550 connection->command_type = AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE; 551 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 552 connection->subunit_id = AVRCP_SUBUNIT_ID; 553 554 connection->cmd_operands[connection->cmd_operands_length++] = pdu_id; 555 // reserved 556 connection->cmd_operands[connection->cmd_operands_length++] = 0; 557 // param length 558 big_endian_store_16(connection->cmd_operands, connection->cmd_operands_length, param_length); 559 connection->cmd_operands_length += 2; 560 return ERROR_CODE_SUCCESS; 561 } 562 563 static inline uint8_t avrcp_prepare_vendor_dependent_response(uint16_t avrcp_cid, avrcp_connection_t ** out_connection, avrcp_pdu_id_t pdu_id, uint16_t param_length){ 564 *out_connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 565 if (!*out_connection){ 566 log_error("avrcp tartget: could not find a connection."); 567 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 568 } 569 return avrcp_prepare_vendor_dependent_response_for_connection(*out_connection, pdu_id, param_length); 570 } 571 572 573 static uint8_t avrcp_target_supported_events(avrcp_connection_t * connection){ 574 uint8_t num_events = 0; 575 uint8_t event_id; 576 uint8_t events[(uint8_t) AVRCP_NOTIFICATION_EVENT_LAST_INDEX]; 577 578 for (event_id = (uint8_t) AVRCP_NOTIFICATION_EVENT_FIRST_INDEX; event_id < (uint8_t) AVRCP_NOTIFICATION_EVENT_LAST_INDEX; event_id++){ 579 if ((connection->target_supported_notifications & (1<<event_id)) == 0){ 580 continue; 581 } 582 events[num_events] = event_id; 583 num_events++; 584 } 585 586 uint8_t events_size = sizeof(uint8_t) * num_events; 587 uint8_t status = avrcp_prepare_vendor_dependent_response_for_connection(connection, AVRCP_PDU_ID_GET_CAPABILITIES, 2 + events_size); 588 if (status != ERROR_CODE_SUCCESS) return status; 589 590 connection->cmd_operands[connection->cmd_operands_length++] = AVRCP_CAPABILITY_ID_EVENT; 591 connection->cmd_operands[connection->cmd_operands_length++] = num_events; 592 593 (void)memcpy(connection->cmd_operands + connection->cmd_operands_length, events, events_size); 594 connection->cmd_operands_length += events_size; 595 596 connection->state = AVCTP_W2_SEND_RESPONSE; 597 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 598 return ERROR_CODE_SUCCESS; 599 } 600 601 static uint8_t avrcp_target_supported_companies(avrcp_connection_t * connection){ 602 static uint32_t default_companies[] = { 603 0x581900 //BT SIG registered CompanyID 604 }; 605 606 uint8_t target_supported_companies_num = connection->target_supported_companies_num; 607 const uint32_t *target_supported_companies = connection->target_supported_companies; 608 609 if (connection->target_supported_companies_num == 0){ 610 target_supported_companies_num = 1; 611 target_supported_companies = default_companies; 612 } 613 614 uint16_t capabilities_size = target_supported_companies_num * 3; 615 616 uint8_t status = avrcp_prepare_vendor_dependent_response_for_connection(connection, AVRCP_PDU_ID_GET_CAPABILITIES, 2 + capabilities_size); 617 if (status != ERROR_CODE_SUCCESS) return status; 618 619 connection->cmd_operands[connection->cmd_operands_length++] = AVRCP_CAPABILITY_ID_COMPANY; 620 connection->cmd_operands[connection->cmd_operands_length++] = target_supported_companies_num; 621 622 uint8_t i; 623 for (i = 0; i < target_supported_companies_num; i++){ 624 little_endian_store_24(connection->cmd_operands, connection->cmd_operands_length, target_supported_companies[i]); 625 connection->cmd_operands_length += 3; 626 } 627 628 connection->state = AVCTP_W2_SEND_RESPONSE; 629 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 630 return ERROR_CODE_SUCCESS; 631 } 632 633 uint8_t avrcp_target_support_event(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id){ 634 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 635 if (!connection){ 636 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 637 } 638 639 if ((event_id < (uint8_t)AVRCP_NOTIFICATION_EVENT_FIRST_INDEX) || (event_id > (uint8_t)AVRCP_NOTIFICATION_EVENT_LAST_INDEX)){ 640 return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; 641 } 642 643 connection->target_supported_notifications |= (1 << (uint8_t)event_id); 644 return ERROR_CODE_SUCCESS; 645 } 646 647 uint8_t avrcp_target_support_companies(uint16_t avrcp_cid, uint8_t num_companies, const uint32_t *companies){ 648 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 649 if (!connection){ 650 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 651 } 652 653 connection->target_supported_companies_num = num_companies; 654 connection->target_supported_companies = companies; 655 return ERROR_CODE_SUCCESS; 656 } 657 658 uint8_t avrcp_target_play_status(uint16_t avrcp_cid, uint32_t song_length_ms, uint32_t song_position_ms, avrcp_playback_status_t play_status){ 659 avrcp_connection_t * connection = NULL; 660 uint8_t status = avrcp_prepare_vendor_dependent_response(avrcp_cid, &connection, AVRCP_PDU_ID_GET_PLAY_STATUS, 11); 661 if (status != ERROR_CODE_SUCCESS) return status; 662 663 big_endian_store_32(connection->cmd_operands, connection->cmd_operands_length, song_length_ms); 664 connection->cmd_operands_length += 4; 665 big_endian_store_32(connection->cmd_operands, connection->cmd_operands_length, song_position_ms); 666 connection->cmd_operands_length += 4; 667 connection->cmd_operands[connection->cmd_operands_length++] = play_status; 668 669 connection->state = AVCTP_W2_SEND_RESPONSE; 670 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 671 return ERROR_CODE_SUCCESS; 672 } 673 674 static uint8_t avrcp_target_now_playing_info(avrcp_connection_t * connection){ 675 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 676 connection->now_playing_info_response = 1; 677 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 678 connection->command_type = AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE; 679 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 680 connection->subunit_id = AVRCP_SUBUNIT_ID; 681 682 connection->state = AVCTP_W2_SEND_RESPONSE; 683 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 684 return ERROR_CODE_SUCCESS; 685 } 686 687 static uint8_t avrcp_target_store_media_attr(avrcp_connection_t * connection, avrcp_media_attribute_id_t attr_id, const char * value){ 688 int index = attr_id - 1; 689 if (!value) return AVRCP_STATUS_INVALID_PARAMETER; 690 connection->now_playing_info[index].value = (uint8_t*)value; 691 connection->now_playing_info[index].len = strlen(value); 692 return ERROR_CODE_SUCCESS; 693 } 694 695 uint8_t avrcp_target_set_playback_status(uint16_t avrcp_cid, avrcp_playback_status_t playback_status){ 696 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 697 if (!connection){ 698 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 699 } 700 if (connection->playback_status == playback_status){ 701 return ERROR_CODE_SUCCESS; 702 } 703 704 connection->playback_status = playback_status; 705 if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED)) { 706 connection->playback_status_changed = 1; 707 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 708 } 709 return ERROR_CODE_SUCCESS; 710 } 711 712 uint8_t avrcp_target_set_now_playing_info(uint16_t avrcp_cid, const avrcp_track_t * current_track, uint16_t total_tracks){ 713 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 714 if (!connection){ 715 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 716 } 717 if (!current_track){ 718 connection->track_selected = 0; 719 connection->playback_status = AVRCP_PLAYBACK_STATUS_ERROR; 720 return ERROR_CODE_COMMAND_DISALLOWED; 721 } 722 723 (void)memcpy(connection->track_id, current_track->track_id, 8); 724 connection->song_length_ms = current_track->song_length_ms; 725 connection->track_nr = current_track->track_nr; 726 connection->total_tracks = total_tracks; 727 avrcp_target_store_media_attr(connection, AVRCP_MEDIA_ATTR_TITLE, current_track->title); 728 avrcp_target_store_media_attr(connection, AVRCP_MEDIA_ATTR_ARTIST, current_track->artist); 729 avrcp_target_store_media_attr(connection, AVRCP_MEDIA_ATTR_ALBUM, current_track->album); 730 avrcp_target_store_media_attr(connection, AVRCP_MEDIA_ATTR_GENRE, current_track->genre); 731 connection->track_selected = 1; 732 733 if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED)) { 734 connection->track_changed = 1; 735 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 736 } 737 return ERROR_CODE_SUCCESS; 738 } 739 740 uint8_t avrcp_target_track_changed(uint16_t avrcp_cid, uint8_t * track_id){ 741 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 742 if (!connection){ 743 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 744 } 745 if (!track_id){ 746 return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; 747 } 748 749 (void)memcpy(connection->track_id, track_id, 8); 750 if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED)) { 751 connection->track_changed = 1; 752 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 753 } 754 return ERROR_CODE_SUCCESS; 755 } 756 757 uint8_t avrcp_target_playing_content_changed(uint16_t avrcp_cid){ 758 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 759 if (!connection){ 760 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 761 } 762 if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED)) { 763 connection->playing_content_changed = 1; 764 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 765 } 766 return ERROR_CODE_SUCCESS; 767 } 768 769 uint8_t avrcp_target_addressed_player_changed(uint16_t avrcp_cid, uint16_t player_id, uint16_t uid_counter){ 770 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 771 if (!connection){ 772 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 773 } 774 775 if (connection->addressed_player_id == player_id){ 776 return ERROR_CODE_SUCCESS; 777 } 778 779 connection->uid_counter = uid_counter; 780 connection->addressed_player_id = player_id; 781 782 if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED)) { 783 connection->addressed_player_changed = 1; 784 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 785 } 786 return ERROR_CODE_SUCCESS; 787 } 788 789 uint8_t avrcp_target_battery_status_changed(uint16_t avrcp_cid, avrcp_battery_status_t battery_status){ 790 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 791 if (!connection){ 792 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 793 } 794 if (connection->battery_status == battery_status){ 795 return ERROR_CODE_SUCCESS; 796 } 797 798 connection->battery_status = battery_status; 799 800 if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED)) { 801 connection->battery_status_changed = 1; 802 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 803 } 804 return ERROR_CODE_SUCCESS; 805 } 806 807 uint8_t avrcp_target_adjust_absolute_volume(uint16_t avrcp_cid, uint8_t absolute_volume){ 808 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 809 if (!connection){ 810 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 811 } 812 813 connection->absolute_volume = absolute_volume; 814 return ERROR_CODE_SUCCESS; 815 } 816 817 uint8_t avrcp_target_volume_changed(uint16_t avrcp_cid, uint8_t absolute_volume){ 818 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 819 if (!connection){ 820 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 821 } 822 if (connection->absolute_volume == absolute_volume){ 823 return ERROR_CODE_SUCCESS; 824 } 825 826 connection->absolute_volume = absolute_volume; 827 828 if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED )) { 829 connection->notify_absolute_volume_changed = 1; 830 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 831 } 832 return ERROR_CODE_SUCCESS; 833 } 834 835 static void avrcp_target_set_transaction_label_for_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t notification, uint8_t transaction_label){ 836 if (notification > AVRCP_NOTIFICATION_EVENT_MAX_VALUE) return; 837 connection->notifications_transaction_label[notification] = transaction_label; 838 } 839 840 static uint8_t avrcp_target_get_transaction_label_for_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t notification){ 841 if (notification > AVRCP_NOTIFICATION_EVENT_MAX_VALUE) return 0; 842 return connection->notifications_transaction_label[notification]; 843 } 844 845 static bool avcrp_operation_id_is_valid(avrcp_operation_id_t operation_id){ 846 if (operation_id < AVRCP_OPERATION_ID_RESERVED_1) return true; 847 848 if (operation_id < AVRCP_OPERATION_ID_0) return false; 849 if (operation_id < AVRCP_OPERATION_ID_RESERVED_2) return true; 850 851 if (operation_id < AVRCP_OPERATION_ID_CHANNEL_UP) return false; 852 if (operation_id < AVRCP_OPERATION_ID_RESERVED_3) return true; 853 854 if (operation_id < AVRCP_OPERATION_ID_CHANNEL_UP) return false; 855 if (operation_id < AVRCP_OPERATION_ID_RESERVED_3) return true; 856 857 if (operation_id < AVRCP_OPERATION_ID_SKIP) return false; 858 if (operation_id == AVRCP_OPERATION_ID_SKIP) return true; 859 860 if (operation_id < AVRCP_OPERATION_ID_POWER) return false; 861 if (operation_id < AVRCP_OPERATION_ID_RESERVED_4) return true; 862 863 if (operation_id < AVRCP_OPERATION_ID_ANGLE) return false; 864 if (operation_id < AVRCP_OPERATION_ID_RESERVED_5) return true; 865 866 if (operation_id < AVRCP_OPERATION_ID_F1) return false; 867 if (operation_id < AVRCP_OPERATION_ID_RESERVED_6) return true; 868 869 return false; 870 } 871 872 static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connection_t * connection, uint8_t *packet, uint16_t size){ 873 874 if (size < 6u) return; 875 876 uint16_t pid = 0; 877 uint8_t transport_header = packet[0]; 878 connection->transaction_id = transport_header >> 4; 879 880 avrcp_packet_type_t packet_type = (avrcp_packet_type_t) ((transport_header & 0x0F) >> 2); 881 switch (packet_type){ 882 case AVRCP_SINGLE_PACKET: 883 pid = big_endian_read_16(packet, 1); 884 break; 885 case AVRCP_START_PACKET: 886 pid = big_endian_read_16(packet, 2); 887 break; 888 default: 889 break; 890 } 891 892 switch (packet_type){ 893 case AVRCP_SINGLE_PACKET: 894 case AVRCP_START_PACKET: 895 if (pid != BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL){ 896 log_info("Invalid pid 0x%02x, expected 0x%02x", connection->invalid_pid, BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL); 897 connection->reject_transport_header = 1; 898 connection->invalid_pid = pid; 899 connection->transport_header = (connection->transaction_id << 4) | (AVRCP_SINGLE_PACKET << 2 ) | (AVRCP_RESPONSE_FRAME << 1) | 1; 900 connection->state = AVCTP_W2_SEND_RESPONSE; 901 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 902 return; 903 } 904 break; 905 default: 906 break; 907 } 908 909 if (packet_type != AVRCP_SINGLE_PACKET) return; 910 911 avrcp_subunit_type_t subunit_type = (avrcp_subunit_type_t) (packet[4] >> 3); 912 avrcp_subunit_id_t subunit_id = (avrcp_subunit_id_t) (packet[4] & 0x07); 913 914 avrcp_command_opcode_t opcode = (avrcp_command_opcode_t) avrcp_cmd_opcode(packet,size); 915 916 int pos = 6; 917 uint16_t length; 918 avrcp_pdu_id_t pdu_id; 919 connection->cmd_operands_length = 0; 920 uint8_t offset; 921 uint8_t operand; 922 uint16_t event_mask; 923 avrcp_operation_id_t operation_id; 924 925 switch (opcode){ 926 case AVRCP_CMD_OPCODE_UNIT_INFO: 927 avrcp_target_unit_info(connection); 928 break; 929 case AVRCP_CMD_OPCODE_SUBUNIT_INFO: 930 if ((size - pos) < 3) return; 931 // page: packet[pos] >> 4, 932 offset = 4 * (packet[pos]>>4); 933 // extension code (fixed 7) = packet[pos] & 0x0F 934 // 4 bytes paga data, all 0xFF 935 avrcp_target_subunit_info(connection, offset); 936 break; 937 938 case AVRCP_CMD_OPCODE_PASS_THROUGH: 939 if (size < 8) return; 940 log_info("AVRCP_OPERATION_ID 0x%02x, operands length %d", packet[6], packet[7]); 941 operation_id = (avrcp_operation_id_t) (packet[6] & 0x7f); 942 operand = 0; 943 if ((packet[7] >= 1) && (size >= 9)){ 944 operand = packet[8]; 945 } 946 947 if (avcrp_operation_id_is_valid(operation_id)){ 948 bool button_pressed = (packet[6] & 0x80) == 0; 949 950 avrcp_target_operation_accepted(connection->avrcp_cid, (avrcp_operation_id_t) packet[6], packet[7], operand); 951 avrcp_target_emit_operation(avrcp_target_context.avrcp_callback, connection->avrcp_cid, 952 operation_id, button_pressed, packet[7], operand); 953 } else { 954 avrcp_target_operation_not_implemented(connection->avrcp_cid, (avrcp_operation_id_t) packet[6], packet[7], operand); 955 } 956 break; 957 958 959 case AVRCP_CMD_OPCODE_VENDOR_DEPENDENT: 960 961 if (size < 13) return; 962 963 // pos = 6 - company id 964 (void)memcpy(connection->cmd_operands, &packet[pos], 3); 965 connection->cmd_operands_length = 3; 966 pos += 3; 967 // pos = 9 968 pdu_id = (avrcp_pdu_id_t) packet[pos++]; 969 // 1 - reserved 970 pos++; 971 // 2-3 param length, 972 length = big_endian_read_16(packet, pos); 973 pos += 2; 974 // pos = 13 975 switch (pdu_id){ 976 case AVRCP_PDU_ID_SET_ADDRESSED_PLAYER:{ 977 if ((pos + 2) > size) return; 978 bool ok = length == 4; 979 if (avrcp_target_context.set_addressed_player_callback != NULL){ 980 uint16_t player_id = big_endian_read_16(packet, pos); 981 ok = avrcp_target_context.set_addressed_player_callback(player_id); 982 } 983 if (ok){ 984 avrcp_target_response_accept(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_SUCCESS); 985 } else { 986 avrcp_target_response_reject(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_INVALID_PLAYER_ID); 987 } 988 break; 989 } 990 case AVRCP_PDU_ID_GET_CAPABILITIES:{ 991 avrcp_capability_id_t capability_id = (avrcp_capability_id_t) packet[pos]; 992 switch (capability_id){ 993 case AVRCP_CAPABILITY_ID_EVENT: 994 avrcp_target_supported_events(connection); 995 break; 996 case AVRCP_CAPABILITY_ID_COMPANY: 997 avrcp_target_supported_companies(connection); 998 break; 999 default: 1000 avrcp_target_response_reject(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_INVALID_PARAMETER); 1001 break; 1002 } 1003 break; 1004 } 1005 case AVRCP_PDU_ID_GET_PLAY_STATUS: 1006 avrcp_target_emit_respond_vendor_dependent_query(avrcp_target_context.avrcp_callback, connection->avrcp_cid, AVRCP_SUBEVENT_PLAY_STATUS_QUERY); 1007 break; 1008 case AVRCP_PDU_ID_REQUEST_ABORT_CONTINUING_RESPONSE: 1009 if ((pos + 1) > size) return; 1010 connection->cmd_operands[0] = packet[pos]; 1011 connection->abort_continue_response = 1; 1012 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1013 break; 1014 case AVRCP_PDU_ID_REQUEST_CONTINUING_RESPONSE: 1015 if ((pos + 1) > size) return; 1016 if (packet[pos] != AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES){ 1017 avrcp_target_response_reject(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_INVALID_COMMAND); 1018 return; 1019 } 1020 connection->now_playing_info_response = 1; 1021 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1022 break; 1023 case AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES:{ 1024 if ((pos + 9) > size) return; 1025 uint8_t play_identifier[8]; 1026 memset(play_identifier, 0, 8); 1027 if (memcmp(&packet[pos], play_identifier, 8) != 0) { 1028 avrcp_target_response_reject(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_INVALID_PARAMETER); 1029 return; 1030 } 1031 pos += 8; 1032 uint8_t attribute_count = packet[pos++]; 1033 connection->next_attr_id = AVRCP_MEDIA_ATTR_NONE; 1034 if (!attribute_count){ 1035 connection->now_playing_info_attr_bitmap = 0xFE; 1036 } else { 1037 int i; 1038 connection->now_playing_info_attr_bitmap = 0; 1039 if ((pos + attribute_count * 2) > size) return; 1040 for (i=0; i < attribute_count; i++){ 1041 uint16_t attr_id = big_endian_read_16(packet, pos); 1042 pos += 2; 1043 connection->now_playing_info_attr_bitmap |= (1 << attr_id); 1044 } 1045 } 1046 log_info("now_playing_info_attr_bitmap 0x%02x", connection->now_playing_info_attr_bitmap); 1047 avrcp_target_now_playing_info(connection); 1048 break; 1049 } 1050 case AVRCP_PDU_ID_REGISTER_NOTIFICATION:{ 1051 if ((pos + 1) > size) return; 1052 avrcp_notification_event_id_t event_id = (avrcp_notification_event_id_t) packet[pos]; 1053 1054 avrcp_target_set_transaction_label_for_notification(connection, event_id, connection->transaction_id); 1055 1056 if (event_id < AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED || 1057 event_id > AVRCP_NOTIFICATION_EVENT_MAX_VALUE){ 1058 avrcp_target_response_reject(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_INVALID_PARAMETER); 1059 return; 1060 } 1061 1062 switch (event_id){ 1063 case AVRCP_NOTIFICATION_EVENT_AVAILABLE_PLAYERS_CHANGED: 1064 case AVRCP_NOTIFICATION_EVENT_PLAYER_APPLICATION_SETTING_CHANGED: 1065 case AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED: 1066 case AVRCP_NOTIFICATION_EVENT_TRACK_REACHED_END: 1067 case AVRCP_NOTIFICATION_EVENT_TRACK_REACHED_START: 1068 case AVRCP_NOTIFICATION_EVENT_PLAYBACK_POS_CHANGED: 1069 case AVRCP_NOTIFICATION_EVENT_SYSTEM_STATUS_CHANGED: 1070 case AVRCP_NOTIFICATION_EVENT_MAX_VALUE: 1071 avrcp_target_response_not_implemented(connection, subunit_type, subunit_id, opcode, pdu_id, event_id); 1072 return; 1073 default: 1074 break; 1075 } 1076 1077 event_mask = (1 << event_id); 1078 connection->notifications_enabled |= event_mask; 1079 avrcp_target_response_setup(connection, AVRCP_CTYPE_RESPONSE_INTERIM, subunit_type, subunit_id, opcode); 1080 1081 switch (event_id){ 1082 case AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED: 1083 if (connection->track_selected){ 1084 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, AVRCP_NOTIFICATION_TRACK_SELECTED, 8); 1085 } else { 1086 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, AVRCP_NOTIFICATION_TRACK_NOT_SELECTED, 8); 1087 } 1088 break; 1089 case AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED: 1090 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, (const uint8_t *)&connection->playback_status, 1); 1091 break; 1092 case AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED: 1093 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, NULL, 0); 1094 break; 1095 case AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED: 1096 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, (const uint8_t *)&connection->absolute_volume, 1); 1097 break; 1098 case AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED: 1099 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, (const uint8_t *)&connection->battery_status, 1); 1100 break; 1101 case AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED: 1102 avrcp_target_response_addressed_player_changed_interim(connection, subunit_type, subunit_id, opcode, pdu_id); 1103 return; 1104 default: 1105 btstack_assert(false); 1106 return; 1107 } 1108 break; 1109 } 1110 case AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME: { 1111 if ( (length != 1) || ((pos + 1) > size)){ 1112 avrcp_target_response_reject(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_INVALID_COMMAND); 1113 break; 1114 } 1115 1116 uint8_t absolute_volume = packet[pos]; 1117 if (absolute_volume < 0x80){ 1118 connection->absolute_volume = absolute_volume; 1119 } 1120 avrcp_target_emit_volume_changed(avrcp_target_context.avrcp_callback, connection->avrcp_cid, connection->absolute_volume); 1121 avrcp_target_response_accept(connection, subunit_type, subunit_id, opcode, pdu_id, connection->absolute_volume); 1122 break; 1123 } 1124 default: 1125 log_info("AVRCP target: unhandled pdu id 0x%02x", pdu_id); 1126 avrcp_target_response_reject(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_INVALID_COMMAND); 1127 break; 1128 } 1129 break; 1130 default: 1131 log_info("AVRCP target: opcode 0x%02x not implemented", avrcp_cmd_opcode(packet,size)); 1132 break; 1133 } 1134 } 1135 1136 static int avrcp_target_send_notification(uint16_t cid, avrcp_connection_t * connection, avrcp_notification_event_id_t notification_id, uint8_t * value, uint16_t value_len){ 1137 if (!connection){ 1138 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1139 } 1140 1141 btstack_assert((value_len == 0) || (value != NULL)); 1142 1143 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1144 connection->command_type = AVRCP_CTYPE_RESPONSE_CHANGED_STABLE; 1145 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1146 connection->subunit_id = AVRCP_SUBUNIT_ID; 1147 connection->transaction_id = avrcp_target_get_transaction_label_for_notification(connection, notification_id); 1148 1149 uint16_t pos = 0; 1150 l2cap_reserve_packet_buffer(); 1151 uint8_t * packet = l2cap_get_outgoing_buffer(); 1152 1153 // value <= 8 ==> pdu <= 22 < L2CAP Default MTU 1154 btstack_assert((14 + value_len) <= l2cap_get_remote_mtu_for_local_cid(connection->l2cap_signaling_cid)); 1155 1156 connection->packet_type = AVRCP_SINGLE_PACKET; 1157 packet[pos++] = (connection->transaction_id << 4) | (connection->packet_type << 2) | (AVRCP_RESPONSE_FRAME << 1) | 0; 1158 // Profile IDentifier (PID) 1159 packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8; 1160 packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF; 1161 1162 // command_type 1163 packet[pos++] = connection->command_type; 1164 // subunit_type | subunit ID 1165 packet[pos++] = (connection->subunit_type << 3) | connection->subunit_id; 1166 // opcode 1167 packet[pos++] = (uint8_t)connection->command_opcode; 1168 1169 // company id is 3 bytes long 1170 big_endian_store_24(packet, pos, BT_SIG_COMPANY_ID); 1171 pos += 3; 1172 1173 packet[pos++] = AVRCP_PDU_ID_REGISTER_NOTIFICATION; 1174 packet[pos++] = 0; 1175 1176 big_endian_store_16(packet, pos, 1 + value_len); 1177 pos += 2; 1178 packet[pos++] = notification_id; 1179 if (value_len > 0){ 1180 (void)memcpy(packet + pos, value, value_len); 1181 pos += value_len; 1182 } 1183 1184 return l2cap_send_prepared(cid, pos); 1185 } 1186 1187 static void avrcp_target_reset_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t notification_id){ 1188 if (!connection){ 1189 log_error("avrcp tartget: could not find a connection."); 1190 return; 1191 } 1192 connection->notifications_enabled &= ~(1 << notification_id); 1193 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1194 avrcp_target_set_transaction_label_for_notification(connection, notification_id, 0); 1195 } 1196 1197 static void avrcp_target_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 1198 avrcp_connection_t * connection; 1199 switch (packet_type) { 1200 case L2CAP_DATA_PACKET: 1201 connection = avrcp_get_connection_for_l2cap_signaling_cid_for_role(AVRCP_TARGET, channel); 1202 avrcp_handle_l2cap_data_packet_for_signaling_connection(connection, packet, size); 1203 break; 1204 case HCI_EVENT_PACKET: 1205 switch (hci_event_packet_get_type(packet)){ 1206 case L2CAP_EVENT_CAN_SEND_NOW:{ 1207 connection = avrcp_get_connection_for_l2cap_signaling_cid_for_role(AVRCP_TARGET, channel); 1208 1209 if (connection->accept_response){ 1210 connection->accept_response = 0; 1211 avrcp_target_send_response(connection->l2cap_signaling_cid, connection); 1212 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1213 return; 1214 } 1215 1216 if (connection->abort_continue_response){ 1217 connection->abort_continue_response = 0; 1218 connection->now_playing_info_response = 0; 1219 avrcp_target_abort_continue_response(connection->l2cap_signaling_cid, connection); 1220 return; 1221 } 1222 1223 if (connection->now_playing_info_response){ 1224 connection->now_playing_info_response = 0; 1225 avrcp_target_send_now_playing_info(connection->l2cap_signaling_cid, connection); 1226 return; 1227 } 1228 1229 if (connection->track_changed){ 1230 connection->track_changed = 0; 1231 avrcp_target_send_notification(connection->l2cap_signaling_cid, connection, AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED, connection->track_id, 8); 1232 avrcp_target_reset_notification(connection, AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED); 1233 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1234 return; 1235 } 1236 1237 if (connection->playback_status_changed){ 1238 connection->playback_status_changed = 0; 1239 uint8_t playback_status = (uint8_t) connection->playback_status; 1240 avrcp_target_send_notification(connection->l2cap_signaling_cid, connection, AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED, &playback_status, 1); 1241 avrcp_target_reset_notification(connection, AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED); 1242 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1243 return; 1244 } 1245 1246 if (connection->playing_content_changed){ 1247 connection->playing_content_changed = 0; 1248 avrcp_target_send_notification(connection->l2cap_signaling_cid, connection, AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED, NULL, 0); 1249 avrcp_target_reset_notification(connection, AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED); 1250 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1251 return; 1252 } 1253 1254 if (connection->battery_status_changed){ 1255 connection->battery_status_changed = 0; 1256 avrcp_target_send_notification(connection->l2cap_signaling_cid, connection, AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED, (uint8_t *)&connection->battery_status, 1); 1257 avrcp_target_reset_notification(connection, AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED); 1258 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1259 return; 1260 } 1261 1262 if (connection->notify_absolute_volume_changed){ 1263 connection->notify_absolute_volume_changed = 0; 1264 avrcp_target_send_notification(connection->l2cap_signaling_cid, connection, AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED, &connection->absolute_volume, 1); 1265 avrcp_target_reset_notification(connection, AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED); 1266 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1267 return; 1268 } 1269 1270 if (connection->addressed_player_changed){ 1271 connection->addressed_player_changed = 0; 1272 uint8_t buffer[4]; 1273 big_endian_store_16(buffer, 0, connection->addressed_player_id); 1274 big_endian_store_16(buffer, 2, connection->uid_counter); 1275 avrcp_target_send_notification(connection->l2cap_signaling_cid, connection, AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED, buffer, 4); 1276 avrcp_target_reset_notification(connection, AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED); 1277 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1278 return; 1279 } 1280 1281 if (connection->reject_transport_header){ 1282 connection->state = AVCTP_CONNECTION_OPENED; 1283 connection->reject_transport_header = 0; 1284 l2cap_reserve_packet_buffer(); 1285 uint8_t * out_buffer = l2cap_get_outgoing_buffer(); 1286 out_buffer[0] = connection->transport_header; 1287 big_endian_store_16(out_buffer, 1, connection->invalid_pid); 1288 l2cap_send_prepared(connection->l2cap_signaling_cid, 3); 1289 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1290 return; 1291 } 1292 1293 switch (connection->state){ 1294 case AVCTP_W2_SEND_RESPONSE: 1295 connection->state = AVCTP_CONNECTION_OPENED; 1296 avrcp_target_send_response(connection->l2cap_signaling_cid, connection); 1297 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1298 return; 1299 default: 1300 break; 1301 } 1302 1303 break; 1304 } 1305 default: 1306 break; 1307 } 1308 default: 1309 break; 1310 } 1311 } 1312 1313 void avrcp_target_init(void){ 1314 avrcp_target_context.role = AVRCP_TARGET; 1315 avrcp_target_context.packet_handler = avrcp_target_packet_handler; 1316 avrcp_register_target_packet_handler(&avrcp_target_packet_handler); 1317 } 1318 1319 void avrcp_target_deinit(void){ 1320 memset(&avrcp_target_context, 0, sizeof(avrcp_context_t)); 1321 } 1322 1323 void avrcp_target_register_packet_handler(btstack_packet_handler_t callback){ 1324 btstack_assert(callback != NULL); 1325 avrcp_target_context.avrcp_callback = callback; 1326 } 1327 1328 void avrcp_target_register_set_addressed_player_handler(bool (*callback)(uint16_t player_id)){ 1329 btstack_assert(callback != NULL); 1330 avrcp_target_context.set_addressed_player_callback = callback; 1331 } 1332 1333 1334