avrcp_controller.c (7c76cd61122c3b4d5e95cb50c249f0af13c896a8) avrcp_controller.c (c3b8c0a2ef52262b8ac0ada052c4f8297106104e)
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

--- 676 unchanged lines hidden (view full) ---

685 connection->notifications_enabled &= reset_event_mask;
686 connection->notifications_to_deregister &= reset_event_mask;
687 break;
688 }
689
690 avrcp_controller_emit_notification_for_event_id(connection->avrcp_cid, event_id, ctype, payload + pos, size - pos);
691}
692
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

--- 676 unchanged lines hidden (view full) ---

685 connection->notifications_enabled &= reset_event_mask;
686 connection->notifications_to_deregister &= reset_event_mask;
687 break;
688 }
689
690 avrcp_controller_emit_notification_for_event_id(connection->avrcp_cid, event_id, ctype, payload + pos, size - pos);
691}
692
693#ifdef ENABLE_AVCTP_FRAGMENTATION
694static void avctp_reassemble_message(avrcp_connection_t * connection, avctp_packet_type_t packet_type, uint8_t *packet, uint16_t size){
695 // after header (transaction label and packet type)
696 uint16_t pos;
697 uint16_t bytes_to_store;
698
699 switch (packet_type){
700 case AVCTP_START_PACKET:
701 if (size < 2) return;
702
703 // store header
704 pos = 0;
705 connection->avctp_reassembly_buffer[pos] = packet[pos];
706 pos++;
707 connection->avctp_reassembly_size = pos;
708
709 // NOTE: num packets not needed for reassembly, ignoring it does not pose security risk -> no need to store it
710 pos++;
711
712 // PID in reassembled packet is at offset 1, it will be read later after the avctp_reassemble_message with AVCTP_END_PACKET is called
713
714 bytes_to_store = btstack_min(size - pos, sizeof(connection->avctp_reassembly_buffer) - connection->avctp_reassembly_size);
715 memcpy(&connection->avctp_reassembly_buffer[connection->avctp_reassembly_size], &packet[pos], bytes_to_store);
716 connection->avctp_reassembly_size += bytes_to_store;
717 break;
718
719 case AVCTP_CONTINUE_PACKET:
720 case AVCTP_END_PACKET:
721 if (size < 1) return;
722
723 // store remaining data, ignore header
724 pos = 1;
725 bytes_to_store = btstack_min(size - pos, sizeof(connection->avctp_reassembly_buffer) - connection->avctp_reassembly_size);
726 memcpy(&connection->avctp_reassembly_buffer[connection->avctp_reassembly_size], &packet[pos], bytes_to_store);
727 connection->avctp_reassembly_size += bytes_to_store;
728 break;
729
730 default:
731 return;
732 }
733}
734#endif
735
693static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connection_t * connection, uint8_t *packet, uint16_t size){
694 if (size < 6u) return;
736static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connection_t * connection, uint8_t *packet, uint16_t size){
737 if (size < 6u) return;
695
696 uint8_t pdu_id;
738 uint8_t pdu_id;
697 uint8_t vendor_dependent_packet_type;
739 avrcp_packet_type_t vendor_dependent_packet_type;
698
740
699 connection->last_confirmed_transaction_id = packet[0] >> 4;
741 uint16_t pos = 0;
742 connection->last_confirmed_transaction_id = packet[pos] >> 4;
743 avrcp_frame_type_t frame_type = (avrcp_frame_type_t)((packet[pos] >> 1) & 0x01);
744 avctp_packet_type_t packet_type = (avctp_packet_type_t)((packet[pos] >> 2) & 0x03);
745 pos++;
700
746
701 avrcp_frame_type_t frame_type = (avrcp_frame_type_t)((packet[0] >> 1) & 0x01);
702 if (frame_type != AVRCP_RESPONSE_FRAME) return;
747 if (frame_type != AVRCP_RESPONSE_FRAME) return;
703
704 avrcp_packet_type_t packet_type = (avrcp_packet_type_t)((packet[0] >> 2) & 0x03);
748
705 switch (packet_type){
749 switch (packet_type){
706 case AVRCP_SINGLE_PACKET:
750 case AVCTP_SINGLE_PACKET:
707 break;
751 break;
752
753#ifdef ENABLE_AVCTP_FRAGMENTATION
754 case AVCTP_START_PACKET:
755 case AVCTP_CONTINUE_PACKET:
756 avctp_reassemble_message(connection, packet_type, packet, size);
757 return;
758
759 case AVCTP_END_PACKET:
760 avctp_reassemble_message(connection, packet_type, packet, size);
761
762 packet = connection->avctp_reassembly_buffer;
763 size = connection->avctp_reassembly_size;
764 break;
765#endif
766
708 default:
767 default:
709 log_info("Fragmentation is not supported");
710 return;
711 }
712
768 return;
769 }
770
713 uint16_t pos = 3;
771 pos += 2; // PID
772
714 avrcp_command_type_t ctype = (avrcp_command_type_t) packet[pos++];
715
716#ifdef ENABLE_LOG_INFO
717 uint8_t byte_value = packet[pos];
718 avrcp_subunit_type_t subunit_type = (avrcp_subunit_type_t) (byte_value >> 3);
773 avrcp_command_type_t ctype = (avrcp_command_type_t) packet[pos++];
774
775#ifdef ENABLE_LOG_INFO
776 uint8_t byte_value = packet[pos];
777 avrcp_subunit_type_t subunit_type = (avrcp_subunit_type_t) (byte_value >> 3);
719 avrcp_subunit_type_t subunit_id = (avrcp_subunit_type_t) (byte_value & 0x07);
778 avrcp_subunit_type_t subunit_id = (avrcp_subunit_type_t) (byte_value & 0x07);
720#endif
721 pos++;
722
723 uint8_t opcode = packet[pos++];
724 uint16_t param_length;
725
726 switch (opcode){
727 case AVRCP_CMD_OPCODE_SUBUNIT_INFO:{

--- 30 unchanged lines hidden (view full) ---

758 if ((size - pos) < 7) return;
759
760 // Company ID (3)
761 pos += 3;
762 pdu_id = packet[pos++];
763 vendor_dependent_packet_type = (avrcp_packet_type_t)(packet[pos++] & 0x03);
764 param_length = big_endian_read_16(packet, pos);
765 pos += 2;
779#endif
780 pos++;
781
782 uint8_t opcode = packet[pos++];
783 uint16_t param_length;
784
785 switch (opcode){
786 case AVRCP_CMD_OPCODE_SUBUNIT_INFO:{

--- 30 unchanged lines hidden (view full) ---

817 if ((size - pos) < 7) return;
818
819 // Company ID (3)
820 pos += 3;
821 pdu_id = packet[pos++];
822 vendor_dependent_packet_type = (avrcp_packet_type_t)(packet[pos++] & 0x03);
823 param_length = big_endian_read_16(packet, pos);
824 pos += 2;
766 log_info("operands length %d, remaining size %d", param_length, size - pos);
767
825
768 if ((size - pos) < param_length) return;
769
770 // handle asynchronous notifications, without changing state
771 if (pdu_id == AVRCP_PDU_ID_REGISTER_NOTIFICATION){
772 avrcp_controller_handle_notification(connection, ctype, packet + pos, size - pos);
773 break;
774 }
775

--- 847 unchanged lines hidden ---
826 if ((size - pos) < param_length) return;
827
828 // handle asynchronous notifications, without changing state
829 if (pdu_id == AVRCP_PDU_ID_REGISTER_NOTIFICATION){
830 avrcp_controller_handle_notification(connection, ctype, packet + pos, size - pos);
831 break;
832 }
833

--- 847 unchanged lines hidden ---