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