aboutsummaryrefslogtreecommitdiff
path: root/packet/avrcp
diff options
context:
space:
mode:
authorAjay Panicker <apanicke@google.com>2018-03-31 14:38:53 -0700
committerAjay Panicker <apanicke@google.com>2018-04-02 11:26:40 -0700
commite6552097abb756fcf92c24cc0cff4d7677fb0825 (patch)
tree842cd5f8eb72256193ecdcffdd383636e9677b23 /packet/avrcp
parent4e01c6d5f2d03fb5c98567b573a9dd32d28a4106 (diff)
downloadbt-e6552097abb756fcf92c24cc0cff4d7677fb0825.tar.gz
Add MTU Handling for AVRCP Packets
Bug: 77241554 Test: Run host native tests net_test_avrcp and net_test_btpacket Change-Id: If32aa506dc8f99220ef35efeb4d77a1023767afe
Diffstat (limited to 'packet/avrcp')
-rw-r--r--packet/avrcp/get_element_attributes_packet.cc32
-rw-r--r--packet/avrcp/get_element_attributes_packet.h18
-rw-r--r--packet/avrcp/get_folder_items.cc51
-rw-r--r--packet/avrcp/get_folder_items.h19
-rw-r--r--packet/avrcp/get_item_attributes.cc39
-rw-r--r--packet/avrcp/get_item_attributes.h17
-rw-r--r--packet/avrcp/vendor_packet.cc7
7 files changed, 108 insertions, 75 deletions
diff --git a/packet/avrcp/get_element_attributes_packet.cc b/packet/avrcp/get_element_attributes_packet.cc
index 43b51ee00..c26207e61 100644
--- a/packet/avrcp/get_element_attributes_packet.cc
+++ b/packet/avrcp/get_element_attributes_packet.cc
@@ -83,37 +83,41 @@ std::string GetElementAttributesRequest::ToString() const {
}
std::unique_ptr<GetElementAttributesResponseBuilder>
-GetElementAttributesResponseBuilder::MakeBuilder() {
+GetElementAttributesResponseBuilder::MakeBuilder(size_t mtu) {
std::unique_ptr<GetElementAttributesResponseBuilder> builder(
- new GetElementAttributesResponseBuilder());
+ new GetElementAttributesResponseBuilder(mtu));
return builder;
}
-GetElementAttributesResponseBuilder*
-GetElementAttributesResponseBuilder::AddAttributeEntry(AttributeEntry entry) {
+bool GetElementAttributesResponseBuilder::AddAttributeEntry(
+ AttributeEntry entry) {
CHECK_LT(entries_.size(), size_t(0xFF))
<< __func__ << ": attribute entry overflow";
- entries_.insert(entry);
+ size_t remaining_space = mtu_ - size();
+ if (entry.size() > remaining_space) {
+ entry.resize(remaining_space);
+ }
+
+ if (entry.empty()) {
+ return false;
+ }
- return this;
+ entries_.insert(entry);
+ return true;
}
-GetElementAttributesResponseBuilder*
-GetElementAttributesResponseBuilder::AddAttributeEntry(Attribute attribute,
- std::string value) {
+bool GetElementAttributesResponseBuilder::AddAttributeEntry(Attribute attribute,
+ std::string value) {
return AddAttributeEntry(AttributeEntry(attribute, value));
}
size_t GetElementAttributesResponseBuilder::size() const {
size_t attr_list_size = 0;
- for (auto attribute_entry : entries_) {
- attr_list_size += 4; // Size of attr entry
- attr_list_size += 2; // Size of value length field
- attr_list_size += 2; // Size of character encoding
- attr_list_size += attribute_entry.second.length();
+ for (auto& attribute_entry : entries_) {
+ attr_list_size += attribute_entry.size();
}
return VendorPacket::kMinSize() + 1 + attr_list_size;
diff --git a/packet/avrcp/get_element_attributes_packet.h b/packet/avrcp/get_element_attributes_packet.h
index 6f75b93bb..03fa8d1d1 100644
--- a/packet/avrcp/get_element_attributes_packet.h
+++ b/packet/avrcp/get_element_attributes_packet.h
@@ -16,7 +16,7 @@
#pragma once
-#include <map>
+#include <set>
#include "vendor_packet.h"
namespace bluetooth {
@@ -62,22 +62,24 @@ class GetElementAttributesResponseBuilder : public VendorPacketBuilder {
public:
virtual ~GetElementAttributesResponseBuilder() = default;
- static std::unique_ptr<GetElementAttributesResponseBuilder> MakeBuilder();
+ static std::unique_ptr<GetElementAttributesResponseBuilder> MakeBuilder(
+ size_t mtu);
- GetElementAttributesResponseBuilder* AddAttributeEntry(AttributeEntry entry);
- GetElementAttributesResponseBuilder* AddAttributeEntry(Attribute attribute,
- std::string value);
+ bool AddAttributeEntry(AttributeEntry entry);
+ bool AddAttributeEntry(Attribute attribute, std::string value);
virtual size_t size() const override;
virtual bool Serialize(
const std::shared_ptr<::bluetooth::Packet>& pkt) override;
private:
- std::map<Attribute, std::string> entries_;
+ std::set<AttributeEntry> entries_;
+ size_t mtu_;
- GetElementAttributesResponseBuilder()
+ GetElementAttributesResponseBuilder(size_t mtu)
: VendorPacketBuilder(CType::STABLE, CommandPdu::GET_ELEMENT_ATTRIBUTES,
- PacketType::SINGLE){};
+ PacketType::SINGLE),
+ mtu_(mtu){};
};
} // namespace avrcp
diff --git a/packet/avrcp/get_folder_items.cc b/packet/avrcp/get_folder_items.cc
index 5a267b15b..319960bbd 100644
--- a/packet/avrcp/get_folder_items.cc
+++ b/packet/avrcp/get_folder_items.cc
@@ -21,29 +21,32 @@ namespace avrcp {
std::unique_ptr<GetFolderItemsResponseBuilder>
GetFolderItemsResponseBuilder::MakePlayerListBuilder(Status status,
- uint16_t uid_counter) {
+ uint16_t uid_counter,
+ size_t mtu) {
std::unique_ptr<GetFolderItemsResponseBuilder> builder(
new GetFolderItemsResponseBuilder(Scope::MEDIA_PLAYER_LIST, status,
- uid_counter));
+ uid_counter, mtu));
return builder;
}
std::unique_ptr<GetFolderItemsResponseBuilder>
GetFolderItemsResponseBuilder::MakeVFSBuilder(Status status,
- uint16_t uid_counter) {
+ uint16_t uid_counter,
+ size_t mtu) {
std::unique_ptr<GetFolderItemsResponseBuilder> builder(
- new GetFolderItemsResponseBuilder(Scope::VFS, status, uid_counter));
+ new GetFolderItemsResponseBuilder(Scope::VFS, status, uid_counter, mtu));
return builder;
}
std::unique_ptr<GetFolderItemsResponseBuilder>
GetFolderItemsResponseBuilder::MakeNowPlayingBuilder(Status status,
- uint16_t uid_counter) {
+ uint16_t uid_counter,
+ size_t mtu) {
std::unique_ptr<GetFolderItemsResponseBuilder> builder(
- new GetFolderItemsResponseBuilder(Scope::NOW_PLAYING, status,
- uid_counter));
+ new GetFolderItemsResponseBuilder(Scope::NOW_PLAYING, status, uid_counter,
+ mtu));
return builder;
}
@@ -59,7 +62,7 @@ size_t GetFolderItemsResponseBuilder::size() const {
len += 2; // UID Counter
len += 2; // Number of Items;
for (const auto& item : items_) {
- len += MediaListItem::size(item);
+ len += item.size();
}
return len;
@@ -90,19 +93,31 @@ bool GetFolderItemsResponseBuilder::Serialize(
return true;
}
-void GetFolderItemsResponseBuilder::AddMediaPlayer(MediaPlayerItem item) {
+bool GetFolderItemsResponseBuilder::AddMediaPlayer(MediaPlayerItem item) {
CHECK(scope_ == Scope::MEDIA_PLAYER_LIST);
+
+ if (size() + item.size() > mtu_) return false;
+
items_.push_back(MediaListItem(item));
+ return true;
}
-void GetFolderItemsResponseBuilder::AddSong(MediaElementItem item) {
+bool GetFolderItemsResponseBuilder::AddSong(MediaElementItem item) {
CHECK(scope_ == Scope::VFS || scope_ == Scope::NOW_PLAYING);
+
+ if (size() + item.size() > mtu_) return false;
+
items_.push_back(MediaListItem(item));
+ return true;
}
-void GetFolderItemsResponseBuilder::AddFolder(FolderItem item) {
+bool GetFolderItemsResponseBuilder::AddFolder(FolderItem item) {
CHECK(scope_ == Scope::VFS);
+
+ if (size() + item.size() > mtu_) return false;
+
items_.push_back(MediaListItem(item));
+ return true;
}
void GetFolderItemsResponseBuilder::PushMediaListItem(
@@ -125,7 +140,7 @@ void GetFolderItemsResponseBuilder::PushMediaPlayerItem(
const std::shared_ptr<::bluetooth::Packet>& pkt,
const MediaPlayerItem& item) {
AddPayloadOctets1(pkt, 0x01); // Media Player Item
- uint16_t item_len = MediaPlayerItem::size(item) - 3;
+ uint16_t item_len = item.size() - 3;
AddPayloadOctets2(pkt, base::ByteSwap(item_len)); // Item length
AddPayloadOctets2(pkt, base::ByteSwap(item.id_)); // Player ID
AddPayloadOctets1(pkt, 0x01); // Player Type
@@ -168,7 +183,7 @@ void GetFolderItemsResponseBuilder::PushMediaPlayerItem(
void GetFolderItemsResponseBuilder::PushFolderItem(
const std::shared_ptr<::bluetooth::Packet>& pkt, const FolderItem& item) {
AddPayloadOctets1(pkt, 0x02); // Folder Item
- uint16_t item_len = FolderItem::size(item) - 3;
+ uint16_t item_len = item.size() - 3;
AddPayloadOctets2(pkt, base::ByteSwap(item_len));
AddPayloadOctets8(pkt, base::ByteSwap(item.uid_));
AddPayloadOctets1(pkt, item.folder_type_);
@@ -186,7 +201,7 @@ void GetFolderItemsResponseBuilder::PushMediaElementItem(
const std::shared_ptr<::bluetooth::Packet>& pkt,
const MediaElementItem& item) {
AddPayloadOctets1(pkt, 0x03); // Media Element Item
- uint16_t item_len = MediaElementItem::size(item) - 3;
+ uint16_t item_len = item.size() - 3;
AddPayloadOctets2(pkt, base::ByteSwap(item_len));
AddPayloadOctets8(pkt, base::ByteSwap(item.uid_));
AddPayloadOctets1(pkt, 0x00); // Media Type Audio
@@ -199,14 +214,14 @@ void GetFolderItemsResponseBuilder::PushMediaElementItem(
}
AddPayloadOctets1(pkt, (uint8_t)item.attributes_.size());
- for (const auto& attribute : item.attributes_) {
- AddPayloadOctets4(pkt, base::ByteSwap((uint32_t)attribute.first));
+ for (const auto& entry : item.attributes_) {
+ AddPayloadOctets4(pkt, base::ByteSwap((uint32_t)entry.attribute()));
AddPayloadOctets2(pkt,
base::ByteSwap((uint16_t)0x006a)); // UTF-8 Character Set
- std::string attr_val = attribute.second;
+ std::string attr_val = entry.value();
uint16_t attr_len = attr_val.size();
- ;
+
AddPayloadOctets2(pkt, base::ByteSwap(attr_len));
for (const uint8_t& byte : attr_val) {
AddPayloadOctets1(pkt, byte);
diff --git a/packet/avrcp/get_folder_items.h b/packet/avrcp/get_folder_items.h
index 1ab216a3d..454a3cee5 100644
--- a/packet/avrcp/get_folder_items.h
+++ b/packet/avrcp/get_folder_items.h
@@ -25,32 +25,35 @@ class GetFolderItemsResponseBuilder : public BrowsePacketBuilder {
public:
virtual ~GetFolderItemsResponseBuilder() = default;
static std::unique_ptr<GetFolderItemsResponseBuilder> MakePlayerListBuilder(
- Status status, uint16_t uid_counter);
+ Status status, uint16_t uid_counter, size_t mtu);
static std::unique_ptr<GetFolderItemsResponseBuilder> MakeVFSBuilder(
- Status status, uint16_t uid_counter);
+ Status status, uint16_t uid_counter, size_t mtu);
static std::unique_ptr<GetFolderItemsResponseBuilder> MakeNowPlayingBuilder(
- Status status, uint16_t uid_counter);
+ Status status, uint16_t uid_counter, size_t mtu);
virtual size_t size() const override;
virtual bool Serialize(
const std::shared_ptr<::bluetooth::Packet>& pkt) override;
- void AddMediaPlayer(MediaPlayerItem item);
- void AddSong(MediaElementItem item);
- void AddFolder(FolderItem item);
+ // Returns false if adding an item would exceed the MTU
+ bool AddMediaPlayer(MediaPlayerItem item);
+ bool AddSong(MediaElementItem item);
+ bool AddFolder(FolderItem item);
protected:
Scope scope_;
std::vector<MediaListItem> items_;
Status status_;
uint16_t uid_counter_;
+ size_t mtu_;
GetFolderItemsResponseBuilder(Scope scope, Status status,
- uint16_t uid_counter)
+ uint16_t uid_counter, size_t mtu)
: BrowsePacketBuilder(BrowsePdu::GET_FOLDER_ITEMS),
scope_(scope),
status_(status),
- uid_counter_(uid_counter){};
+ uid_counter_(uid_counter),
+ mtu_(mtu){};
private:
void PushMediaListItem(const std::shared_ptr<::bluetooth::Packet>& pkt,
diff --git a/packet/avrcp/get_item_attributes.cc b/packet/avrcp/get_item_attributes.cc
index e662437d7..34304744c 100644
--- a/packet/avrcp/get_item_attributes.cc
+++ b/packet/avrcp/get_item_attributes.cc
@@ -20,23 +20,31 @@ namespace bluetooth {
namespace avrcp {
std::unique_ptr<GetItemAttributesResponseBuilder>
-GetItemAttributesResponseBuilder::MakeBuilder(Status status) {
+GetItemAttributesResponseBuilder::MakeBuilder(Status status, size_t mtu) {
std::unique_ptr<GetItemAttributesResponseBuilder> builder(
- new GetItemAttributesResponseBuilder(status));
+ new GetItemAttributesResponseBuilder(status, mtu));
return builder;
}
-GetItemAttributesResponseBuilder*
-GetItemAttributesResponseBuilder::AddAttributeEntry(AttributeEntry entry) {
+bool GetItemAttributesResponseBuilder::AddAttributeEntry(AttributeEntry entry) {
CHECK(entries_.size() < 0xFF);
+
+ size_t remaining_space = mtu_ - size();
+ if (entry.size() > remaining_space) {
+ entry.resize(remaining_space);
+ }
+
+ if (entry.empty()) {
+ return false;
+ }
+
entries_.insert(entry);
- return this;
+ return true;
}
-GetItemAttributesResponseBuilder*
-GetItemAttributesResponseBuilder::AddAttributeEntry(Attribute attribute,
- std::string value) {
+bool GetItemAttributesResponseBuilder::AddAttributeEntry(Attribute attribute,
+ std::string value) {
return AddAttributeEntry(AttributeEntry(attribute, value));
}
@@ -46,11 +54,8 @@ size_t GetItemAttributesResponseBuilder::size() const {
if (status_ != Status::NO_ERROR) return len;
len += 1; // Number of attributes
- for (const auto& attribute_entry : entries_) {
- len += 4; // Size of attr entry
- len += 2; // Size of value length field
- len += 2; // Size of character encoding
- len += attribute_entry.second.length();
+ for (const auto& entry : entries_) {
+ len += entry.size();
}
return len;
}
@@ -65,13 +70,13 @@ bool GetItemAttributesResponseBuilder::Serialize(
if (status_ != Status::NO_ERROR) return true;
AddPayloadOctets1(pkt, entries_.size());
- for (auto attribute_entry : entries_) {
- AddPayloadOctets4(pkt, base::ByteSwap((uint32_t)attribute_entry.first));
+ for (auto entry : entries_) {
+ AddPayloadOctets4(pkt, base::ByteSwap((uint32_t)entry.attribute()));
uint16_t character_set = 0x006a; // UTF-8
AddPayloadOctets2(pkt, base::ByteSwap(character_set));
- uint16_t value_length = attribute_entry.second.length();
+ uint16_t value_length = entry.value().length();
AddPayloadOctets2(pkt, base::ByteSwap(value_length));
- for (const uint8_t& byte : attribute_entry.second) {
+ for (const uint8_t& byte : entry.value()) {
AddPayloadOctets1(pkt, byte);
}
}
diff --git a/packet/avrcp/get_item_attributes.h b/packet/avrcp/get_item_attributes.h
index efb50d1e4..aa1db7121 100644
--- a/packet/avrcp/get_item_attributes.h
+++ b/packet/avrcp/get_item_attributes.h
@@ -16,7 +16,7 @@
#pragma once
-#include <map>
+#include <set>
#include "avrcp_browse_packet.h"
@@ -28,10 +28,10 @@ class GetItemAttributesResponseBuilder : public BrowsePacketBuilder {
virtual ~GetItemAttributesResponseBuilder() = default;
static std::unique_ptr<GetItemAttributesResponseBuilder> MakeBuilder(
- Status status);
+ Status status, size_t mtu);
- GetItemAttributesResponseBuilder* AddAttributeEntry(AttributeEntry entry);
- GetItemAttributesResponseBuilder* AddAttributeEntry(Attribute, std::string);
+ bool AddAttributeEntry(AttributeEntry entry);
+ bool AddAttributeEntry(Attribute, std::string);
virtual size_t size() const override;
virtual bool Serialize(
@@ -39,10 +39,13 @@ class GetItemAttributesResponseBuilder : public BrowsePacketBuilder {
private:
Status status_;
- std::map<Attribute, std::string> entries_;
+ size_t mtu_;
+ std::set<AttributeEntry> entries_;
- GetItemAttributesResponseBuilder(Status status)
- : BrowsePacketBuilder(BrowsePdu::GET_ITEM_ATTRIBUTES), status_(status) {}
+ GetItemAttributesResponseBuilder(Status status, size_t mtu)
+ : BrowsePacketBuilder(BrowsePdu::GET_ITEM_ATTRIBUTES),
+ status_(status),
+ mtu_(mtu) {}
};
class GetItemAttributesRequest : public BrowsePacket {
diff --git a/packet/avrcp/vendor_packet.cc b/packet/avrcp/vendor_packet.cc
index ceb2eb05a..982cf8176 100644
--- a/packet/avrcp/vendor_packet.cc
+++ b/packet/avrcp/vendor_packet.cc
@@ -66,13 +66,14 @@ void VendorPacketBuilder::PushHeader(
bool VendorPacketBuilder::PushAttributeValue(
const std::shared_ptr<::bluetooth::Packet>& pkt,
const AttributeEntry& entry) {
- AddPayloadOctets4(pkt, base::ByteSwap(static_cast<uint32_t>(entry.first)));
+ AddPayloadOctets4(pkt,
+ base::ByteSwap(static_cast<uint32_t>(entry.attribute())));
uint16_t character_set = 0x006a; // UTF-8
AddPayloadOctets2(pkt, base::ByteSwap(character_set));
- uint16_t value_length = entry.second.length();
+ uint16_t value_length = entry.value().length();
AddPayloadOctets2(pkt, base::ByteSwap(value_length));
for (int i = 0; i < value_length; i++) {
- AddPayloadOctets1(pkt, entry.second[i]);
+ AddPayloadOctets1(pkt, entry.value()[i]);
}
return true;