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