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