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#pragma once 18341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 197bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker#include <set> 208f7377353db29efe0a506123deec03d70935957aAjay Panicker 212c822c94aa90b1014800633fe6f663d5598be196Ajay Panicker#include <base/sys_byteorder.h> 222c822c94aa90b1014800633fe6f663d5598be196Ajay Panicker 23341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickernamespace bluetooth { 24341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickernamespace avrcp { 25341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 26341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickerconstexpr uint32_t BLUETOOTH_COMPANY_ID = 0x001958; 27341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 282c822c94aa90b1014800633fe6f663d5598be196Ajay Panickerconstexpr uint8_t MAX_TRANSACTION_LABEL = 0xF; 292c822c94aa90b1014800633fe6f663d5598be196Ajay Panicker 30341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickerenum class CType : uint8_t { 31341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker CONTROL = 0x0, 32341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker STATUS = 0x1, 33341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker NOTIFY = 0x3, 34ff915a9f4d2f7a03f0a3b52b635fc6841a1188e3Myles Watson NOT_IMPLEMENTED = 0x8, 35341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker ACCEPTED = 0x9, 36341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker REJECTED = 0xa, 37341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker STABLE = 0xc, 38341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker CHANGED = 0xd, 39341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker INTERIM = 0xf, 40341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker}; 41341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 42341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickerenum class Opcode : uint8_t { 43341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker VENDOR = 0x00, 44341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker UNIT_INFO = 0x30, 45341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker SUBUNIT_INFO = 0x31, 46341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker PASS_THROUGH = 0x7c, 47341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker}; 48341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 49341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker// Found in AVRCP_v1.6.1 Section 4.5 Table 4.5 50341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker// Searching can be done in the spec by Camel Casing the constant name 51341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickerenum class CommandPdu : uint8_t { 52341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker GET_CAPABILITIES = 0x10, 53341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker LIST_APPLICATION_SETTING_ATTRIBUTES = 0x11, 54341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker GET_ELEMENT_ATTRIBUTES = 0x20, 55341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker GET_PLAY_STATUS = 0x30, 56341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker REGISTER_NOTIFICATION = 0x31, 570c348413fb8d0a579acb8178c7e006d751508a3eAjay Panicker SET_ABSOLUTE_VOLUME = 0x50, 588f7377353db29efe0a506123deec03d70935957aAjay Panicker SET_ADDRESSED_PLAYER = 0x60, 598f7377353db29efe0a506123deec03d70935957aAjay Panicker PLAY_ITEM = 0x74, 60341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker}; 61341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 62341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickerenum class PacketType : uint8_t { 63341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker SINGLE = 0x00, 64341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker}; 65341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 66341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickerenum class Capability : uint8_t { 67341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker COMPANY_ID = 0x02, 68341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker EVENTS_SUPPORTED = 0x03, 69341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker}; 70341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 71341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker// Found in AVRCP_v1.6.1 Section 28 Appendix H 72341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickerenum class Event : uint8_t { 73341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker PLAYBACK_STATUS_CHANGED = 0x01, 74341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker TRACK_CHANGED = 0x02, 75341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker PLAYBACK_POS_CHANGED = 0x05, 76341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker PLAYER_APPLICATION_SETTING_CHANGED = 0x08, 77341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker NOW_PLAYING_CONTENT_CHANGED = 0x09, 78341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker AVAILABLE_PLAYERS_CHANGED = 0x0a, 79341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker ADDRESSED_PLAYER_CHANGED = 0x0b, 80341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker UIDS_CHANGED = 0x0c, 81341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker VOLUME_CHANGED = 0x0d, 82341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker}; 83341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 84341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickerenum class Attribute : uint32_t { 85341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker TITLE = 0x01, 868f7377353db29efe0a506123deec03d70935957aAjay Panicker ARTIST_NAME = 0x02, 878f7377353db29efe0a506123deec03d70935957aAjay Panicker ALBUM_NAME = 0x03, 888f7377353db29efe0a506123deec03d70935957aAjay Panicker TRACK_NUMBER = 0x04, 898f7377353db29efe0a506123deec03d70935957aAjay Panicker TOTAL_NUMBER_OF_TRACKS = 0x05, 908f7377353db29efe0a506123deec03d70935957aAjay Panicker GENRE = 0x06, 918f7377353db29efe0a506123deec03d70935957aAjay Panicker PLAYING_TIME = 0x07, 928f7377353db29efe0a506123deec03d70935957aAjay Panicker DEFAULT_COVER_ART = 0x08, 93341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker}; 94341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 95341ab2befa059e859cdc67655d83bac14980ea9eAjay Panickerenum class Status : uint8_t { 96341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker INVALID_COMMAND = 0x00, 978f7377353db29efe0a506123deec03d70935957aAjay Panicker INVALID_PARAMETER = 0x01, 988f7377353db29efe0a506123deec03d70935957aAjay Panicker PARAMETER_CONTENT_ERROR = 0x02, 998f7377353db29efe0a506123deec03d70935957aAjay Panicker INTERNAL_ERROR = 0x03, 1008f7377353db29efe0a506123deec03d70935957aAjay Panicker NO_ERROR = 0x04, 1018f7377353db29efe0a506123deec03d70935957aAjay Panicker UIDS_CHANGED = 0x05, 1028f7377353db29efe0a506123deec03d70935957aAjay Panicker RESERVED = 0x06, 1038f7377353db29efe0a506123deec03d70935957aAjay Panicker INVALID_DIRECTION = 0x07, 1048f7377353db29efe0a506123deec03d70935957aAjay Panicker NOT_A_DIRECTORY = 0x08, 1058f7377353db29efe0a506123deec03d70935957aAjay Panicker DOES_NOT_EXIST = 0x09, 1068f7377353db29efe0a506123deec03d70935957aAjay Panicker INVALID_SCOPE = 0x0a, 1078f7377353db29efe0a506123deec03d70935957aAjay Panicker RANGE_OUT_OF_BOUNDS = 0xb, 1088f7377353db29efe0a506123deec03d70935957aAjay Panicker FOLDER_ITEM_NOT_PLAYABLE = 0x0c, 1098f7377353db29efe0a506123deec03d70935957aAjay Panicker MEDIA_IN_USE = 0x0d, 1108f7377353db29efe0a506123deec03d70935957aAjay Panicker NOW_PLAYING_LIST_FULL = 0x0e, 1118f7377353db29efe0a506123deec03d70935957aAjay Panicker SEARCH_NOT_SUPPORTED = 0x0f, 1128f7377353db29efe0a506123deec03d70935957aAjay Panicker SEARCH_IN_PROGRESS = 0x10, 1138f7377353db29efe0a506123deec03d70935957aAjay Panicker INVALID_PLAYER_ID = 0x11, 1148f7377353db29efe0a506123deec03d70935957aAjay Panicker PLAYER_NOT_BROWSABLE = 0x12, 1158f7377353db29efe0a506123deec03d70935957aAjay Panicker PLAYER_NOT_ADDRESSED = 0x13, 1168f7377353db29efe0a506123deec03d70935957aAjay Panicker NO_VALID_SEARCH_RESULTS = 0x14, 1178f7377353db29efe0a506123deec03d70935957aAjay Panicker NO_AVAILABLE_PLAYERS = 0x15, 1188f7377353db29efe0a506123deec03d70935957aAjay Panicker ADDRESSED_PLAYER_CHANGED = 0x16, 1198f7377353db29efe0a506123deec03d70935957aAjay Panicker}; 1208f7377353db29efe0a506123deec03d70935957aAjay Panicker 1218f7377353db29efe0a506123deec03d70935957aAjay Panickerenum class BrowsePdu : uint8_t { 1228f7377353db29efe0a506123deec03d70935957aAjay Panicker SET_BROWSED_PLAYER = 0x70, 1238f7377353db29efe0a506123deec03d70935957aAjay Panicker GET_FOLDER_ITEMS = 0x71, 1248f7377353db29efe0a506123deec03d70935957aAjay Panicker CHANGE_PATH = 0x72, 1258f7377353db29efe0a506123deec03d70935957aAjay Panicker GET_ITEM_ATTRIBUTES = 0x73, 1268f7377353db29efe0a506123deec03d70935957aAjay Panicker GET_TOTAL_NUMBER_OF_ITEMS = 0x75, 1273fbf8b4fff8b52b781fa611e0b62c97bca28d76ftedwang GENERAL_REJECT = 0xa0, 1288f7377353db29efe0a506123deec03d70935957aAjay Panicker}; 1298f7377353db29efe0a506123deec03d70935957aAjay Panicker 1308f7377353db29efe0a506123deec03d70935957aAjay Panickerenum class Scope : uint8_t { 1318f7377353db29efe0a506123deec03d70935957aAjay Panicker MEDIA_PLAYER_LIST = 0x00, 1328f7377353db29efe0a506123deec03d70935957aAjay Panicker VFS = 0x01, 1338f7377353db29efe0a506123deec03d70935957aAjay Panicker SEARCH = 0x02, 1348f7377353db29efe0a506123deec03d70935957aAjay Panicker NOW_PLAYING = 0x03, 1358f7377353db29efe0a506123deec03d70935957aAjay Panicker}; 1368f7377353db29efe0a506123deec03d70935957aAjay Panicker 1378f7377353db29efe0a506123deec03d70935957aAjay Panickerenum class Direction : uint8_t { 1388f7377353db29efe0a506123deec03d70935957aAjay Panicker UP = 0x00, 1398f7377353db29efe0a506123deec03d70935957aAjay Panicker DOWN = 0x01, 140341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker}; 141341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 14205c13ff0be3e638bbbd54786f60f3a3b17d1e1c0Ajay Panickerenum class KeyState : uint8_t { 14305c13ff0be3e638bbbd54786f60f3a3b17d1e1c0Ajay Panicker PUSHED = 0x00, 14405c13ff0be3e638bbbd54786f60f3a3b17d1e1c0Ajay Panicker RELEASED = 0x01, 14505c13ff0be3e638bbbd54786f60f3a3b17d1e1c0Ajay Panicker}; 14605c13ff0be3e638bbbd54786f60f3a3b17d1e1c0Ajay Panicker 1477bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panickerclass AttributeEntry { 1487bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker public: 1497bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker AttributeEntry(const Attribute& attribute, const std::string& value) 1507bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker : attribute_(attribute), value_(value) {} 1517bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker 1527bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker AttributeEntry(const Attribute& attribute) : attribute_(attribute) {} 1537bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker 1547bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker AttributeEntry(const AttributeEntry&) = default; 1557bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker 1567bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker Attribute attribute() const { return attribute_; } 1577bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker 1587bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker std::string value() const { return value_; } 1597bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker 1607bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker static constexpr size_t kHeaderSize() { 1617bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker size_t ret = 0; 1627bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker ret += 4; // Size of attribute field 1637bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker ret += 2; // Size of length field 1647bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker ret += 2; // Size of character encoding field 1657bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker return ret; 1667bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker } 1677bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker 1687bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker size_t size() const { return kHeaderSize() + value_.size(); } 1697bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker 1707bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker void resize(size_t new_size) { 1717bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker new_size = new_size < kHeaderSize() ? 0 : new_size - kHeaderSize(); 1727bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker if (value_.size() > new_size) { 1737bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker value_.resize(new_size); 1747bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker } 1757bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker } 1767bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker 1777bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker bool empty() { return value_.empty(); } 1787bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker 1797bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker bool operator<(const AttributeEntry& rhs) const { 1807bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker return attribute_ < rhs.attribute_; 1817bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker } 1827bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker 1837bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker private: 1847bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker Attribute attribute_; 1857bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker std::string value_; 1867bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker}; 1877bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker 1887bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panickerconstexpr size_t MAX_FIELD_LEN = 100; 189341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker 1908f7377353db29efe0a506123deec03d70935957aAjay Panickerstruct MediaPlayerItem { 1918f7377353db29efe0a506123deec03d70935957aAjay Panicker uint16_t id_; 1928f7377353db29efe0a506123deec03d70935957aAjay Panicker std::string name_; 1938f7377353db29efe0a506123deec03d70935957aAjay Panicker bool browsable_; 1948f7377353db29efe0a506123deec03d70935957aAjay Panicker 1957bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker MediaPlayerItem(uint16_t id, const std::string& name, bool browsable) 1967bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker : id_(id), name_(name), browsable_(browsable) { 1977bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker if (name_.size() > MAX_FIELD_LEN) { 1987bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker name_.resize(MAX_FIELD_LEN); 1997bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker } 2007bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker } 2018f7377353db29efe0a506123deec03d70935957aAjay Panicker 2028f7377353db29efe0a506123deec03d70935957aAjay Panicker MediaPlayerItem(const MediaPlayerItem&) = default; 2038f7377353db29efe0a506123deec03d70935957aAjay Panicker 2047bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker static constexpr size_t kHeaderSize() { 2058f7377353db29efe0a506123deec03d70935957aAjay Panicker size_t ret = 0; 2068f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 1; // Media Player Type 2078f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 2; // Item Length 2088f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 2; // Player Id 2098f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 1; // Player Type 2108f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 4; // Player Subtype 2118f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 1; // Play Status 2128f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 16; // Features 2138f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 2; // UTF-8 character set 2148f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 2; // Name Length 2158f7377353db29efe0a506123deec03d70935957aAjay Panicker return ret; 2168f7377353db29efe0a506123deec03d70935957aAjay Panicker } 2177bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker 2187bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker size_t size() const { return kHeaderSize() + name_.size(); } 2198f7377353db29efe0a506123deec03d70935957aAjay Panicker}; 2208f7377353db29efe0a506123deec03d70935957aAjay Panicker 2218f7377353db29efe0a506123deec03d70935957aAjay Panickerstruct FolderItem { 2228f7377353db29efe0a506123deec03d70935957aAjay Panicker uint64_t uid_; 2238f7377353db29efe0a506123deec03d70935957aAjay Panicker uint8_t folder_type_; 2248f7377353db29efe0a506123deec03d70935957aAjay Panicker bool is_playable_; 2258f7377353db29efe0a506123deec03d70935957aAjay Panicker std::string name_; 2268f7377353db29efe0a506123deec03d70935957aAjay Panicker 2278f7377353db29efe0a506123deec03d70935957aAjay Panicker FolderItem(uint64_t uid, uint8_t folder_type, bool is_playable, 2288f7377353db29efe0a506123deec03d70935957aAjay Panicker const std::string& name) 2298f7377353db29efe0a506123deec03d70935957aAjay Panicker : uid_(uid), 2308f7377353db29efe0a506123deec03d70935957aAjay Panicker folder_type_(folder_type), 2318f7377353db29efe0a506123deec03d70935957aAjay Panicker is_playable_(is_playable), 2327bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker name_(name) { 2337bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker if (name_.size() > MAX_FIELD_LEN) { 2347bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker name_.resize(MAX_FIELD_LEN); 2357bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker } 2367bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker } 2378f7377353db29efe0a506123deec03d70935957aAjay Panicker 2388f7377353db29efe0a506123deec03d70935957aAjay Panicker FolderItem(const FolderItem&) = default; 2398f7377353db29efe0a506123deec03d70935957aAjay Panicker 2407bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker static constexpr size_t kHeaderSize() { 2418f7377353db29efe0a506123deec03d70935957aAjay Panicker size_t ret = 0; 2428f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 1; // Folder Item Type 2438f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 2; // Item Length 2448f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 8; // Folder UID 2458f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 1; // Folder Type 2468f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 1; // Is Playable byte 2478f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 2; // UTF-8 Character Set 2488f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 2; // Name Length 2498f7377353db29efe0a506123deec03d70935957aAjay Panicker return ret; 2508f7377353db29efe0a506123deec03d70935957aAjay Panicker } 2517bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker 2527bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker size_t size() const { return kHeaderSize() + name_.size(); } 2538f7377353db29efe0a506123deec03d70935957aAjay Panicker}; 2548f7377353db29efe0a506123deec03d70935957aAjay Panicker 2558f7377353db29efe0a506123deec03d70935957aAjay Panicker// NOTE: We never use media type field because we only support audio types 2568f7377353db29efe0a506123deec03d70935957aAjay Panickerstruct MediaElementItem { 2578f7377353db29efe0a506123deec03d70935957aAjay Panicker uint64_t uid_ = 0; 2588f7377353db29efe0a506123deec03d70935957aAjay Panicker std::string name_; 2597bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker std::set<AttributeEntry> attributes_; 2607bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker 2617bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker // Truncate the name and attribute fields so that we don't have a single item 2627bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker // that can exceed the Browsing MTU 2637bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker MediaElementItem(uint64_t uid, const std::string& name, 2647bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker std::set<AttributeEntry> attributes) 2657bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker : uid_(uid), name_(name) { 2667bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker if (name_.size() > MAX_FIELD_LEN) { 2677bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker name_.resize(MAX_FIELD_LEN); 2687bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker } 2698f7377353db29efe0a506123deec03d70935957aAjay Panicker 2707bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker for (AttributeEntry val : attributes) { 2717bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker val.resize(MAX_FIELD_LEN); 2727bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker attributes_.insert(val); 2737bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker } 2747bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker } 2758f7377353db29efe0a506123deec03d70935957aAjay Panicker 2768f7377353db29efe0a506123deec03d70935957aAjay Panicker MediaElementItem(const MediaElementItem&) = default; 2778f7377353db29efe0a506123deec03d70935957aAjay Panicker 2787bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker size_t size() const { 2798f7377353db29efe0a506123deec03d70935957aAjay Panicker size_t ret = 0; 2808f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 1; // Media Element Item Type 2818f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 2; // Item Length 2828f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 8; // Item UID 2838f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 1; // Media Type 2848f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 2; // UTF-8 Character Set 2858f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 2; // Name Length 2867bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker ret += name_.size(); 2878f7377353db29efe0a506123deec03d70935957aAjay Panicker ret += 1; // Number of Attributes 2887bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker for (const auto& entry : attributes_) { 2897bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker ret += entry.size(); 2908f7377353db29efe0a506123deec03d70935957aAjay Panicker } 2918f7377353db29efe0a506123deec03d70935957aAjay Panicker 2928f7377353db29efe0a506123deec03d70935957aAjay Panicker return ret; 2938f7377353db29efe0a506123deec03d70935957aAjay Panicker } 2948f7377353db29efe0a506123deec03d70935957aAjay Panicker}; 2958f7377353db29efe0a506123deec03d70935957aAjay Panicker 2968f7377353db29efe0a506123deec03d70935957aAjay Panickerstruct MediaListItem { 2978f7377353db29efe0a506123deec03d70935957aAjay Panicker enum : uint8_t { PLAYER = 0x01, FOLDER = 0x02, SONG = 0x03 } type_; 2988f7377353db29efe0a506123deec03d70935957aAjay Panicker 2998f7377353db29efe0a506123deec03d70935957aAjay Panicker union { 3008f7377353db29efe0a506123deec03d70935957aAjay Panicker MediaPlayerItem player_; 3018f7377353db29efe0a506123deec03d70935957aAjay Panicker FolderItem folder_; 3028f7377353db29efe0a506123deec03d70935957aAjay Panicker MediaElementItem song_; 3038f7377353db29efe0a506123deec03d70935957aAjay Panicker }; 3048f7377353db29efe0a506123deec03d70935957aAjay Panicker 3058f7377353db29efe0a506123deec03d70935957aAjay Panicker MediaListItem(MediaPlayerItem item) : type_(PLAYER), player_(item) {} 3068f7377353db29efe0a506123deec03d70935957aAjay Panicker 3078f7377353db29efe0a506123deec03d70935957aAjay Panicker MediaListItem(FolderItem item) : type_(FOLDER), folder_(item) {} 3088f7377353db29efe0a506123deec03d70935957aAjay Panicker 3098f7377353db29efe0a506123deec03d70935957aAjay Panicker MediaListItem(MediaElementItem item) : type_(SONG), song_(item) {} 3108f7377353db29efe0a506123deec03d70935957aAjay Panicker 3118f7377353db29efe0a506123deec03d70935957aAjay Panicker MediaListItem(const MediaListItem& item) { 3128f7377353db29efe0a506123deec03d70935957aAjay Panicker type_ = item.type_; 3138f7377353db29efe0a506123deec03d70935957aAjay Panicker switch (item.type_) { 3148f7377353db29efe0a506123deec03d70935957aAjay Panicker case PLAYER: 3158f7377353db29efe0a506123deec03d70935957aAjay Panicker new (&player_) MediaPlayerItem(item.player_); 3168f7377353db29efe0a506123deec03d70935957aAjay Panicker return; 3178f7377353db29efe0a506123deec03d70935957aAjay Panicker case FOLDER: 3188f7377353db29efe0a506123deec03d70935957aAjay Panicker new (&folder_) FolderItem(item.folder_); 3198f7377353db29efe0a506123deec03d70935957aAjay Panicker return; 3208f7377353db29efe0a506123deec03d70935957aAjay Panicker case SONG: 3218f7377353db29efe0a506123deec03d70935957aAjay Panicker new (&song_) MediaElementItem(item.song_); 3228f7377353db29efe0a506123deec03d70935957aAjay Panicker return; 3238f7377353db29efe0a506123deec03d70935957aAjay Panicker } 3248f7377353db29efe0a506123deec03d70935957aAjay Panicker } 3258f7377353db29efe0a506123deec03d70935957aAjay Panicker 3268f7377353db29efe0a506123deec03d70935957aAjay Panicker ~MediaListItem() { 3278f7377353db29efe0a506123deec03d70935957aAjay Panicker switch (type_) { 3288f7377353db29efe0a506123deec03d70935957aAjay Panicker case PLAYER: 3298f7377353db29efe0a506123deec03d70935957aAjay Panicker player_.~MediaPlayerItem(); 3308f7377353db29efe0a506123deec03d70935957aAjay Panicker return; 3318f7377353db29efe0a506123deec03d70935957aAjay Panicker case FOLDER: 3328f7377353db29efe0a506123deec03d70935957aAjay Panicker folder_.~FolderItem(); 3338f7377353db29efe0a506123deec03d70935957aAjay Panicker return; 3348f7377353db29efe0a506123deec03d70935957aAjay Panicker case SONG: 3358f7377353db29efe0a506123deec03d70935957aAjay Panicker song_.~MediaElementItem(); 3368f7377353db29efe0a506123deec03d70935957aAjay Panicker return; 3378f7377353db29efe0a506123deec03d70935957aAjay Panicker } 3388f7377353db29efe0a506123deec03d70935957aAjay Panicker } 3398f7377353db29efe0a506123deec03d70935957aAjay Panicker 3407bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker size_t size() const { 3417bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker switch (type_) { 3428f7377353db29efe0a506123deec03d70935957aAjay Panicker case PLAYER: 3437bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker return player_.size(); 3448f7377353db29efe0a506123deec03d70935957aAjay Panicker case FOLDER: 3457bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker return folder_.size(); 3468f7377353db29efe0a506123deec03d70935957aAjay Panicker case SONG: 3477bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker return song_.size(); 3488f7377353db29efe0a506123deec03d70935957aAjay Panicker } 3498f7377353db29efe0a506123deec03d70935957aAjay Panicker } 3508f7377353db29efe0a506123deec03d70935957aAjay Panicker}; 3518f7377353db29efe0a506123deec03d70935957aAjay Panicker 3527bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panickerconstexpr size_t AVCT_HDR_LEN = 3; 3537bed53df63e72be19412e6519b2f23ed2565bdaeAjay Panicker 354341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker} // namespace avrcp 355341ab2befa059e859cdc67655d83bac14980ea9eAjay Panicker} // namespace bluetooth