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 void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connection_t * connection, uint8_t *packet, uint16_t size){ 745 746 if (size < 6u) return; 747 748 uint16_t pid = 0; 749 uint8_t transport_header = packet[0]; 750 connection->transaction_id = transport_header >> 4; 751 752 avrcp_packet_type_t packet_type = (avrcp_packet_type_t) ((transport_header & 0x0F) >> 2); 753 switch (packet_type){ 754 case AVRCP_SINGLE_PACKET: 755 pid = big_endian_read_16(packet, 1); 756 break; 757 case AVRCP_START_PACKET: 758 pid = big_endian_read_16(packet, 2); 759 break; 760 default: 761 break; 762 } 763 764 switch (packet_type){ 765 case AVRCP_SINGLE_PACKET: 766 case AVRCP_START_PACKET: 767 if (pid != BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL){ 768 log_info("Invalid pid 0x%02x, expected 0x%02x", connection->invalid_pid, BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL); 769 connection->reject_transport_header = 1; 770 connection->invalid_pid = pid; 771 connection->transport_header = (connection->transaction_id << 4) | (AVRCP_SINGLE_PACKET << 2 ) | (AVRCP_RESPONSE_FRAME << 1) | 1; 772 connection->state = AVCTP_W2_SEND_RESPONSE; 773 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 774 return; 775 } 776 break; 777 default: 778 break; 779 } 780 781 if (packet_type != AVRCP_SINGLE_PACKET) return; 782 783 avrcp_subunit_type_t subunit_type = (avrcp_subunit_type_t) (packet[4] >> 3); 784 avrcp_subunit_id_t subunit_id = (avrcp_subunit_id_t) (packet[4] & 0x07); 785 786 avrcp_command_opcode_t opcode = (avrcp_command_opcode_t) avrcp_cmd_opcode(packet,size); 787 788 int pos = 6; 789 uint16_t length; 790 avrcp_pdu_id_t pdu_id; 791 connection->cmd_operands_length = 0; 792 793 switch (opcode){ 794 case AVRCP_CMD_OPCODE_UNIT_INFO: 795 avrcp_target_unit_info(connection); 796 break; 797 case AVRCP_CMD_OPCODE_SUBUNIT_INFO:{ 798 if ((size - pos) < 3) return; 799 uint8_t offset = 4 * (packet[pos+2]>>4); 800 avrcp_target_subunit_info(connection, offset); 801 break; 802 } 803 case AVRCP_CMD_OPCODE_PASS_THROUGH:{ 804 if (size < 8) return; 805 log_info("AVRCP_OPERATION_ID 0x%02x, operands length %d", packet[6], packet[7]); 806 avrcp_operation_id_t operation_id = (avrcp_operation_id_t) (packet[6] & 0x7f); 807 bool button_pressed = (packet[6] & 0x80) == 0; 808 uint8_t operand = 0; 809 if ((packet[7] >= 1) && (size >= 9)){ 810 operand = packet[8]; 811 } 812 813 switch (operation_id){ 814 case AVRCP_OPERATION_ID_PLAY: 815 case AVRCP_OPERATION_ID_PAUSE: 816 case AVRCP_OPERATION_ID_STOP: 817 case AVRCP_OPERATION_ID_VOLUME_UP: 818 case AVRCP_OPERATION_ID_VOLUME_DOWN: 819 case AVRCP_OPERATION_ID_REWIND: 820 case AVRCP_OPERATION_ID_FAST_FORWARD: 821 case AVRCP_OPERATION_ID_FORWARD: 822 case AVRCP_OPERATION_ID_BACKWARD: 823 case AVRCP_OPERATION_ID_SKIP: 824 case AVRCP_OPERATION_ID_MUTE: 825 case AVRCP_OPERATION_ID_CHANNEL_UP: 826 case AVRCP_OPERATION_ID_CHANNEL_DOWN: 827 case AVRCP_OPERATION_ID_SELECT: 828 case AVRCP_OPERATION_ID_UP: 829 case AVRCP_OPERATION_ID_DOWN: 830 case AVRCP_OPERATION_ID_LEFT: 831 case AVRCP_OPERATION_ID_RIGHT: 832 case AVRCP_OPERATION_ID_ROOT_MENU: 833 avrcp_target_operation_accepted(connection->avrcp_cid, (avrcp_operation_id_t) packet[6], packet[7], operand); 834 avrcp_target_emit_operation(avrcp_target_context.avrcp_callback, connection->avrcp_cid, 835 operation_id, button_pressed, packet[7], operand); 836 break; 837 case AVRCP_OPERATION_ID_UNDEFINED: 838 avrcp_target_operation_not_implemented(connection->avrcp_cid, (avrcp_operation_id_t) packet[6], packet[7], operand); 839 return; 840 default: 841 avrcp_target_operation_not_implemented(connection->avrcp_cid, (avrcp_operation_id_t) packet[6], packet[7], operand); 842 return; 843 } 844 break; 845 } 846 847 case AVRCP_CMD_OPCODE_VENDOR_DEPENDENT: 848 849 if (size < 13) return; 850 851 // pos = 6 - company id 852 (void)memcpy(connection->cmd_operands, &packet[pos], 3); 853 connection->cmd_operands_length = 3; 854 pos += 3; 855 // pos = 9 856 pdu_id = (avrcp_pdu_id_t) packet[pos++]; 857 // 1 - reserved 858 pos++; 859 // 2-3 param length, 860 length = big_endian_read_16(packet, pos); 861 pos += 2; 862 // pos = 13 863 switch (pdu_id){ 864 case AVRCP_PDU_ID_SET_ADDRESSED_PLAYER:{ 865 if ((pos + 2) > size) return; 866 bool ok = length == 4; 867 if (avrcp_target_context.set_addressed_player_callback != NULL){ 868 uint16_t player_id = big_endian_read_16(packet, pos); 869 ok = avrcp_target_context.set_addressed_player_callback(player_id); 870 } 871 if (ok){ 872 avrcp_target_response_accept(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_SUCCESS); 873 } else { 874 avrcp_target_response_reject(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_INVALID_PLAYER_ID); 875 } 876 break; 877 } 878 case AVRCP_PDU_ID_GET_CAPABILITIES:{ 879 avrcp_capability_id_t capability_id = (avrcp_capability_id_t) packet[pos]; 880 switch (capability_id){ 881 case AVRCP_CAPABILITY_ID_EVENT: 882 avrcp_target_emit_respond_vendor_dependent_query(avrcp_target_context.avrcp_callback, connection->avrcp_cid, AVRCP_SUBEVENT_EVENT_IDS_QUERY); 883 break; 884 case AVRCP_CAPABILITY_ID_COMPANY: 885 avrcp_target_emit_respond_vendor_dependent_query(avrcp_target_context.avrcp_callback, connection->avrcp_cid, AVRCP_SUBEVENT_COMPANY_IDS_QUERY); 886 break; 887 default: 888 avrcp_target_response_reject(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_INVALID_PARAMETER); 889 break; 890 } 891 break; 892 } 893 case AVRCP_PDU_ID_GET_PLAY_STATUS: 894 avrcp_target_emit_respond_vendor_dependent_query(avrcp_target_context.avrcp_callback, connection->avrcp_cid, AVRCP_SUBEVENT_PLAY_STATUS_QUERY); 895 break; 896 case AVRCP_PDU_ID_REQUEST_ABORT_CONTINUING_RESPONSE: 897 if ((pos + 1) > size) return; 898 connection->cmd_operands[0] = packet[pos]; 899 connection->abort_continue_response = 1; 900 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 901 break; 902 case AVRCP_PDU_ID_REQUEST_CONTINUING_RESPONSE: 903 if ((pos + 1) > size) return; 904 if (packet[pos] != AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES){ 905 avrcp_target_response_reject(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_INVALID_COMMAND); 906 return; 907 } 908 connection->now_playing_info_response = 1; 909 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 910 break; 911 case AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES:{ 912 if ((pos + 9) > size) return; 913 uint8_t play_identifier[8]; 914 memset(play_identifier, 0, 8); 915 if (memcmp(&packet[pos], play_identifier, 8) != 0) { 916 avrcp_target_response_reject(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_INVALID_PARAMETER); 917 return; 918 } 919 pos += 8; 920 uint8_t attribute_count = packet[pos++]; 921 connection->next_attr_id = AVRCP_MEDIA_ATTR_NONE; 922 if (!attribute_count){ 923 connection->now_playing_info_attr_bitmap = 0xFE; 924 } else { 925 int i; 926 connection->now_playing_info_attr_bitmap = 0; 927 if ((pos + attribute_count * 2) > size) return; 928 for (i=0; i < attribute_count; i++){ 929 uint16_t attr_id = big_endian_read_16(packet, pos); 930 pos += 2; 931 connection->now_playing_info_attr_bitmap |= (1 << attr_id); 932 } 933 } 934 log_info("now_playing_info_attr_bitmap 0x%02x", connection->now_playing_info_attr_bitmap); 935 avrcp_target_now_playing_info(connection); 936 break; 937 } 938 case AVRCP_PDU_ID_REGISTER_NOTIFICATION:{ 939 if ((pos + 1) > size) return; 940 avrcp_notification_event_id_t event_id = (avrcp_notification_event_id_t) packet[pos]; 941 uint16_t event_mask = (1 << event_id); 942 avrcp_target_set_transaction_label_for_notification(connection, event_id, connection->transaction_id); 943 944 switch (event_id){ 945 case AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED: 946 connection->notifications_enabled |= event_mask; 947 avrcp_target_response_setup(connection, AVRCP_CTYPE_RESPONSE_INTERIM, subunit_type, subunit_id, opcode); 948 if (connection->track_selected){ 949 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, AVRCP_NOTIFICATION_TRACK_SELECTED, 8); 950 } else { 951 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, AVRCP_NOTIFICATION_TRACK_NOT_SELECTED, 8); 952 } 953 break; 954 case AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED: 955 connection->notifications_enabled |= event_mask; 956 avrcp_target_response_setup(connection, AVRCP_CTYPE_RESPONSE_INTERIM, subunit_type, subunit_id, opcode); 957 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, (const uint8_t *)&connection->playback_status, 1); 958 break; 959 case AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED: 960 connection->notifications_enabled |= event_mask; 961 avrcp_target_response_setup(connection, AVRCP_CTYPE_RESPONSE_INTERIM, subunit_type, subunit_id, opcode); 962 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, NULL, 0); 963 break; 964 case AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED: 965 connection->notify_volume_percentage_changed = 0; 966 connection->notifications_enabled |= event_mask; 967 avrcp_target_response_setup(connection, AVRCP_CTYPE_RESPONSE_INTERIM, subunit_type, subunit_id, opcode); 968 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, (const uint8_t *)&connection->volume_percentage, 1); 969 break; 970 case AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED: 971 connection->notifications_enabled |= event_mask; 972 avrcp_target_response_setup(connection, AVRCP_CTYPE_RESPONSE_INTERIM, subunit_type, subunit_id, opcode); 973 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, (const uint8_t *)&connection->battery_status, 1); 974 break; 975 case AVRCP_NOTIFICATION_EVENT_AVAILABLE_PLAYERS_CHANGED: 976 case AVRCP_NOTIFICATION_EVENT_PLAYER_APPLICATION_SETTING_CHANGED: 977 case AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED: 978 avrcp_target_response_not_implemented(connection, subunit_type, subunit_id, opcode, pdu_id, event_id); 979 return; 980 case AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED: 981 connection->notifications_enabled |= event_mask; 982 avrcp_target_response_addressed_player_changed_interim(connection, subunit_type, subunit_id, opcode, pdu_id); 983 return; 984 default: 985 avrcp_target_response_reject(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_INVALID_PARAMETER); 986 return; 987 } 988 break; 989 } 990 case AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME: { 991 if (length != 1){ 992 avrcp_target_response_reject(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_INVALID_COMMAND); 993 break; 994 } 995 996 if ((pos + 1) > size) return; 997 uint8_t absolute_volume = packet[pos]; 998 if (absolute_volume < 0x80){ 999 connection->volume_percentage = absolute_volume; 1000 } 1001 avrcp_target_response_accept(connection, subunit_type, subunit_id, opcode, pdu_id, connection->volume_percentage); 1002 avrcp_target_emit_volume_changed(avrcp_target_context.avrcp_callback, connection->avrcp_cid, connection->volume_percentage); 1003 break; 1004 } 1005 default: 1006 log_info("AVRCP target: unhandled pdu id 0x%02x", pdu_id); 1007 avrcp_target_response_reject(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_INVALID_COMMAND); 1008 break; 1009 } 1010 break; 1011 default: 1012 log_info("AVRCP target: opcode 0x%02x not implemented", avrcp_cmd_opcode(packet,size)); 1013 break; 1014 } 1015 } 1016 1017 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){ 1018 if (!connection){ 1019 log_error("avrcp tartget: could not find a connection."); 1020 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1021 } 1022 1023 btstack_assert((value_len == 0) || (value != NULL)); 1024 1025 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1026 connection->command_type = AVRCP_CTYPE_RESPONSE_CHANGED_STABLE; 1027 connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL; 1028 connection->subunit_id = AVRCP_SUBUNIT_ID; 1029 connection->transaction_id = avrcp_target_get_transaction_label_for_notification(connection, notification_id); 1030 1031 uint16_t pos = 0; 1032 l2cap_reserve_packet_buffer(); 1033 uint8_t * packet = l2cap_get_outgoing_buffer(); 1034 1035 // value <= 8 ==> pdu <= 22 < L2CAP Default MTU 1036 btstack_assert((14 + value_len) <= l2cap_get_remote_mtu_for_local_cid(connection->l2cap_signaling_cid)); 1037 1038 connection->packet_type = AVRCP_SINGLE_PACKET; 1039 packet[pos++] = (connection->transaction_id << 4) | (connection->packet_type << 2) | (AVRCP_RESPONSE_FRAME << 1) | 0; 1040 // Profile IDentifier (PID) 1041 packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8; 1042 packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF; 1043 1044 // command_type 1045 packet[pos++] = connection->command_type; 1046 // subunit_type | subunit ID 1047 packet[pos++] = (connection->subunit_type << 3) | connection->subunit_id; 1048 // opcode 1049 packet[pos++] = (uint8_t)connection->command_opcode; 1050 1051 // company id is 3 bytes long 1052 big_endian_store_24(packet, pos, BT_SIG_COMPANY_ID); 1053 pos += 3; 1054 1055 packet[pos++] = AVRCP_PDU_ID_REGISTER_NOTIFICATION; 1056 packet[pos++] = 0; 1057 1058 big_endian_store_16(packet, pos, 1 + value_len); 1059 pos += 2; 1060 packet[pos++] = notification_id; 1061 if (value_len > 0){ 1062 (void)memcpy(packet + pos, value, value_len); 1063 pos += value_len; 1064 } 1065 1066 return l2cap_send_prepared(cid, pos); 1067 } 1068 1069 static void avrcp_target_reset_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t notification_id){ 1070 if (!connection){ 1071 log_error("avrcp tartget: could not find a connection."); 1072 return; 1073 } 1074 connection->notifications_enabled &= ~(1 << notification_id); 1075 connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT; 1076 avrcp_target_set_transaction_label_for_notification(connection, notification_id, 0); 1077 } 1078 1079 static void avrcp_target_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 1080 avrcp_connection_t * connection; 1081 switch (packet_type) { 1082 case L2CAP_DATA_PACKET: 1083 connection = avrcp_get_connection_for_l2cap_signaling_cid_for_role(AVRCP_TARGET, channel); 1084 avrcp_handle_l2cap_data_packet_for_signaling_connection(connection, packet, size); 1085 break; 1086 case HCI_EVENT_PACKET: 1087 switch (hci_event_packet_get_type(packet)){ 1088 case L2CAP_EVENT_CAN_SEND_NOW:{ 1089 connection = avrcp_get_connection_for_l2cap_signaling_cid_for_role(AVRCP_TARGET, channel); 1090 1091 if (connection->accept_response){ 1092 connection->accept_response = 0; 1093 avrcp_target_send_response(connection->l2cap_signaling_cid, connection); 1094 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1095 return; 1096 } 1097 1098 if (connection->abort_continue_response){ 1099 connection->abort_continue_response = 0; 1100 connection->now_playing_info_response = 0; 1101 avrcp_target_abort_continue_response(connection->l2cap_signaling_cid, connection); 1102 return; 1103 } 1104 1105 if (connection->now_playing_info_response){ 1106 connection->now_playing_info_response = 0; 1107 avrcp_target_send_now_playing_info(connection->l2cap_signaling_cid, connection); 1108 return; 1109 } 1110 1111 if (connection->track_changed){ 1112 connection->track_changed = 0; 1113 avrcp_target_send_notification(connection->l2cap_signaling_cid, connection, AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED, connection->track_id, 8); 1114 avrcp_target_reset_notification(connection, AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED); 1115 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1116 return; 1117 } 1118 1119 if (connection->playback_status_changed){ 1120 connection->playback_status_changed = 0; 1121 uint8_t playback_status = (uint8_t) connection->playback_status; 1122 avrcp_target_send_notification(connection->l2cap_signaling_cid, connection, AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED, &playback_status, 1); 1123 avrcp_target_reset_notification(connection, AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED); 1124 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1125 return; 1126 } 1127 1128 if (connection->playing_content_changed){ 1129 connection->playing_content_changed = 0; 1130 avrcp_target_send_notification(connection->l2cap_signaling_cid, connection, AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED, NULL, 0); 1131 avrcp_target_reset_notification(connection, AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED); 1132 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1133 return; 1134 } 1135 1136 if (connection->battery_status_changed){ 1137 connection->battery_status_changed = 0; 1138 avrcp_target_send_notification(connection->l2cap_signaling_cid, connection, AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED, (uint8_t *)&connection->battery_status, 1); 1139 avrcp_target_reset_notification(connection, AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED); 1140 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1141 return; 1142 } 1143 1144 if (connection->notify_volume_percentage_changed){ 1145 connection->notify_volume_percentage_changed = 0; 1146 avrcp_target_send_notification(connection->l2cap_signaling_cid, connection, AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED, &connection->volume_percentage, 1); 1147 avrcp_target_reset_notification(connection, AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED); 1148 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1149 return; 1150 } 1151 1152 if (connection->reject_transport_header){ 1153 connection->state = AVCTP_CONNECTION_OPENED; 1154 connection->reject_transport_header = 0; 1155 l2cap_reserve_packet_buffer(); 1156 uint8_t * out_buffer = l2cap_get_outgoing_buffer(); 1157 out_buffer[0] = connection->transport_header; 1158 big_endian_store_16(out_buffer, 1, connection->invalid_pid); 1159 l2cap_send_prepared(connection->l2cap_signaling_cid, 3); 1160 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1161 return; 1162 } 1163 1164 switch (connection->state){ 1165 case AVCTP_W2_SEND_RESPONSE: 1166 connection->state = AVCTP_CONNECTION_OPENED; 1167 avrcp_target_send_response(connection->l2cap_signaling_cid, connection); 1168 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1169 return; 1170 default: 1171 break; 1172 } 1173 1174 break; 1175 } 1176 default: 1177 break; 1178 } 1179 default: 1180 break; 1181 } 1182 } 1183 1184 void avrcp_target_init(void){ 1185 avrcp_target_context.role = AVRCP_TARGET; 1186 avrcp_target_context.packet_handler = avrcp_target_packet_handler; 1187 avrcp_register_target_packet_handler(&avrcp_target_packet_handler); 1188 } 1189 1190 void avrcp_target_deinit(void){ 1191 memset(&avrcp_target_context, 0, sizeof(avrcp_context_t)); 1192 } 1193 1194 void avrcp_target_register_packet_handler(btstack_packet_handler_t callback){ 1195 btstack_assert(callback != NULL); 1196 avrcp_target_context.avrcp_callback = callback; 1197 } 1198 1199 void avrcp_target_register_set_addressed_player_handler(bool (*callback)(uint16_t player_id)){ 1200 btstack_assert(callback != NULL); 1201 avrcp_target_context.set_addressed_player_callback = callback; 1202 } 1203 1204 1205