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