1341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker/* 2341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker * Copyright 2018 The Android Open Source Project 3341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker * 4341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker * Licensed under the Apache License, Version 2.0 (the "License"); 5341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker * you may not use this file except in compliance with the License. 6341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker * You may obtain a copy of the License at 7341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker * 8341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker * http://www.apache.org/licenses/LICENSE-2.0 9341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker * 10341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker * Unless required by applicable law or agreed to in writing, software 11341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker * distributed under the License is distributed on an "AS IS" BASIS, 12341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker * See the License for the specific language governing permissions and 14341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker * limitations under the License. 15341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker */ 16341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 17341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker#include "capabilities_packet.h" 18341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 19341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickernamespace bluetooth { 20341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickernamespace avrcp { 21341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 22341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickerstd::unique_ptr<GetCapabilitiesRequestBuilder> 23341ab2befa059e859cdc67655d83bac14980ea9eAjay PanickerGetCapabilitiesRequestBuilder::MakeBuilder(Capability capability) { 24341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker std::unique_ptr<GetCapabilitiesRequestBuilder> builder( 25341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker new GetCapabilitiesRequestBuilder(capability)); 26341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 27341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker return builder; 28341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker} 29341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 30341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickersize_t GetCapabilitiesRequestBuilder::size() const { 318f7377353db29efe0a506123deec03d70935957aAjay Panicker return GetCapabilitiesRequest::kMinSize(); 32341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker} 33341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 34341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickerbool GetCapabilitiesRequestBuilder::Serialize( 35341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker const std::shared_ptr<::bluetooth::Packet>& pkt) { 36341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker ReserveSpace(pkt, size()); 37341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 38341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker // Push the standard avrcp headers 39341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker PacketBuilder::PushHeader(pkt); 40341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 41341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker // Push the avrcp vendor command headers, the parameter length is always 1 42341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker VendorPacketBuilder::PushHeader(pkt, 1); 43341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 44341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker // Push the capability 45341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker return AddPayloadOctets1(pkt, static_cast<uint8_t>(capability_)); 46341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker} 47341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 48341ab2befa059e859cdc67655d83bac14980ea9eAjay PanickerCapability GetCapabilitiesRequest::GetCapabilityRequested() const { 498f7377353db29efe0a506123deec03d70935957aAjay Panicker auto value = *(begin() + VendorPacket::kMinSize()); 50341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker return static_cast<Capability>(value); 51341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker} 52341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 53341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickerbool GetCapabilitiesRequest::IsValid() const { 54341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker if (!VendorPacket::IsValid()) return false; 558f7377353db29efe0a506123deec03d70935957aAjay Panicker return (size() == VendorPacket::kMinSize() + 1); 56341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker} 57341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 58341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickerstd::string GetCapabilitiesRequest::ToString() const { 59341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker std::stringstream ss; 60341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker ss << "AvrcpCapabilityReqPacket: " << std::endl; 61341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker ss << " └ cType = " << GetCType() << std::endl; 62341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker ss << " └ Subunit Type = " << loghex(GetSubunitType()) << std::endl; 63341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker ss << " └ Subunit ID = " << loghex(GetSubunitId()) << std::endl; 64341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker ss << " └ OpCode = " << GetOpcode() << std::endl; 65341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker ss << " └ Company ID = " << loghex(GetCompanyId()) << std::endl; 66341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker ss << " └ Command PDU = " << GetCommandPdu() << std::endl; 67341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker ss << " └ PacketType = " << GetPacketType() << std::endl; 68341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker ss << " └ Parameter Length = " << loghex(GetParameterLength()) << std::endl; 69341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker ss << " └ Capabilities Request = " << GetCapabilityRequested() << std::endl; 70341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker return ss.str(); 71341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker} 72341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 73341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickerstd::unique_ptr<GetCapabilitiesResponseBuilder> 74341ab2befa059e859cdc67655d83bac14980ea9eAjay PanickerGetCapabilitiesResponseBuilder::MakeCompanyIdBuilder( 75341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker uint32_t company_id_element) { 76341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker std::unique_ptr<GetCapabilitiesResponseBuilder> builder( 77341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker new GetCapabilitiesResponseBuilder(Capability::COMPANY_ID)); 78341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 79341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker company_id_element &= 0x00FFFFFF; 80341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker builder->elements_.insert(company_id_element); 81341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 82341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker return builder; 83341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker} 84341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 85341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickerstd::unique_ptr<GetCapabilitiesResponseBuilder> 86341ab2befa059e859cdc67655d83bac14980ea9eAjay PanickerGetCapabilitiesResponseBuilder::MakeEventsSupportedBuilder(Event event) { 87341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker std::unique_ptr<GetCapabilitiesResponseBuilder> builder( 88341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker new GetCapabilitiesResponseBuilder(Capability::EVENTS_SUPPORTED)); 89341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 90341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker builder->elements_.insert(static_cast<uint8_t>(event)); 91341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 92341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker return builder; 93341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker} 94341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 95341ab2befa059e859cdc67655d83bac14980ea9eAjay PanickerGetCapabilitiesResponseBuilder* GetCapabilitiesResponseBuilder::AddCompanyId( 96341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker uint32_t company_id) { 97341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker CHECK_EQ(capability_, Capability::COMPANY_ID); 98341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker CHECK_LT(elements_.size(), size_t(0xFF)) 99341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker << __func__ << ": maximum capability count reached"; 100341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 101341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker company_id &= 0x00FFFFFF; 102341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker elements_.insert(company_id); 103341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 104341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker return this; 105341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker} 106341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 107341ab2befa059e859cdc67655d83bac14980ea9eAjay PanickerGetCapabilitiesResponseBuilder* GetCapabilitiesResponseBuilder::AddEvent( 108341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker Event event) { 109341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker CHECK_EQ(capability_, Capability::EVENTS_SUPPORTED); 110341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker CHECK_LT(elements_.size(), size_t(0xFF)) 111341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker << __func__ << ": maximum capability count reached"; 112341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 113341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker elements_.insert(static_cast<uint8_t>(event)); 114341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 115341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker return this; 116341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker} 117341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 118341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickersize_t GetCapabilitiesResponseBuilder::size() const { 119341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker // Company ID's have a size of 3 while Events have a size of 1 120341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker size_t capability_count = elements_.size(); 121341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker size_t capability_size = capability_ == Capability::COMPANY_ID ? 3 : 1; 122341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 1238f7377353db29efe0a506123deec03d70935957aAjay Panicker return GetCapabilitiesResponse::kMinSize() + 124341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker (capability_count * capability_size); 125341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker} 126341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 127341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickerbool GetCapabilitiesResponseBuilder::Serialize( 128341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker const std::shared_ptr<::bluetooth::Packet>& pkt) { 129341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker ReserveSpace(pkt, size()); 130341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 131341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker // Push the standard avrcp headers 132341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker PacketBuilder::PushHeader(pkt); 133341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 134341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker // Push the avrcp vendor command headers 1358f7377353db29efe0a506123deec03d70935957aAjay Panicker uint16_t parameter_count = size() - VendorPacket::kMinSize(); 136341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker VendorPacketBuilder::PushHeader(pkt, parameter_count); 137341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 138341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker // Push the capability, capability count, and elements 139341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker AddPayloadOctets1(pkt, static_cast<uint8_t>(capability_)); 140341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker AddPayloadOctets1(pkt, elements_.size()); 141341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker for (auto it = elements_.begin(); it != elements_.end(); it++) { 142341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker if (capability_ == Capability::COMPANY_ID) 143341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker PushCompanyId(pkt, *it); 144341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker else 145341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker AddPayloadOctets1(pkt, *it); 146341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker } 147341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 148341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker return true; 149341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker} 150341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 151341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker} // namespace avrcp 152341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker} // namespace bluetooth