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 #include <stdio.h> 55 #define AVRCP_ATTR_HEADER_LEN 8 56 57 static const uint8_t AVRCP_NOTIFICATION_TRACK_SELECTED[] = {0,0,0,0,0,0,0,0}; 58 static const uint8_t AVRCP_NOTIFICATION_TRACK_NOT_SELECTED[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; 59 60 static const char * avrcp_default_target_service_name = "AVRCP Target"; 61 static const char * avrcp_default_target_service_provider_name = "BlueKitchen"; 62 63 avrcp_context_t avrcp_target_context; 64 65 static uint32_t default_companies[] = { 66 0x581900 //BT SIG registered CompanyID 67 }; 68 69 static int avrcp_target_supports_browsing(uint16_t target_supported_features){ 70 return target_supported_features & AVRCP_FEATURE_MASK_BROWSING; 71 } 72 73 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){ 74 if (service_name == NULL){ 75 service_name = avrcp_default_target_service_name; 76 } 77 if (service_provider_name == NULL){ 78 service_provider_name = avrcp_default_target_service_provider_name; 79 } 80 avrcp_create_sdp_record(false, service, service_record_handle, avrcp_target_supports_browsing(supported_features), supported_features, service_name, service_provider_name); 81 } 82 83 static void 84 avrcp_target_emit_operation(btstack_packet_handler_t callback, uint16_t avrcp_cid, avrcp_operation_id_t operation_id, 85 bool button_pressed, uint8_t operands_length, uint8_t operand) { 86 btstack_assert(callback != NULL); 87 88 uint8_t event[9]; 89 int pos = 0; 90 event[pos++] = HCI_EVENT_AVRCP_META; 91 event[pos++] = sizeof(event) - 2; 92 event[pos++] = AVRCP_SUBEVENT_OPERATION; 93 little_endian_store_16(event, pos, avrcp_cid); 94 pos += 2; 95 event[pos++] = operation_id; 96 event[pos++] = button_pressed ? 1 : 0; 97 event[pos++] = operands_length; 98 event[pos++] = operand; 99 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 100 } 101 102 static void avrcp_target_emit_volume_changed(btstack_packet_handler_t callback, uint16_t avrcp_cid, uint8_t absolute_volume){ 103 btstack_assert(callback != NULL); 104 105 uint8_t event[7]; 106 int offset = 0; 107 event[offset++] = HCI_EVENT_AVRCP_META; 108 event[offset++] = sizeof(event) - 2; 109 event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED; 110 little_endian_store_16(event, offset, avrcp_cid); 111 offset += 2; 112 event[offset++] = AVRCP_CTYPE_NOTIFY; 113 event[offset++] = absolute_volume; 114 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 115 } 116 117 static void avrcp_target_emit_respond_vendor_dependent_query(btstack_packet_handler_t callback, uint16_t avrcp_cid, uint8_t subevent_id){ 118 btstack_assert(callback != NULL); 119 120 uint8_t event[5]; 121 int pos = 0; 122 event[pos++] = HCI_EVENT_AVRCP_META; 123 event[pos++] = sizeof(event) - 2; 124 event[pos++] = subevent_id; 125 little_endian_store_16(event, pos, avrcp_cid); 126 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 127 } 128 129 static void avrcp_target_emit_respond_play_item(btstack_packet_handler_t callback, uint16_t avrcp_cid, uint16_t uid_counter, avrcp_browsing_scope_t scope, uint8_t * uid){ 130 btstack_assert(callback != NULL); 131 132 uint8_t event[16]; 133 int pos = 0; 134 event[pos++] = HCI_EVENT_AVRCP_META; 135 event[pos++] = sizeof(event) - 2; 136 event[pos++] = AVRCP_SUBEVENT_PLAY_ITEM; 137 little_endian_store_16(event, pos, avrcp_cid); 138 pos += 2; 139 little_endian_store_16(event, pos, uid_counter); 140 pos += 2; 141 event[pos++] = (uint8_t) scope; 142 memcpy(&event[pos], uid, 8); 143 pos += 8; 144 145 (*callback)(HCI_EVENT_PACKET, 0, event, pos); 146 } 147 148 // returns number of bytes stored 149 static uint16_t avrcp_target_pack_single_element_header(uint8_t * buffer, avrcp_media_attribute_id_t attr_id, uint16_t attr_value_size){ 150 btstack_assert(attr_id > AVRCP_MEDIA_ATTR_ALL); 151 btstack_assert(attr_id < AVRCP_MEDIA_ATTR_NUM); 152 uint16_t pos = 0; 153 big_endian_store_32(buffer, pos, attr_id); 154 big_endian_store_16(buffer, pos + 4, RFC2978_CHARSET_MIB_UTF8); 155 big_endian_store_16(buffer, pos + 6, attr_value_size); 156 return 8; 157 } 158 159 static uint16_t avrcp_now_playing_info_attr_id_value_len(avrcp_connection_t * connection, avrcp_media_attribute_id_t attr_id){ 160 char buffer[AVRCP_MAX_ATTRIBUTE_SIZE]; 161 uint16_t str_len; 162 switch (attr_id) { 163 case AVRCP_MEDIA_ATTR_ALL: 164 case AVRCP_MEDIA_ATTR_NONE: 165 return 0; 166 case AVRCP_MEDIA_ATTR_TRACK: 167 str_len = btstack_snprintf_assert_complete(buffer, sizeof(buffer), "%" PRIu32, connection->target_track_nr); 168 break; 169 case AVRCP_MEDIA_ATTR_TOTAL_NUM_ITEMS: 170 str_len = btstack_snprintf_assert_complete(buffer, sizeof(buffer), "%" PRIu32, connection->target_total_tracks); 171 break; 172 case AVRCP_MEDIA_ATTR_SONG_LENGTH_MS: 173 str_len = btstack_snprintf_assert_complete(buffer, sizeof(buffer), "%" PRIu32, connection->target_song_length_ms); 174 break; 175 default: 176 str_len = connection->target_now_playing_info[(uint16_t)attr_id - 1].len; 177 break; 178 } 179 return str_len; 180 } 181 182 static uint16_t avrcp_now_playing_info_value_len_with_headers(avrcp_connection_t * connection){ 183 uint16_t playing_info_len = 0; 184 185 uint8_t i; 186 for ( i = (uint8_t)AVRCP_MEDIA_ATTR_ALL + 1; i < (uint8_t) AVRCP_MEDIA_ATTR_NUM; i++){ 187 avrcp_media_attribute_id_t attr_id = (avrcp_media_attribute_id_t) i; 188 189 if ((connection->target_now_playing_info_attr_bitmap & (1 << attr_id)) == 0) { 190 continue; 191 } 192 193 switch (attr_id) { 194 case AVRCP_MEDIA_ATTR_ALL: 195 case AVRCP_MEDIA_ATTR_NONE: 196 case AVRCP_MEDIA_ATTR_DEFAULT_COVER_ART: 197 break; 198 default: 199 playing_info_len += AVRCP_ATTR_HEADER_LEN + avrcp_now_playing_info_attr_id_value_len(connection, attr_id); 200 break; 201 } 202 } 203 // for total num bytes that of the attributes + headers 204 playing_info_len += 1; 205 return playing_info_len; 206 } 207 208 static uint8_t * avrcp_get_attribute_value_from_u32(avrcp_connection_t * connection, uint32_t value, uint16_t * num_bytes_to_copy){ 209 *num_bytes_to_copy = 0; 210 211 if (connection->attribute_value_len == 0){ 212 // "4294967296" = 10 chars + \0 213 connection->attribute_value_len = btstack_snprintf_assert_complete((char *)connection->attribute_value, 11, "%" PRIu32, value); 214 connection->attribute_value_offset = 0; 215 } 216 *num_bytes_to_copy = connection->attribute_value_len - connection->attribute_value_offset; 217 return connection->attribute_value + connection->attribute_value_offset; 218 } 219 220 static uint8_t * avrcp_get_next_value_fragment_for_attribute_id(avrcp_connection_t * connection, avrcp_media_attribute_id_t attr_id, uint16_t * num_bytes_to_copy){ 221 switch (attr_id){ 222 case AVRCP_MEDIA_ATTR_TRACK: 223 return avrcp_get_attribute_value_from_u32(connection, connection->target_track_nr, num_bytes_to_copy); 224 case AVRCP_MEDIA_ATTR_TOTAL_NUM_ITEMS: 225 return avrcp_get_attribute_value_from_u32(connection, connection->target_total_tracks, num_bytes_to_copy); 226 case AVRCP_MEDIA_ATTR_SONG_LENGTH_MS: 227 return avrcp_get_attribute_value_from_u32(connection, connection->target_song_length_ms, num_bytes_to_copy); 228 default: 229 break; 230 } 231 int attr_index = attr_id - 1; 232 if (connection->attribute_value_len == 0){ 233 connection->attribute_value_len = avrcp_now_playing_info_attr_id_value_len(connection, attr_id); 234 connection->attribute_value_offset = 0; 235 } 236 *num_bytes_to_copy = connection->target_now_playing_info[attr_index].len - connection->attribute_value_offset; 237 return (uint8_t *) (connection->target_now_playing_info[attr_index].value + connection->attribute_value_offset); 238 } 239 240 // TODO Review 241 static uint16_t avrcp_store_avctp_now_playing_info_fragment(avrcp_connection_t * connection, uint16_t packet_size, uint8_t * packet){ 242 uint16_t num_free_bytes = packet_size; 243 244 uint16_t bytes_stored = 0; 245 246 while ((num_free_bytes > 0) && (connection->next_attr_id <= AVRCP_MEDIA_ATTR_SONG_LENGTH_MS)){ 247 if ((connection->target_now_playing_info_attr_bitmap & (1 << (uint8_t)connection->next_attr_id)) == 0) { 248 connection->next_attr_id = (avrcp_media_attribute_id_t) (((int) connection->next_attr_id) + 1); 249 continue; 250 } 251 252 // prepare attribute value 253 uint16_t num_bytes_to_copy; 254 uint8_t * attr_value_with_offset = avrcp_get_next_value_fragment_for_attribute_id(connection, 255 connection->next_attr_id, 256 &num_bytes_to_copy); 257 258 // store header 259 if (connection->attribute_value_offset == 0){ 260 // pack the whole attribute value header 261 if (connection->parser_attribute_header_pos == 0) { 262 avrcp_target_pack_single_element_header(connection->parser_attribute_header, connection->next_attr_id, 263 connection->attribute_value_len); 264 } 265 } 266 267 if (connection->parser_attribute_header_pos < AVRCP_ATTRIBUTE_HEADER_LEN){ 268 uint16_t num_header_bytes_to_store = btstack_min(num_free_bytes, AVRCP_ATTRIBUTE_HEADER_LEN - connection->parser_attribute_header_pos); 269 memcpy(packet + bytes_stored, connection->parser_attribute_header + connection->parser_attribute_header_pos, num_header_bytes_to_store); 270 connection->parser_attribute_header_pos += num_header_bytes_to_store; 271 bytes_stored += num_header_bytes_to_store; 272 num_free_bytes -= num_header_bytes_to_store; 273 connection->data_offset += num_header_bytes_to_store; 274 275 if (num_free_bytes == 0){ 276 continue; 277 } 278 } 279 280 // store value 281 uint16_t num_attr_value_bytes_to_store = btstack_min(num_free_bytes, connection->attribute_value_len - connection->attribute_value_offset); 282 memcpy(packet + bytes_stored, attr_value_with_offset, num_attr_value_bytes_to_store); 283 bytes_stored += num_attr_value_bytes_to_store; 284 num_free_bytes -= num_attr_value_bytes_to_store; 285 connection->attribute_value_offset += num_attr_value_bytes_to_store; 286 connection->data_offset += num_attr_value_bytes_to_store; 287 288 if (connection->attribute_value_offset == connection->attribute_value_len){ 289 // C++ compatible version of connection->next_attr_id++ 290 connection->next_attr_id = (avrcp_media_attribute_id_t) (((int) connection->next_attr_id) + 1); 291 connection->attribute_value_offset = 0; 292 connection->attribute_value_len = 0; 293 connection->parser_attribute_header_pos = 0; 294 } 295 } 296 return bytes_stored; 297 } 298 299 static void avrcp_send_response_with_avctp_fragmentation(avrcp_connection_t * connection){ 300 l2cap_reserve_packet_buffer(); 301 uint8_t * packet = l2cap_get_outgoing_buffer(); 302 303 // transport header 304 // Transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier) 305 306 uint16_t max_payload_size; 307 connection->avctp_packet_type = avctp_get_packet_type(connection, &max_payload_size); 308 connection->avrcp_packet_type = avrcp_get_packet_type(connection); 309 310 // AVCTP header 311 // transport header : transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier) 312 uint16_t pos = 0; 313 packet[pos++] = (connection->transaction_id << 4) | (connection->avctp_packet_type << 2) | (AVRCP_RESPONSE_FRAME << 1) | 0; 314 315 uint16_t param_len = connection->data_len; 316 317 if (connection->avctp_packet_type == AVCTP_START_PACKET){ 318 uint16_t max_frame_size = btstack_min(connection->l2cap_mtu, AVRCP_MAX_AV_C_MESSAGE_FRAME_SIZE); 319 // first packet: max_payload_size 320 // rest packets 321 uint16_t num_payload_bytes = param_len - max_payload_size; 322 uint16_t frame_size_for_continue_packet = max_frame_size - avctp_get_num_bytes_for_header(AVCTP_CONTINUE_PACKET); 323 uint16_t num_avctp_packets = (num_payload_bytes + frame_size_for_continue_packet - 1)/frame_size_for_continue_packet + 1; 324 btstack_assert(num_avctp_packets <= 255); 325 packet[pos++] = (uint8_t) num_avctp_packets; 326 } 327 328 uint16_t bytes_stored = 0; 329 uint8_t i; 330 331 switch (connection->avctp_packet_type) { 332 case AVCTP_SINGLE_PACKET: 333 case AVCTP_START_PACKET: 334 // Profile IDentifier (PID) 335 packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8; 336 packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF; 337 338 // AVRCP message 339 // command_type 340 packet[pos++] = connection->command_type; 341 // subunit_type | subunit ID 342 packet[pos++] = (connection->subunit_type << 3) | connection->subunit_id; 343 // opcode 344 packet[pos++] = (uint8_t) connection->command_opcode; 345 346 switch (connection->command_opcode) { 347 case AVRCP_CMD_OPCODE_VENDOR_DEPENDENT: 348 big_endian_store_24(packet, pos, connection->company_id); 349 pos += 3; 350 packet[pos++] = connection->pdu_id; 351 // AVRCP packet type 352 353 packet[pos++] = (uint8_t)connection->avrcp_packet_type; 354 // parameter length 355 big_endian_store_16(packet, pos, param_len); 356 pos += 2; 357 358 switch (connection->pdu_id) { 359 // message is small enough to fit the single packet, no need for extra check 360 case AVRCP_PDU_ID_GET_CAPABILITIES: 361 // capability ID 362 packet[pos++] = connection->data[0]; 363 // num_capabilities 364 packet[pos++] = connection->data[1]; 365 366 switch ((avrcp_capability_id_t) connection->data[0]) { 367 case AVRCP_CAPABILITY_ID_EVENT: 368 for (i = (uint8_t) AVRCP_NOTIFICATION_EVENT_FIRST_INDEX; 369 i < (uint8_t) AVRCP_NOTIFICATION_EVENT_LAST_INDEX; i++) { 370 if ((connection->notifications_supported_by_target & (1 << i)) == 0) { 371 continue; 372 } 373 packet[pos++] = i; 374 } 375 break; 376 case AVRCP_CAPABILITY_ID_COMPANY: 377 // use Bluetooth SIG as default company 378 for (i = 0; i < connection->data[1]; i++) { 379 little_endian_store_24(packet, pos, 380 connection->target_supported_companies[i]); 381 pos += 3; 382 } 383 break; 384 default: 385 // error response 386 break; 387 } 388 l2cap_send_prepared(connection->l2cap_signaling_cid, pos); 389 return; 390 391 case AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES: 392 packet[pos++] = count_set_bits_uint32(connection->target_now_playing_info_attr_bitmap); 393 max_payload_size--; 394 395 bytes_stored = avrcp_store_avctp_now_playing_info_fragment(connection, max_payload_size, packet + pos); 396 397 connection->avrcp_frame_bytes_sent += bytes_stored + pos; 398 l2cap_send_prepared(connection->l2cap_signaling_cid, pos + bytes_stored); 399 return; 400 401 default: 402 // error response and other OPCODEs 403 break; 404 } 405 break; 406 407 case AVRCP_CMD_OPCODE_PASS_THROUGH: 408 packet[pos++] = connection->operation_id; 409 // parameter length 410 packet[pos++] = (uint8_t) connection->data_len; 411 pos += 2; 412 break; 413 case AVRCP_CMD_OPCODE_UNIT_INFO: 414 break; 415 case AVRCP_CMD_OPCODE_SUBUNIT_INFO: 416 break; 417 default: 418 btstack_assert(false); 419 return; 420 } 421 break; 422 case AVCTP_CONTINUE_PACKET: 423 case AVCTP_END_PACKET: 424 switch (connection->pdu_id) { 425 case AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES: 426 bytes_stored = avrcp_store_avctp_now_playing_info_fragment(connection, max_payload_size, packet + pos); 427 428 connection->avrcp_frame_bytes_sent += bytes_stored + pos; 429 l2cap_send_prepared(connection->l2cap_signaling_cid, pos + bytes_stored); 430 return; 431 432 default: 433 break; 434 } 435 break; 436 default: 437 btstack_assert(false); 438 return; 439 } 440 441 // compare number of bytes to store with the remaining buffer size 442 uint16_t bytes_to_copy = btstack_min(connection->data_len - connection->data_offset, max_payload_size - pos); 443 444 (void)memcpy(packet + pos, &connection->data[connection->data_offset], bytes_to_copy); 445 pos += bytes_to_copy; 446 connection->data_offset += bytes_to_copy; 447 connection->avrcp_frame_bytes_sent += pos; 448 449 l2cap_send_prepared(connection->l2cap_signaling_cid, pos); 450 } 451 452 static void avctp_send_reject_cmd_wrong_pid(avrcp_connection_t * connection){ 453 l2cap_reserve_packet_buffer(); 454 uint8_t * packet = l2cap_get_outgoing_buffer(); 455 456 // AVCTP header 457 // transport header : transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier) 458 packet[0] = (connection->transaction_id << 4) | (AVRCP_SINGLE_PACKET << 2) | (AVRCP_RESPONSE_FRAME << 1) | 1; 459 big_endian_store_16(packet, 1, connection->message_body[0]); 460 l2cap_send_prepared(connection->l2cap_signaling_cid, 3); 461 } 462 463 static void avrcp_target_custom_command_data_init(avrcp_connection_t * connection, 464 avrcp_command_opcode_t opcode, avrcp_command_type_t command_type, 465 avrcp_subunit_type_t subunit_type, avrcp_subunit_id_t subunit_id, 466 avrcp_pdu_id_t pdu_id, uint32_t company_id){ 467 468 connection->command_opcode = opcode; 469 connection->command_type = command_type; 470 connection->subunit_type = subunit_type; 471 connection->subunit_id = subunit_id; 472 connection->company_id = company_id << 16; 473 connection->pdu_id = pdu_id; 474 connection->data = NULL; 475 connection->data_offset = 0; 476 connection->data_len = 0; 477 connection->avrcp_frame_bytes_sent = 0; 478 } 479 480 static void avrcp_target_vendor_dependent_response_data_init(avrcp_connection_t * connection, avrcp_command_type_t command_type, avrcp_pdu_id_t pdu_id){ 481 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 482 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 483 connection->subunit_id = AVRCP_SUBUNIT_ID; 484 connection->company_id = BT_SIG_COMPANY_ID; 485 486 connection->command_type = command_type; 487 connection->pdu_id = pdu_id; 488 connection->data = connection->message_body; 489 connection->data_offset = 0; 490 connection->data_len = 0; 491 connection->avrcp_frame_bytes_sent = 0; 492 } 493 494 static void avrcp_target_pass_through_command_data_init(avrcp_connection_t * connection, avrcp_command_type_t command_type, avrcp_operation_id_t opid){ 495 connection->command_opcode = AVRCP_CMD_OPCODE_PASS_THROUGH; 496 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 497 connection->subunit_id = AVRCP_SUBUNIT_ID; 498 499 connection->command_type = command_type; 500 connection->company_id = 0; 501 connection->pdu_id = AVRCP_PDU_ID_UNDEFINED; 502 connection->operation_id = opid; 503 504 connection->data = connection->message_body; 505 connection->data_offset = 0; 506 connection->data_len = 0; 507 connection->avrcp_frame_bytes_sent = 0; 508 } 509 510 511 static uint8_t avrcp_target_vendor_dependent_response_accept(avrcp_connection_t * connection, avrcp_pdu_id_t pdu_id, uint8_t status){ 512 avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_ACCEPTED, pdu_id); 513 connection->data_len = 1; 514 connection->data[0] = status; 515 516 connection->target_accept_response = true; 517 connection->state = AVCTP_W2_SEND_RESPONSE; 518 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 519 return ERROR_CODE_SUCCESS; 520 } 521 522 static uint8_t avrcp_target_response_vendor_dependent_reject(avrcp_connection_t * connection, avrcp_pdu_id_t pdu_id, avrcp_status_code_t status){ 523 avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_REJECTED, pdu_id); 524 connection->data_len = 1; 525 connection->data[0] = status; 526 527 connection->state = AVCTP_W2_SEND_RESPONSE; 528 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 529 return ERROR_CODE_SUCCESS; 530 } 531 532 static uint8_t avrcp_target_response_vendor_dependent_not_implemented(avrcp_connection_t * connection, avrcp_pdu_id_t pdu_id, uint8_t event_id){ 533 avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_NOT_IMPLEMENTED, pdu_id); 534 connection->data_len = 1; 535 connection->data[0] = event_id; 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_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){ 543 btstack_assert(value_len + 1 < AVRCP_MAX_COMMAND_PARAMETER_LENGTH); 544 avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_INTERIM, pdu_id); 545 connection->data_len = 1 + value_len; 546 connection->data[0] = event_id; 547 548 if (value && (value_len > 0)){ 549 (void)memcpy(connection->data + 1, value, value_len); 550 } 551 552 connection->state = AVCTP_W2_SEND_RESPONSE; 553 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 554 return ERROR_CODE_SUCCESS; 555 } 556 557 static uint8_t avrcp_target_response_addressed_player_changed_interim(avrcp_connection_t * connection, avrcp_pdu_id_t pdu_id, uint8_t event_id){ 558 avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_INTERIM, pdu_id); 559 560 connection->data_len = 5; 561 connection->data[0] = event_id; 562 big_endian_store_16(connection->data, 1, connection->target_addressed_player_id); 563 big_endian_store_16(connection->data, 3, connection->target_uid_counter); 564 565 connection->state = AVCTP_W2_SEND_RESPONSE; 566 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 567 return ERROR_CODE_SUCCESS; 568 } 569 570 static uint8_t avrcp_target_pass_through_response(uint16_t avrcp_cid, avrcp_command_type_t ctype, avrcp_operation_id_t opid, uint8_t operands_length, uint8_t operand){ 571 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 572 if (!connection){ 573 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 574 } 575 avrcp_target_pass_through_command_data_init(connection, ctype, opid); 576 577 if (operands_length == 1){ 578 connection->data_len = 1; 579 connection->message_body[0] = operand; 580 } 581 582 connection->state = AVCTP_W2_SEND_RESPONSE; 583 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 584 return ERROR_CODE_SUCCESS; 585 } 586 587 uint8_t avrcp_target_operation_rejected(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint8_t operands_length, uint8_t operand){ 588 return avrcp_target_pass_through_response(avrcp_cid, AVRCP_CTYPE_RESPONSE_REJECTED, opid, operands_length, operand); 589 } 590 591 uint8_t avrcp_target_operation_accepted(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint8_t operands_length, uint8_t operand){ 592 return avrcp_target_pass_through_response(avrcp_cid, AVRCP_CTYPE_RESPONSE_ACCEPTED, opid, operands_length, operand); 593 } 594 595 uint8_t avrcp_target_operation_not_implemented(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint8_t operands_length, uint8_t operand){ 596 return avrcp_target_pass_through_response(avrcp_cid, AVRCP_CTYPE_RESPONSE_ACCEPTED, opid, operands_length, operand); 597 } 598 599 uint8_t avrcp_target_set_unit_info(uint16_t avrcp_cid, avrcp_subunit_type_t unit_type, uint32_t company_id){ 600 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 601 if (!connection){ 602 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 603 } 604 connection->target_unit_type = unit_type; 605 connection->company_id = company_id; 606 return ERROR_CODE_SUCCESS; 607 } 608 609 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){ 610 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 611 if (!connection){ 612 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 613 } 614 connection->target_subunit_info_type = subunit_type; 615 connection->target_subunit_info_data = subunit_info_data; 616 connection->target_subunit_info_data_size = subunit_info_data_size; 617 return ERROR_CODE_SUCCESS; 618 } 619 620 static uint8_t avrcp_target_unit_info(avrcp_connection_t * connection){ 621 if (connection->state != AVCTP_CONNECTION_OPENED){ 622 return ERROR_CODE_COMMAND_DISALLOWED; 623 } 624 625 avrcp_target_custom_command_data_init(connection, 626 AVRCP_CMD_OPCODE_UNIT_INFO, AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE, 627 AVRCP_SUBUNIT_TYPE_UNIT, AVRCP_SUBUNIT_ID_IGNORE, AVRCP_PDU_ID_UNDEFINED, 628 connection->company_id); 629 630 uint8_t unit = 0; 631 connection->data = connection->message_body; 632 connection->data_len = 5; 633 connection->data[0] = 0x07; 634 connection->data[1] = (connection->target_unit_type << 4) | unit; 635 // company id is 3 bytes long 636 big_endian_store_24(connection->data, 2, connection->company_id); 637 638 connection->state = AVCTP_W2_SEND_RESPONSE; 639 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 640 return ERROR_CODE_SUCCESS; 641 } 642 643 static uint8_t avrcp_target_subunit_info(avrcp_connection_t * connection, uint8_t offset){ 644 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 645 if (offset >= 32) return AVRCP_STATUS_INVALID_PARAMETER; 646 647 avrcp_target_custom_command_data_init(connection, AVRCP_CMD_OPCODE_SUBUNIT_INFO, 648 AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE, 649 AVRCP_SUBUNIT_TYPE_UNIT, AVRCP_SUBUNIT_ID_IGNORE, AVRCP_PDU_ID_UNDEFINED, 650 connection->company_id); 651 652 uint8_t page = offset / 4; 653 uint8_t extension_code = 7; 654 connection->data = connection->message_body; 655 connection->data_len = 5; 656 connection->data[0] = (page << 4) | extension_code; 657 658 // mark non-existent entries with 0xff 659 memset(&connection->message_body[1], 0xFF, 4); 660 if ((connection->data != NULL) && (offset < connection->target_subunit_info_data_size)){ 661 uint8_t bytes_to_copy = btstack_min(connection->target_subunit_info_data_size - offset, 4); 662 memcpy(&connection->data[1], &connection->target_subunit_info_data[offset], bytes_to_copy); 663 } 664 665 connection->state = AVCTP_W2_SEND_RESPONSE; 666 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 667 return ERROR_CODE_SUCCESS; 668 } 669 670 static uint8_t avrcp_target_response_vendor_dependent_supported_events(avrcp_connection_t * connection){ 671 avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE, AVRCP_PDU_ID_GET_CAPABILITIES); 672 673 uint8_t event_id; 674 uint8_t num_events = 0; 675 for (event_id = (uint8_t) AVRCP_NOTIFICATION_EVENT_FIRST_INDEX; event_id < (uint8_t) AVRCP_NOTIFICATION_EVENT_LAST_INDEX; event_id++){ 676 if ((connection->notifications_supported_by_target & (1 << event_id)) == 0){ 677 continue; 678 } 679 num_events++; 680 } 681 682 connection->data[0] = AVRCP_CAPABILITY_ID_EVENT; 683 connection->data[1] = num_events; 684 connection->data_len = 2 + num_events; 685 686 // fill the data later directly to the L2CAP outgoing buffer 687 connection->state = AVCTP_W2_SEND_RESPONSE; 688 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 689 return ERROR_CODE_SUCCESS; 690 } 691 692 static uint8_t avrcp_target_response_vendor_dependent_supported_companies(avrcp_connection_t * connection){ 693 avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE, AVRCP_PDU_ID_GET_CAPABILITIES); 694 695 connection->data[0] = AVRCP_CAPABILITY_ID_COMPANY; 696 if (connection->target_supported_companies_num == 0){ 697 connection->target_supported_companies_num = 1; 698 connection->target_supported_companies = default_companies; 699 } 700 701 connection->data[1] = connection->target_supported_companies_num; 702 connection->data_len = 2 + connection->data[1] * 3; 703 704 // fill the data later directly to the L2CAP outgoing buffer and 705 // use Bluetooth SIG as default company 706 connection->state = AVCTP_W2_SEND_RESPONSE; 707 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 708 return ERROR_CODE_SUCCESS; 709 } 710 711 uint8_t avrcp_target_support_event(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id){ 712 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 713 if (!connection){ 714 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 715 } 716 717 if ((event_id < (uint8_t)AVRCP_NOTIFICATION_EVENT_FIRST_INDEX) || (event_id > (uint8_t)AVRCP_NOTIFICATION_EVENT_LAST_INDEX)){ 718 return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; 719 } 720 721 connection->notifications_supported_by_target |= (1 << (uint8_t)event_id); 722 return ERROR_CODE_SUCCESS; 723 } 724 725 uint8_t avrcp_target_support_companies(uint16_t avrcp_cid, uint8_t num_companies, const uint32_t *companies){ 726 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 727 if (!connection){ 728 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 729 } 730 731 connection->target_supported_companies_num = num_companies; 732 connection->target_supported_companies = companies; 733 return ERROR_CODE_SUCCESS; 734 } 735 736 // TODO Review (use flags) 737 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){ 738 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 739 if (!connection){ 740 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 741 } 742 if (connection->state != AVCTP_CONNECTION_OPENED){ 743 return ERROR_CODE_COMMAND_DISALLOWED; 744 } 745 746 avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE, AVRCP_PDU_ID_GET_PLAY_STATUS); 747 connection->data_len = 9; 748 big_endian_store_32(connection->data, 0, song_length_ms); 749 big_endian_store_32(connection->data, 4, song_position_ms); 750 connection->data[8] = play_status; 751 752 connection->state = AVCTP_W2_SEND_RESPONSE; 753 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 754 return ERROR_CODE_SUCCESS; 755 } 756 757 static uint8_t avrcp_target_store_media_attr(avrcp_connection_t * connection, avrcp_media_attribute_id_t attr_id, const char * value){ 758 int index = attr_id - 1; 759 if (!value) return AVRCP_STATUS_INVALID_PARAMETER; 760 uint16_t value_len = (uint16_t)strlen(value); 761 btstack_assert(value_len <= 255); 762 connection->target_now_playing_info[index].value = (uint8_t*)value; 763 connection->target_now_playing_info[index].len = value_len; 764 return ERROR_CODE_SUCCESS; 765 } 766 767 uint8_t avrcp_target_set_playback_status(uint16_t avrcp_cid, avrcp_playback_status_t playback_status){ 768 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 769 if (!connection){ 770 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 771 } 772 if (connection->target_playback_status == playback_status){ 773 return ERROR_CODE_SUCCESS; 774 } 775 776 connection->target_playback_status = playback_status; 777 if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED)) { 778 connection->target_playback_status_changed = true; 779 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 780 } 781 return ERROR_CODE_SUCCESS; 782 } 783 784 static void avrcp_target_register_track_changed(avrcp_connection_t * connection, const uint8_t * track_id){ 785 if (track_id == NULL){ 786 memset(connection->target_track_id, 0xFF, 8); 787 connection->target_track_selected = false; 788 } else { 789 (void)memcpy(connection->target_track_id, track_id, 8); 790 connection->target_track_selected = true; 791 } 792 793 if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED)) { 794 connection->target_track_changed = true; 795 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 796 } 797 } 798 799 uint8_t avrcp_target_track_changed(uint16_t avrcp_cid, uint8_t * track_id){ 800 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 801 if (!connection){ 802 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 803 } 804 avrcp_target_register_track_changed(connection, track_id); 805 return ERROR_CODE_SUCCESS; 806 } 807 808 uint8_t avrcp_target_set_now_playing_info(uint16_t avrcp_cid, const avrcp_track_t * current_track, uint16_t total_tracks){ 809 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 810 if (!connection){ 811 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 812 } 813 if (!current_track){ 814 return ERROR_CODE_COMMAND_DISALLOWED; 815 } 816 817 (void)memcpy(connection->target_track_id, current_track->track_id, 8); 818 connection->target_song_length_ms = current_track->song_length_ms; 819 connection->target_track_nr = current_track->track_nr; 820 connection->target_total_tracks = total_tracks; 821 avrcp_target_store_media_attr(connection, AVRCP_MEDIA_ATTR_TITLE, current_track->title); 822 avrcp_target_store_media_attr(connection, AVRCP_MEDIA_ATTR_ARTIST, current_track->artist); 823 avrcp_target_store_media_attr(connection, AVRCP_MEDIA_ATTR_ALBUM, current_track->album); 824 avrcp_target_store_media_attr(connection, AVRCP_MEDIA_ATTR_GENRE, current_track->genre); 825 826 avrcp_target_register_track_changed(connection, current_track->track_id); 827 return ERROR_CODE_SUCCESS; 828 } 829 830 831 uint8_t avrcp_target_playing_content_changed(uint16_t avrcp_cid){ 832 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 833 if (!connection){ 834 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 835 } 836 if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED)) { 837 connection->target_playing_content_changed = true; 838 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 839 } 840 return ERROR_CODE_SUCCESS; 841 } 842 843 uint8_t avrcp_target_addressed_player_changed(uint16_t avrcp_cid, uint16_t player_id, uint16_t uid_counter){ 844 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 845 if (!connection){ 846 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 847 } 848 849 if (connection->target_addressed_player_id == player_id){ 850 return ERROR_CODE_SUCCESS; 851 } 852 853 connection->target_uid_counter = uid_counter; 854 connection->target_addressed_player_id = player_id; 855 856 if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED)) { 857 connection->target_addressed_player_changed = true; 858 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 859 } 860 return ERROR_CODE_SUCCESS; 861 } 862 863 uint8_t avrcp_target_uids_changed(uint16_t avrcp_cid, uint16_t uid_counter){ 864 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 865 if (!connection){ 866 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 867 } 868 869 connection->target_uid_counter = uid_counter; 870 871 if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED)) { 872 connection->target_uids_changed = true; 873 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 874 } 875 return ERROR_CODE_SUCCESS; 876 } 877 878 uint8_t avrcp_target_battery_status_changed(uint16_t avrcp_cid, avrcp_battery_status_t battery_status){ 879 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 880 if (!connection){ 881 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 882 } 883 if (connection->target_battery_status == battery_status){ 884 return ERROR_CODE_SUCCESS; 885 } 886 887 connection->target_battery_status = battery_status; 888 889 if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED)) { 890 connection->target_battery_status_changed = true; 891 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 892 } 893 return ERROR_CODE_SUCCESS; 894 } 895 896 uint8_t avrcp_target_adjust_absolute_volume(uint16_t avrcp_cid, uint8_t absolute_volume){ 897 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 898 if (!connection){ 899 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 900 } 901 902 connection->target_absolute_volume = absolute_volume; 903 return ERROR_CODE_SUCCESS; 904 } 905 906 uint8_t avrcp_target_volume_changed(uint16_t avrcp_cid, uint8_t absolute_volume){ 907 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid); 908 if (!connection){ 909 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 910 } 911 if (connection->target_absolute_volume == absolute_volume){ 912 return ERROR_CODE_SUCCESS; 913 } 914 915 connection->target_absolute_volume = absolute_volume; 916 917 if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED )) { 918 connection->target_notify_absolute_volume_changed = true; 919 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 920 } 921 return ERROR_CODE_SUCCESS; 922 } 923 924 static void avrcp_target_set_transaction_label_for_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t notification, uint8_t transaction_label){ 925 if (notification > AVRCP_NOTIFICATION_EVENT_MAX_VALUE) return; 926 connection->target_notifications_transaction_label[notification] = transaction_label; 927 } 928 929 static uint8_t avrcp_target_get_transaction_label_for_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t notification){ 930 if (notification > AVRCP_NOTIFICATION_EVENT_MAX_VALUE) return 0; 931 return connection->target_notifications_transaction_label[notification]; 932 } 933 934 static bool avcrp_operation_id_is_valid(avrcp_operation_id_t operation_id){ 935 if (operation_id < AVRCP_OPERATION_ID_RESERVED_1) return true; 936 937 if (operation_id < AVRCP_OPERATION_ID_0) return false; 938 if (operation_id < AVRCP_OPERATION_ID_RESERVED_2) return true; 939 940 if (operation_id < AVRCP_OPERATION_ID_CHANNEL_UP) return false; 941 if (operation_id < AVRCP_OPERATION_ID_RESERVED_3) return true; 942 943 if (operation_id < AVRCP_OPERATION_ID_CHANNEL_UP) return false; 944 if (operation_id < AVRCP_OPERATION_ID_RESERVED_3) return true; 945 946 if (operation_id < AVRCP_OPERATION_ID_SKIP) return false; 947 if (operation_id == AVRCP_OPERATION_ID_SKIP) return true; 948 949 if (operation_id < AVRCP_OPERATION_ID_POWER) return false; 950 if (operation_id < AVRCP_OPERATION_ID_RESERVED_4) return true; 951 952 if (operation_id < AVRCP_OPERATION_ID_ANGLE) return false; 953 if (operation_id < AVRCP_OPERATION_ID_RESERVED_5) return true; 954 955 if (operation_id < AVRCP_OPERATION_ID_F1) return false; 956 if (operation_id < AVRCP_OPERATION_ID_RESERVED_6) return true; 957 if (operation_id < AVRCP_OPERATION_ID_RESERVED_7) return true; 958 return false; 959 } 960 961 962 #ifdef ENABLE_AVCTP_FRAGMENTATION 963 static void avctp_reassemble_message(avrcp_connection_t * connection, avctp_packet_type_t packet_type, uint8_t *packet, uint16_t size){ 964 // after header (transaction label and packet type) 965 uint16_t pos; 966 uint16_t bytes_to_store; 967 968 switch (packet_type){ 969 case AVCTP_START_PACKET: 970 if (size < 2) return; 971 972 // store header 973 pos = 0; 974 connection->avctp_reassembly_buffer[pos] = packet[pos]; 975 pos++; 976 connection->avctp_reassembly_size = pos; 977 978 // NOTE: num packets not needed for reassembly, ignoring it does not pose security risk -> no need to store it 979 pos++; 980 981 // PID in reassembled packet is at offset 1, it will be read later after the avctp_reassemble_message with AVCTP_END_PACKET is called 982 983 bytes_to_store = btstack_min(size - pos, sizeof(connection->avctp_reassembly_buffer) - connection->avctp_reassembly_size); 984 memcpy(&connection->avctp_reassembly_buffer[connection->avctp_reassembly_size], &packet[pos], bytes_to_store); 985 connection->avctp_reassembly_size += bytes_to_store; 986 break; 987 988 case AVCTP_CONTINUE_PACKET: 989 case AVCTP_END_PACKET: 990 if (size < 1) return; 991 992 // store remaining data, ignore header 993 pos = 1; 994 bytes_to_store = btstack_min(size - pos, sizeof(connection->avctp_reassembly_buffer) - connection->avctp_reassembly_size); 995 memcpy(&connection->avctp_reassembly_buffer[connection->avctp_reassembly_size], &packet[pos], bytes_to_store); 996 connection->avctp_reassembly_size += bytes_to_store; 997 break; 998 999 default: 1000 return; 1001 } 1002 } 1003 #endif 1004 1005 static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connection_t * connection, uint8_t * packet, uint16_t size){ 1006 uint8_t avctp_header = packet[0]; 1007 connection->transaction_id = avctp_header >> 4; 1008 1009 avctp_packet_type_t avctp_packet_type = (avctp_packet_type_t) ((avctp_header & 0x0F) >> 2); 1010 switch (avctp_packet_type){ 1011 case AVCTP_SINGLE_PACKET: 1012 break; 1013 1014 #ifdef ENABLE_AVCTP_FRAGMENTATION 1015 case AVCTP_START_PACKET: 1016 case AVCTP_CONTINUE_PACKET: 1017 avctp_reassemble_message(connection, avctp_packet_type, packet, size); 1018 return; 1019 1020 case AVCTP_END_PACKET: 1021 avctp_reassemble_message(connection, avctp_packet_type, packet, size); 1022 1023 packet = connection->avctp_reassembly_buffer; 1024 size = connection->avctp_reassembly_size; 1025 break; 1026 #endif 1027 default: 1028 return; 1029 } 1030 1031 if (size < 6u) return; 1032 1033 uint16_t pid = big_endian_read_16(packet, 1); 1034 1035 if (pid != BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL){ 1036 log_info("Invalid pid 0x%02x, expected 0x%02x", pid, BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL); 1037 connection->target_reject_transport_header = true; 1038 connection->target_invalid_pid = pid; 1039 connection->state = AVCTP_W2_SEND_RESPONSE; 1040 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1041 return; 1042 } 1043 1044 // avrcp_subunit_type_t subunit_type = (avrcp_subunit_type_t) (packet[4] >> 3); 1045 // avrcp_subunit_id_t subunit_id = (avrcp_subunit_id_t) (packet[4] & 0x07); 1046 1047 avrcp_command_opcode_t opcode = (avrcp_command_opcode_t) avrcp_cmd_opcode(packet,size); 1048 1049 int pos = 6; 1050 uint16_t length; 1051 avrcp_pdu_id_t pdu_id; 1052 // connection->data_len = 0; 1053 uint8_t offset; 1054 uint8_t operand; 1055 uint16_t event_mask; 1056 avrcp_operation_id_t operation_id; 1057 1058 switch (opcode){ 1059 case AVRCP_CMD_OPCODE_UNIT_INFO: 1060 avrcp_target_unit_info(connection); 1061 break; 1062 case AVRCP_CMD_OPCODE_SUBUNIT_INFO: 1063 if ((size - pos) < 3) return; 1064 // page: packet[pos] >> 4, 1065 offset = 4 * (packet[pos]>>4); 1066 // extension code (fixed 7) = packet[pos] & 0x0F 1067 // 4 bytes paga data, all 0xFF 1068 avrcp_target_subunit_info(connection, offset); 1069 break; 1070 1071 case AVRCP_CMD_OPCODE_PASS_THROUGH: 1072 if (size < 8) return; 1073 log_info("AVRCP_OPERATION_ID 0x%02x, operands length %d", packet[6], packet[7]); 1074 operation_id = (avrcp_operation_id_t) (packet[6] & 0x7f); 1075 operand = 0; 1076 if ((packet[7] >= 1) && (size >= 9)){ 1077 operand = packet[8]; 1078 } 1079 1080 if (avcrp_operation_id_is_valid(operation_id)){ 1081 bool button_pressed = (packet[6] & 0x80) == 0; 1082 1083 avrcp_target_operation_accepted(connection->avrcp_cid, (avrcp_operation_id_t) packet[6], packet[7], operand); 1084 avrcp_target_emit_operation(avrcp_target_context.avrcp_callback, connection->avrcp_cid, 1085 operation_id, button_pressed, packet[7], operand); 1086 } else { 1087 avrcp_target_operation_not_implemented(connection->avrcp_cid, (avrcp_operation_id_t) packet[6], packet[7], operand); 1088 } 1089 break; 1090 1091 1092 case AVRCP_CMD_OPCODE_VENDOR_DEPENDENT: 1093 1094 if (size < 13) return; 1095 1096 // pos = 6 - company id 1097 (void)memcpy(connection->message_body, &packet[pos], 3); 1098 // connection->data_len = 3; 1099 pos += 3; 1100 // pos = 9 1101 pdu_id = (avrcp_pdu_id_t) packet[pos++]; 1102 // 1 - reserved 1103 pos++; 1104 // 2-3 param length, 1105 length = big_endian_read_16(packet, pos); 1106 pos += 2; 1107 // pos = 13 1108 switch (pdu_id){ 1109 case AVRCP_PDU_ID_PLAY_ITEM: 1110 if ( (pos + 11) > size){ 1111 avrcp_target_vendor_dependent_response_accept(connection, pdu_id, AVRCP_STATUS_INVALID_COMMAND); 1112 return; 1113 } 1114 1115 connection->target_scope = packet[pos++]; 1116 if (connection->target_scope >= AVRCP_BROWSING_RFU){ 1117 avrcp_target_vendor_dependent_response_accept(connection, pdu_id, AVRCP_STATUS_INVALID_PARAMETER); 1118 return; 1119 } 1120 memcpy(connection->target_track_id, &packet[pos], 8); 1121 pos += 8; 1122 connection->target_uid_counter = big_endian_read_16(packet,pos); 1123 connection->state = AVCTP_W2_CHECK_DATABASE; 1124 avrcp_target_emit_respond_play_item(avrcp_target_context.avrcp_callback, connection->avrcp_cid, connection->target_uid_counter, connection->target_scope,connection->target_track_id); 1125 break; 1126 1127 case AVRCP_PDU_ID_SET_ADDRESSED_PLAYER:{ 1128 if ((pos + 2) > size) return; 1129 bool ok = length == 4; 1130 if (avrcp_target_context.set_addressed_player_callback != NULL){ 1131 uint16_t player_id = big_endian_read_16(packet, pos); 1132 ok = avrcp_target_context.set_addressed_player_callback(player_id); 1133 } 1134 if (ok){ 1135 avrcp_target_vendor_dependent_response_accept(connection, pdu_id, AVRCP_STATUS_SUCCESS); 1136 } else { 1137 avrcp_target_response_vendor_dependent_reject(connection, pdu_id, AVRCP_STATUS_INVALID_PLAYER_ID); 1138 } 1139 break; 1140 } 1141 case AVRCP_PDU_ID_GET_CAPABILITIES:{ 1142 avrcp_capability_id_t capability_id = (avrcp_capability_id_t) packet[pos]; 1143 switch (capability_id){ 1144 case AVRCP_CAPABILITY_ID_EVENT: 1145 avrcp_target_response_vendor_dependent_supported_events(connection); 1146 break; 1147 case AVRCP_CAPABILITY_ID_COMPANY: 1148 avrcp_target_response_vendor_dependent_supported_companies(connection); 1149 break; 1150 default: 1151 avrcp_target_response_vendor_dependent_reject(connection, pdu_id, AVRCP_STATUS_INVALID_PARAMETER); 1152 break; 1153 } 1154 break; 1155 } 1156 case AVRCP_PDU_ID_GET_PLAY_STATUS: 1157 avrcp_target_emit_respond_vendor_dependent_query(avrcp_target_context.avrcp_callback, connection->avrcp_cid, AVRCP_SUBEVENT_PLAY_STATUS_QUERY); 1158 break; 1159 case AVRCP_PDU_ID_REQUEST_ABORT_CONTINUING_RESPONSE: 1160 if ((pos + 1) > size) return; 1161 connection->target_abort_continue_response = true; 1162 connection->state = AVCTP_W2_SEND_RESPONSE; 1163 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1164 break; 1165 case AVRCP_PDU_ID_REQUEST_CONTINUING_RESPONSE: 1166 if ((pos + 1) > size) return; 1167 if (packet[pos] != AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES){ 1168 avrcp_target_response_vendor_dependent_reject(connection, pdu_id, AVRCP_STATUS_INVALID_COMMAND); 1169 return; 1170 } 1171 connection->target_continue_response = true; 1172 connection->target_now_playing_info_response = true; 1173 connection->state = AVCTP_W2_SEND_RESPONSE; 1174 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1175 break; 1176 case AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES:{ 1177 if ((pos + 9) > size) return; 1178 uint8_t play_identifier[8]; 1179 memset(play_identifier, 0, 8); 1180 if (memcmp(&packet[pos], play_identifier, 8) != 0) { 1181 avrcp_target_response_vendor_dependent_reject(connection, pdu_id, AVRCP_STATUS_INVALID_PARAMETER); 1182 return; 1183 } 1184 pos += 8; 1185 uint8_t attribute_count = packet[pos++]; 1186 connection->next_attr_id = AVRCP_MEDIA_ATTR_NONE; 1187 if (!attribute_count){ 1188 connection->next_attr_id = AVRCP_MEDIA_ATTR_TITLE; 1189 connection->target_now_playing_info_attr_bitmap = 0xFE; 1190 } else { 1191 int i; 1192 connection->next_attr_id = AVRCP_MEDIA_ATTR_TITLE; 1193 connection->target_now_playing_info_attr_bitmap = 0; 1194 if ((pos + attribute_count * 4) > size) return; 1195 for (i=0; i < attribute_count; i++){ 1196 uint32_t attr_id = big_endian_read_32(packet, pos); 1197 connection->target_now_playing_info_attr_bitmap |= (1 << attr_id); 1198 pos += 4; 1199 } 1200 } 1201 log_info("target_now_playing_info_attr_bitmap 0x%02x", connection->target_now_playing_info_attr_bitmap); 1202 connection->target_now_playing_info_response = true; 1203 connection->state = AVCTP_W2_SEND_RESPONSE; 1204 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1205 break; 1206 } 1207 case AVRCP_PDU_ID_REGISTER_NOTIFICATION:{ 1208 if ((pos + 1) > size) return; 1209 avrcp_notification_event_id_t event_id = (avrcp_notification_event_id_t) packet[pos]; 1210 1211 avrcp_target_set_transaction_label_for_notification(connection, event_id, connection->transaction_id); 1212 1213 if (event_id < AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED || 1214 event_id > AVRCP_NOTIFICATION_EVENT_MAX_VALUE){ 1215 avrcp_target_response_vendor_dependent_reject(connection, pdu_id, AVRCP_STATUS_INVALID_PARAMETER); 1216 return; 1217 } 1218 1219 switch (event_id){ 1220 case AVRCP_NOTIFICATION_EVENT_AVAILABLE_PLAYERS_CHANGED: 1221 case AVRCP_NOTIFICATION_EVENT_PLAYER_APPLICATION_SETTING_CHANGED: 1222 case AVRCP_NOTIFICATION_EVENT_TRACK_REACHED_END: 1223 case AVRCP_NOTIFICATION_EVENT_TRACK_REACHED_START: 1224 case AVRCP_NOTIFICATION_EVENT_PLAYBACK_POS_CHANGED: 1225 case AVRCP_NOTIFICATION_EVENT_SYSTEM_STATUS_CHANGED: 1226 case AVRCP_NOTIFICATION_EVENT_MAX_VALUE: 1227 avrcp_target_response_vendor_dependent_not_implemented(connection, pdu_id, event_id); 1228 return; 1229 default: 1230 break; 1231 } 1232 1233 event_mask = (1 << event_id); 1234 connection->notifications_enabled |= event_mask; 1235 1236 switch (event_id){ 1237 case AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED:{ 1238 if (connection->target_uid_counter == 0){ 1239 connection->target_uid_counter = 1; 1240 } 1241 uint8_t value[2]; 1242 big_endian_store_16(value, 0, connection->target_uid_counter); 1243 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, value, 2); 1244 break; 1245 } 1246 1247 case AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED: 1248 if (connection->target_track_selected){ 1249 if (connection->target_total_tracks > 0){ 1250 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, connection->target_track_id, 8); 1251 break; 1252 } 1253 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, AVRCP_NOTIFICATION_TRACK_SELECTED, 8); 1254 } else { 1255 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, AVRCP_NOTIFICATION_TRACK_NOT_SELECTED, 8); 1256 } 1257 break; 1258 case AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED: 1259 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, (const uint8_t *)&connection->target_playback_status, 1); 1260 break; 1261 case AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED: 1262 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, NULL, 0); 1263 break; 1264 case AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED: 1265 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, (const uint8_t *)&connection->target_absolute_volume, 1); 1266 break; 1267 case AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED: 1268 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, (const uint8_t *)&connection->target_battery_status, 1); 1269 break; 1270 case AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED: 1271 avrcp_target_response_addressed_player_changed_interim(connection, pdu_id, event_id); 1272 return; 1273 default: 1274 btstack_assert(false); 1275 return; 1276 } 1277 break; 1278 } 1279 case AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME: { 1280 if ((pos + 1) > size ){ 1281 avrcp_target_response_vendor_dependent_reject(connection, pdu_id, AVRCP_STATUS_INVALID_COMMAND); 1282 break; 1283 } 1284 1285 if (length != 1){ 1286 avrcp_target_response_vendor_dependent_reject(connection, pdu_id, AVRCP_STATUS_SPECIFIED_PARAMETER_NOT_FOUND); 1287 break; 1288 } 1289 1290 uint8_t absolute_volume = packet[pos]; 1291 if (absolute_volume >= 0x80) { 1292 avrcp_target_response_vendor_dependent_reject(connection, pdu_id, AVRCP_STATUS_SPECIFIED_PARAMETER_NOT_FOUND); 1293 break; 1294 } 1295 connection->target_absolute_volume = absolute_volume; 1296 1297 avrcp_target_emit_volume_changed(avrcp_target_context.avrcp_callback, connection->avrcp_cid, connection->target_absolute_volume); 1298 avrcp_target_vendor_dependent_response_accept(connection, pdu_id, connection->target_absolute_volume); 1299 break; 1300 } 1301 default: 1302 log_info("AVRCP target: unhandled pdu id 0x%02x", pdu_id); 1303 avrcp_target_response_vendor_dependent_reject(connection, pdu_id, AVRCP_STATUS_INVALID_COMMAND); 1304 break; 1305 } 1306 break; 1307 default: 1308 log_info("AVRCP target: opcode 0x%02x not implemented", avrcp_cmd_opcode(packet,size)); 1309 break; 1310 } 1311 } 1312 1313 static void avrcp_target_notification_init(avrcp_connection_t * connection, avrcp_notification_event_id_t notification_id, uint8_t * value, uint16_t value_len){ 1314 btstack_assert(value_len + 1 < AVRCP_MAX_COMMAND_PARAMETER_LENGTH); 1315 avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_CHANGED_STABLE, AVRCP_PDU_ID_REGISTER_NOTIFICATION); 1316 connection->transaction_id = avrcp_target_get_transaction_label_for_notification(connection, notification_id); 1317 1318 connection->data_len = 1 + value_len; 1319 connection->data[0] = notification_id; 1320 if (value != NULL){ 1321 (void)memcpy(connection->data + 1, value, value_len); 1322 } 1323 } 1324 1325 static void avrcp_target_notification_addressed_player_changed_init(avrcp_connection_t * connection){ 1326 avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_CHANGED_STABLE, AVRCP_PDU_ID_REGISTER_NOTIFICATION); 1327 connection->transaction_id = avrcp_target_get_transaction_label_for_notification(connection, AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED); 1328 1329 connection->data_len = 5; 1330 connection->data[0] = AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED; 1331 big_endian_store_16(connection->data, 1, connection->target_addressed_player_id); 1332 big_endian_store_16(connection->data, 3, connection->target_uid_counter); 1333 } 1334 1335 1336 static void avrcp_target_reset_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t notification_id){ 1337 if (notification_id < AVRCP_NOTIFICATION_EVENT_FIRST_INDEX || notification_id > AVRCP_NOTIFICATION_EVENT_LAST_INDEX){ 1338 return; 1339 } 1340 connection->notifications_enabled &= ~(1 << notification_id); 1341 connection->target_notifications_transaction_label[notification_id] = 0; 1342 } 1343 1344 static void avrcp_request_next_avctp_segment(avrcp_connection_t * connection){ 1345 // AVCTP 1346 switch (connection->avctp_packet_type){ 1347 case AVCTP_END_PACKET: 1348 case AVCTP_SINGLE_PACKET: 1349 connection->state = AVCTP_CONNECTION_OPENED; 1350 break; 1351 default: 1352 connection->state = AVCTP_W2_SEND_RESPONSE; 1353 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1354 break; 1355 } 1356 } 1357 1358 static void avrcp_target_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 1359 avrcp_connection_t * connection; 1360 avrcp_notification_event_id_t notification_id = AVRCP_NOTIFICATION_EVENT_NONE; 1361 1362 switch (packet_type){ 1363 case L2CAP_DATA_PACKET: 1364 connection = avrcp_get_connection_for_l2cap_signaling_cid_for_role(AVRCP_TARGET, channel); 1365 avrcp_handle_l2cap_data_packet_for_signaling_connection(connection, packet, size); 1366 return; 1367 1368 case HCI_EVENT_PACKET: 1369 if (hci_event_packet_get_type(packet) != L2CAP_EVENT_CAN_SEND_NOW){ 1370 return; 1371 } 1372 1373 connection = avrcp_get_connection_for_l2cap_signaling_cid_for_role(AVRCP_TARGET, channel); 1374 if (connection == NULL){ 1375 return; 1376 } 1377 1378 if (connection->state == AVCTP_W2_SEND_RESPONSE){ 1379 // start AVCTP 1380 if (connection->target_reject_transport_header){ 1381 connection->target_reject_transport_header = false; 1382 avctp_send_reject_cmd_wrong_pid(connection); 1383 connection->state = AVCTP_CONNECTION_OPENED; 1384 return; 1385 } 1386 // end AVCTP 1387 1388 // start AVRCP 1389 if (connection->target_abort_continue_response){ 1390 connection->target_abort_continue_response = false; 1391 avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_ACCEPTED, AVRCP_PDU_ID_REQUEST_ABORT_CONTINUING_RESPONSE); 1392 break; 1393 } 1394 1395 if (connection->target_now_playing_info_response){ 1396 connection->target_now_playing_info_response = false; 1397 if (connection->target_continue_response){ 1398 connection->target_continue_response = false; 1399 if (connection->data_len == 0){ 1400 avrcp_target_response_vendor_dependent_reject(connection, connection->pdu_id, AVRCP_STATUS_INVALID_PARAMETER); 1401 return; 1402 } 1403 } else { 1404 avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE, AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES); 1405 connection->data_len = avrcp_now_playing_info_value_len_with_headers(connection); 1406 } 1407 break; 1408 } 1409 1410 // data already prepared 1411 break; 1412 } 1413 1414 // Notifications 1415 1416 if (connection->target_track_changed){ 1417 connection->target_track_changed = false; 1418 notification_id = AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED; 1419 avrcp_target_notification_init(connection, notification_id, connection->target_track_id, 8); 1420 break; 1421 } 1422 1423 if (connection->target_playback_status_changed){ 1424 connection->target_playback_status_changed = false; 1425 notification_id = AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED; 1426 uint8_t playback_status = (uint8_t) connection->target_playback_status; 1427 avrcp_target_notification_init(connection, notification_id, &playback_status, 1); 1428 break; 1429 } 1430 1431 if (connection->target_playing_content_changed){ 1432 connection->target_playing_content_changed = false; 1433 notification_id = AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED; 1434 avrcp_target_notification_init(connection, notification_id, NULL, 0); 1435 break; 1436 } 1437 1438 if (connection->target_battery_status_changed){ 1439 connection->target_battery_status_changed = false; 1440 notification_id = AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED; 1441 avrcp_target_notification_init(connection, notification_id, (uint8_t *)&connection->target_battery_status, 1); 1442 break; 1443 } 1444 1445 if (connection->target_notify_absolute_volume_changed){ 1446 connection->target_notify_absolute_volume_changed = false; 1447 notification_id = AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED; 1448 avrcp_target_notification_init(connection, notification_id, &connection->target_absolute_volume, 1); 1449 break; 1450 } 1451 1452 if (connection->target_addressed_player_changed){ 1453 connection->target_addressed_player_changed = false; 1454 notification_id = AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED; 1455 avrcp_target_notification_addressed_player_changed_init(connection); 1456 break; 1457 } 1458 1459 if (connection->target_uids_changed){ 1460 connection->target_uids_changed = false; 1461 notification_id = AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED; 1462 uint8_t value[2]; 1463 big_endian_store_16(value, 0, connection->target_uid_counter); 1464 avrcp_target_notification_init(connection, notification_id, value, 2); 1465 break; 1466 } 1467 // nothing to send, exit 1468 return; 1469 1470 default: 1471 return; 1472 } 1473 1474 avrcp_send_response_with_avctp_fragmentation(connection); 1475 avrcp_target_reset_notification(connection, notification_id); 1476 avrcp_request_next_avctp_segment(connection); 1477 } 1478 1479 void avrcp_target_init(void){ 1480 avrcp_target_context.role = AVRCP_TARGET; 1481 avrcp_target_context.packet_handler = avrcp_target_packet_handler; 1482 avrcp_register_target_packet_handler(&avrcp_target_packet_handler); 1483 } 1484 1485 void avrcp_target_deinit(void){ 1486 memset(&avrcp_target_context, 0, sizeof(avrcp_context_t)); 1487 } 1488 1489 void avrcp_target_register_packet_handler(btstack_packet_handler_t callback){ 1490 btstack_assert(callback != NULL); 1491 avrcp_target_context.avrcp_callback = callback; 1492 } 1493 1494 void avrcp_target_register_set_addressed_player_handler(bool (*callback)(uint16_t player_id)){ 1495 btstack_assert(callback != NULL); 1496 avrcp_target_context.set_addressed_player_callback = callback; 1497 } 1498 1499 1500 uint8_t avrcp_send_response_to_play_item(uint16_t avrcp_cid, avrcp_status_code_t status){ 1501 avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(avrcp_cid, AVRCP_TARGET); 1502 if (connection == NULL){ 1503 return ERROR_CODE_COMMAND_DISALLOWED; 1504 } 1505 if (connection->state != AVCTP_W2_CHECK_DATABASE){ 1506 return ERROR_CODE_COMMAND_DISALLOWED; 1507 } 1508 if (status != AVRCP_STATUS_SUCCESS){ 1509 return avrcp_target_response_vendor_dependent_reject(connection, AVRCP_PDU_ID_PLAY_ITEM, status); 1510 } 1511 return avrcp_target_vendor_dependent_response_accept(connection, AVRCP_PDU_ID_PLAY_ITEM, status); 1512 } 1513