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 #pragma once
18 
19 #include <bluetooth/log.h>
20 
21 #include <iomanip>
22 #include <iostream>
23 #include <sstream>
24 #include <string>
25 #include <type_traits>
26 
27 #include "avrcp_common.h"
28 #include "macros.h"
29 
30 namespace bluetooth {
31 namespace avrcp {
32 
CTypeText(const CType & type)33 inline std::string CTypeText(const CType& type) {
34   switch (type) {
35     CASE_RETURN_TEXT(CType::CONTROL);
36     CASE_RETURN_TEXT(CType::STATUS);
37     CASE_RETURN_TEXT(CType::NOTIFY);
38     CASE_RETURN_TEXT(CType::ACCEPTED);
39     CASE_RETURN_TEXT(CType::REJECTED);
40     CASE_RETURN_TEXT(CType::STABLE);
41     CASE_RETURN_TEXT(CType::CHANGED);
42     CASE_RETURN_TEXT(CType::INTERIM);
43     default:
44       return std::format("Unknown CType: 0x{:x}", (uint8_t)type);
45   }
46 }
47 
48 inline std::ostream& operator<<(std::ostream& os, const CType& type) {
49   return os << CTypeText(type);
50 }
51 
OpcodeText(const Opcode & opcode)52 inline std::string OpcodeText(const Opcode& opcode) {
53   switch (opcode) {
54     CASE_RETURN_TEXT(Opcode::VENDOR);
55     CASE_RETURN_TEXT(Opcode::UNIT_INFO);
56     CASE_RETURN_TEXT(Opcode::SUBUNIT_INFO);
57     CASE_RETURN_TEXT(Opcode::PASS_THROUGH);
58     default:
59       return std::format("Unknown Opcode: 0x{:x}", (uint8_t)opcode);
60   }
61 }
62 
63 inline std::ostream& operator<<(std::ostream& os, const Opcode& opcode) {
64   return os << OpcodeText(opcode);
65 }
66 
CommandPduText(const CommandPdu & pdu)67 inline std::string CommandPduText(const CommandPdu& pdu) {
68   switch (pdu) {
69     CASE_RETURN_TEXT(CommandPdu::GET_CAPABILITIES);
70     CASE_RETURN_TEXT(CommandPdu::LIST_PLAYER_APPLICATION_SETTING_ATTRIBUTES);
71     CASE_RETURN_TEXT(CommandPdu::LIST_PLAYER_APPLICATION_SETTING_VALUES);
72     CASE_RETURN_TEXT(CommandPdu::GET_CURRENT_PLAYER_APPLICATION_SETTING_VALUE);
73     CASE_RETURN_TEXT(CommandPdu::SET_PLAYER_APPLICATION_SETTING_VALUE);
74     CASE_RETURN_TEXT(CommandPdu::GET_ELEMENT_ATTRIBUTES);
75     CASE_RETURN_TEXT(CommandPdu::GET_PLAY_STATUS);
76     CASE_RETURN_TEXT(CommandPdu::REGISTER_NOTIFICATION);
77     CASE_RETURN_TEXT(CommandPdu::SET_ABSOLUTE_VOLUME);
78     CASE_RETURN_TEXT(CommandPdu::SET_ADDRESSED_PLAYER);
79     CASE_RETURN_TEXT(CommandPdu::PLAY_ITEM);
80     default:
81       return std::format("Unknown Command PDU: 0x{:x}", (uint8_t)pdu);
82   }
83 }
84 
85 inline std::ostream& operator<<(std::ostream& os, const CommandPdu& pdu) {
86   return os << CommandPduText(pdu);
87 }
88 
PacketTypeText(const PacketType & type)89 inline std::string PacketTypeText(const PacketType& type) {
90   switch (type) {
91     CASE_RETURN_TEXT(PacketType::SINGLE);
92     default:
93       return std::format("Unknown Packet Type: 0x{:x}", (uint8_t)type);
94   }
95 }
96 
97 inline std::ostream& operator<<(std::ostream& os, const PacketType& type) {
98   return os << PacketTypeText(type);
99 }
100 
CapabilityText(const Capability & cap)101 inline std::string CapabilityText(const Capability& cap) {
102   switch (cap) {
103     CASE_RETURN_TEXT(Capability::COMPANY_ID);
104     CASE_RETURN_TEXT(Capability::EVENTS_SUPPORTED);
105     default:
106       return std::format("Unknown Capability: 0x{:x}", (uint8_t)cap);
107   }
108 }
109 
110 inline std::ostream& operator<<(std::ostream& os, const Capability& cap) {
111   return os << CapabilityText(cap);
112 }
113 
EventText(const Event & event)114 inline std::string EventText(const Event& event) {
115   switch (event) {
116     CASE_RETURN_TEXT(Event::PLAYBACK_STATUS_CHANGED);
117     CASE_RETURN_TEXT(Event::TRACK_CHANGED);
118     CASE_RETURN_TEXT(Event::PLAYBACK_POS_CHANGED);
119     CASE_RETURN_TEXT(Event::PLAYER_APPLICATION_SETTING_CHANGED);
120     CASE_RETURN_TEXT(Event::NOW_PLAYING_CONTENT_CHANGED);
121     CASE_RETURN_TEXT(Event::AVAILABLE_PLAYERS_CHANGED);
122     CASE_RETURN_TEXT(Event::ADDRESSED_PLAYER_CHANGED);
123     CASE_RETURN_TEXT(Event::UIDS_CHANGED);
124     CASE_RETURN_TEXT(Event::VOLUME_CHANGED);
125     default:
126       return std::format("Unknown Event: 0x{:x}", (uint8_t)event);
127   }
128 }
129 
130 inline std::ostream& operator<<(std::ostream& os, const Event& event) {
131   return os << EventText(event);
132 }
133 
AttributeText(const Attribute & attr)134 inline std::string AttributeText(const Attribute& attr) {
135   switch (attr) {
136     CASE_RETURN_TEXT(Attribute::TITLE);
137     CASE_RETURN_TEXT(Attribute::ARTIST_NAME);
138     CASE_RETURN_TEXT(Attribute::ALBUM_NAME);
139     CASE_RETURN_TEXT(Attribute::TRACK_NUMBER);
140     CASE_RETURN_TEXT(Attribute::TOTAL_NUMBER_OF_TRACKS);
141     CASE_RETURN_TEXT(Attribute::GENRE);
142     CASE_RETURN_TEXT(Attribute::PLAYING_TIME);
143     CASE_RETURN_TEXT(Attribute::DEFAULT_COVER_ART);
144     default:
145       return std::format("Unknown Attribute Value: 0x{:x}", (uint32_t)attr);
146   }
147 }
148 
149 inline std::ostream& operator<<(std::ostream& os, const Attribute& attr) {
150   return os << AttributeText(attr);
151 }
152 
StatusText(const Status & status)153 inline std::string StatusText(const Status& status) {
154   switch (status) {
155     CASE_RETURN_TEXT(Status::INVALID_COMMAND);
156     CASE_RETURN_TEXT(Status::INVALID_PARAMETER);
157     CASE_RETURN_TEXT(Status::PARAMETER_CONTENT_ERROR);
158     CASE_RETURN_TEXT(Status::INTERNAL_ERROR);
159     CASE_RETURN_TEXT(Status::NO_ERROR);
160     CASE_RETURN_TEXT(Status::UIDS_CHANGED);
161     CASE_RETURN_TEXT(Status::RESERVED);
162     CASE_RETURN_TEXT(Status::INVALID_DIRECTION);
163     CASE_RETURN_TEXT(Status::NOT_A_DIRECTORY);
164     CASE_RETURN_TEXT(Status::DOES_NOT_EXIST);
165     CASE_RETURN_TEXT(Status::INVALID_SCOPE);
166     CASE_RETURN_TEXT(Status::RANGE_OUT_OF_BOUNDS);
167     CASE_RETURN_TEXT(Status::FOLDER_ITEM_NOT_PLAYABLE);
168     CASE_RETURN_TEXT(Status::MEDIA_IN_USE);
169     CASE_RETURN_TEXT(Status::NOW_PLAYING_LIST_FULL);
170     CASE_RETURN_TEXT(Status::SEARCH_NOT_SUPPORTED);
171     CASE_RETURN_TEXT(Status::SEARCH_IN_PROGRESS);
172     CASE_RETURN_TEXT(Status::INVALID_PLAYER_ID);
173     CASE_RETURN_TEXT(Status::PLAYER_NOT_BROWSABLE);
174     CASE_RETURN_TEXT(Status::PLAYER_NOT_ADDRESSED);
175     CASE_RETURN_TEXT(Status::NO_VALID_SEARCH_RESULTS);
176     CASE_RETURN_TEXT(Status::NO_AVAILABLE_PLAYERS);
177     CASE_RETURN_TEXT(Status::ADDRESSED_PLAYER_CHANGED);
178     default:
179       return std::format("Unknown Status: 0x{:x}", (uint8_t)status);
180   }
181 }
182 
183 inline std::ostream& operator<<(std::ostream& os, const Status& status) {
184   return os << StatusText(status);
185 }
186 
BrowsePduText(const BrowsePdu & pdu)187 inline std::string BrowsePduText(const BrowsePdu& pdu) {
188   switch (pdu) {
189     CASE_RETURN_TEXT(BrowsePdu::SET_BROWSED_PLAYER);
190     CASE_RETURN_TEXT(BrowsePdu::GET_FOLDER_ITEMS);
191     CASE_RETURN_TEXT(BrowsePdu::CHANGE_PATH);
192     CASE_RETURN_TEXT(BrowsePdu::GET_ITEM_ATTRIBUTES);
193     default:
194       return std::format("Unknown Browse PDU: 0x{:x}", (uint8_t)pdu);
195   }
196 }
197 
198 inline std::ostream& operator<<(std::ostream& os, const BrowsePdu& pdu) {
199   return os << BrowsePduText(pdu);
200 }
201 
ScopeText(const Scope & scope)202 inline std::string ScopeText(const Scope& scope) {
203   switch (scope) {
204     CASE_RETURN_TEXT(Scope::MEDIA_PLAYER_LIST);
205     CASE_RETURN_TEXT(Scope::VFS);
206     CASE_RETURN_TEXT(Scope::SEARCH);
207     CASE_RETURN_TEXT(Scope::NOW_PLAYING);
208     default:
209       return std::format("Unknown Scope: 0x{:x}", (uint8_t)scope);
210   }
211 }
212 
213 inline std::ostream& operator<<(std::ostream& os, const Scope& pdu) { return os << ScopeText(pdu); }
214 
DirectionText(const Direction & dir)215 inline std::string DirectionText(const Direction& dir) {
216   switch (dir) {
217     CASE_RETURN_TEXT(Direction::UP);
218     CASE_RETURN_TEXT(Direction::DOWN);
219     default:
220       return std::format("Unknown Direction: 0x{:x}", (uint8_t)dir);
221   }
222 }
223 
224 inline std::ostream& operator<<(std::ostream& os, const Direction& dir) {
225   return os << DirectionText(dir);
226 }
227 
KeyStateText(const KeyState & state)228 inline std::string KeyStateText(const KeyState& state) {
229   switch (state) {
230     CASE_RETURN_TEXT(KeyState::PUSHED);
231     CASE_RETURN_TEXT(KeyState::RELEASED);
232     default:
233       return std::format("Unknown KeyState: 0x{:x}", (uint8_t)state);
234   }
235 }
236 
237 inline std::ostream& operator<<(std::ostream& os, const KeyState& dir) {
238   return os << KeyStateText(dir);
239 }
240 
PlayerAttributeText(const PlayerAttribute & attr)241 inline std::string PlayerAttributeText(const PlayerAttribute& attr) {
242   switch (attr) {
243     CASE_RETURN_TEXT(PlayerAttribute::EQUALIZER);
244     CASE_RETURN_TEXT(PlayerAttribute::REPEAT);
245     CASE_RETURN_TEXT(PlayerAttribute::SHUFFLE);
246     CASE_RETURN_TEXT(PlayerAttribute::SCAN);
247   }
248   return std::format("Unknown Player Attribute: 0x{:x}", (uint8_t)attr);
249 }
250 
251 inline std::ostream& operator<<(std::ostream& os, const PlayerAttribute& attr) {
252   return os << PlayerAttributeText(attr);
253 }
254 
PlayerRepeatValueText(const PlayerRepeatValue & val)255 inline std::string PlayerRepeatValueText(const PlayerRepeatValue& val) {
256   switch (val) {
257     CASE_RETURN_TEXT(PlayerRepeatValue::OFF);
258     CASE_RETURN_TEXT(PlayerRepeatValue::SINGLE);
259     CASE_RETURN_TEXT(PlayerRepeatValue::ALL);
260     CASE_RETURN_TEXT(PlayerRepeatValue::GROUP);
261   }
262   return std::format("Unknown Player Repeat Value: 0x{:x}", (uint8_t)val);
263 }
264 
265 inline std::ostream& operator<<(std::ostream& os, const PlayerRepeatValue& val) {
266   return os << PlayerRepeatValueText(val);
267 }
268 
PlayerShuffleValueText(const PlayerShuffleValue & val)269 inline std::string PlayerShuffleValueText(const PlayerShuffleValue& val) {
270   switch (val) {
271     CASE_RETURN_TEXT(PlayerShuffleValue::OFF);
272     CASE_RETURN_TEXT(PlayerShuffleValue::ALL);
273     CASE_RETURN_TEXT(PlayerShuffleValue::GROUP);
274   }
275   return std::format("Unknown Player Shuffle Value: 0x{:x}", (uint8_t)val);
276 }
277 
278 inline std::ostream& operator<<(std::ostream& os, const PlayerShuffleValue& val) {
279   return os << PlayerShuffleValueText(val);
280 }
281 
282 }  // namespace avrcp
283 }  // namespace bluetooth
284 
285 namespace std {
286 template <>
287 struct formatter<bluetooth::avrcp::CType> : ostream_formatter {};
288 template <>
289 struct formatter<bluetooth::avrcp::Opcode> : ostream_formatter {};
290 template <>
291 struct formatter<bluetooth::avrcp::CommandPdu> : ostream_formatter {};
292 template <>
293 struct formatter<bluetooth::avrcp::PacketType> : ostream_formatter {};
294 template <>
295 struct formatter<bluetooth::avrcp::Capability> : ostream_formatter {};
296 template <>
297 struct formatter<bluetooth::avrcp::Event> : ostream_formatter {};
298 template <>
299 struct formatter<bluetooth::avrcp::Attribute> : ostream_formatter {};
300 template <>
301 struct formatter<bluetooth::avrcp::Status> : ostream_formatter {};
302 template <>
303 struct formatter<bluetooth::avrcp::BrowsePdu> : ostream_formatter {};
304 template <>
305 struct formatter<bluetooth::avrcp::Scope> : ostream_formatter {};
306 template <>
307 struct formatter<bluetooth::avrcp::Direction> : ostream_formatter {};
308 template <>
309 struct formatter<bluetooth::avrcp::KeyState> : ostream_formatter {};
310 template <>
311 struct formatter<bluetooth::avrcp::PlayerAttribute> : ostream_formatter {};
312 template <>
313 struct formatter<bluetooth::avrcp::PlayerRepeatValue> : ostream_formatter {};
314 template <>
315 struct formatter<bluetooth::avrcp::PlayerShuffleValue> : ostream_formatter {};
316 }  // namespace std
317