1 /*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "capabilities_packet.h"
18
19 namespace bluetooth {
20 namespace avrcp {
21
22 std::unique_ptr<GetCapabilitiesRequestBuilder>
MakeBuilder(Capability capability)23 GetCapabilitiesRequestBuilder::MakeBuilder(Capability capability) {
24 std::unique_ptr<GetCapabilitiesRequestBuilder> builder(
25 new GetCapabilitiesRequestBuilder(capability));
26
27 return builder;
28 }
29
size() const30 size_t GetCapabilitiesRequestBuilder::size() const {
31 return GetCapabilitiesRequest::kMinSize();
32 }
33
Serialize(const std::shared_ptr<::bluetooth::Packet> & pkt)34 bool GetCapabilitiesRequestBuilder::Serialize(
35 const std::shared_ptr<::bluetooth::Packet>& pkt) {
36 ReserveSpace(pkt, size());
37
38 // Push the standard avrcp headers
39 PacketBuilder::PushHeader(pkt);
40
41 // Push the avrcp vendor command headers, the parameter length is always 1
42 VendorPacketBuilder::PushHeader(pkt, 1);
43
44 // Push the capability
45 return AddPayloadOctets1(pkt, static_cast<uint8_t>(capability_));
46 }
47
GetCapabilityRequested() const48 Capability GetCapabilitiesRequest::GetCapabilityRequested() const {
49 auto value = *(begin() + VendorPacket::kMinSize());
50 return static_cast<Capability>(value);
51 }
52
IsValid() const53 bool GetCapabilitiesRequest::IsValid() const {
54 if (!VendorPacket::IsValid()) return false;
55 return (size() == VendorPacket::kMinSize() + 1);
56 }
57
ToString() const58 std::string GetCapabilitiesRequest::ToString() const {
59 std::stringstream ss;
60 ss << "AvrcpCapabilityReqPacket: " << std::endl;
61 ss << " └ cType = " << GetCType() << std::endl;
62 ss << " └ Subunit Type = " << loghex(GetSubunitType()) << std::endl;
63 ss << " └ Subunit ID = " << loghex(GetSubunitId()) << std::endl;
64 ss << " └ OpCode = " << GetOpcode() << std::endl;
65 ss << " └ Company ID = " << loghex(GetCompanyId()) << std::endl;
66 ss << " └ Command PDU = " << GetCommandPdu() << std::endl;
67 ss << " └ PacketType = " << GetPacketType() << std::endl;
68 ss << " └ Parameter Length = " << loghex(GetParameterLength()) << std::endl;
69 ss << " └ Capabilities Request = " << GetCapabilityRequested() << std::endl;
70 return ss.str();
71 }
72
73 std::unique_ptr<GetCapabilitiesResponseBuilder>
MakeCompanyIdBuilder(uint32_t company_id_element)74 GetCapabilitiesResponseBuilder::MakeCompanyIdBuilder(
75 uint32_t company_id_element) {
76 std::unique_ptr<GetCapabilitiesResponseBuilder> builder(
77 new GetCapabilitiesResponseBuilder(Capability::COMPANY_ID));
78
79 company_id_element &= 0x00FFFFFF;
80 builder->elements_.insert(company_id_element);
81
82 return builder;
83 }
84
85 std::unique_ptr<GetCapabilitiesResponseBuilder>
MakeEventsSupportedBuilder(Event event)86 GetCapabilitiesResponseBuilder::MakeEventsSupportedBuilder(Event event) {
87 std::unique_ptr<GetCapabilitiesResponseBuilder> builder(
88 new GetCapabilitiesResponseBuilder(Capability::EVENTS_SUPPORTED));
89
90 builder->elements_.insert(static_cast<uint8_t>(event));
91
92 return builder;
93 }
94
AddCompanyId(uint32_t company_id)95 GetCapabilitiesResponseBuilder* GetCapabilitiesResponseBuilder::AddCompanyId(
96 uint32_t company_id) {
97 CHECK_EQ(capability_, Capability::COMPANY_ID);
98 CHECK_LT(elements_.size(), size_t(0xFF))
99 << __func__ << ": maximum capability count reached";
100
101 company_id &= 0x00FFFFFF;
102 elements_.insert(company_id);
103
104 return this;
105 }
106
AddEvent(Event event)107 GetCapabilitiesResponseBuilder* GetCapabilitiesResponseBuilder::AddEvent(
108 Event event) {
109 CHECK_EQ(capability_, Capability::EVENTS_SUPPORTED);
110 CHECK_LT(elements_.size(), size_t(0xFF))
111 << __func__ << ": maximum capability count reached";
112
113 elements_.insert(static_cast<uint8_t>(event));
114
115 return this;
116 }
117
size() const118 size_t GetCapabilitiesResponseBuilder::size() const {
119 // Company ID's have a size of 3 while Events have a size of 1
120 size_t capability_count = elements_.size();
121 size_t capability_size = capability_ == Capability::COMPANY_ID ? 3 : 1;
122
123 return GetCapabilitiesResponse::kMinSize() +
124 (capability_count * capability_size);
125 }
126
Serialize(const std::shared_ptr<::bluetooth::Packet> & pkt)127 bool GetCapabilitiesResponseBuilder::Serialize(
128 const std::shared_ptr<::bluetooth::Packet>& pkt) {
129 ReserveSpace(pkt, size());
130
131 // Push the standard avrcp headers
132 PacketBuilder::PushHeader(pkt);
133
134 // Push the avrcp vendor command headers
135 uint16_t parameter_count = size() - VendorPacket::kMinSize();
136 VendorPacketBuilder::PushHeader(pkt, parameter_count);
137
138 // Push the capability, capability count, and elements
139 AddPayloadOctets1(pkt, static_cast<uint8_t>(capability_));
140 AddPayloadOctets1(pkt, elements_.size());
141 for (auto it = elements_.begin(); it != elements_.end(); it++) {
142 if (capability_ == Capability::COMPANY_ID)
143 PushCompanyId(pkt, *it);
144 else
145 AddPayloadOctets1(pkt, *it);
146 }
147
148 return true;
149 }
150
151 } // namespace avrcp
152 } // namespace bluetooth