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