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 "change_path.h"
18 
19 #include <base/sys_byteorder.h>
20 
21 #include "internal_include/bt_trace.h"
22 
23 namespace bluetooth {
24 namespace avrcp {
25 
MakeBuilder(Status status,uint32_t num_items_in_folder)26 std::unique_ptr<ChangePathResponseBuilder> ChangePathResponseBuilder::MakeBuilder(
27         Status status, uint32_t num_items_in_folder) {
28   std::unique_ptr<ChangePathResponseBuilder> builder(
29           new ChangePathResponseBuilder(status, num_items_in_folder));
30 
31   return builder;
32 }
33 
size() const34 size_t ChangePathResponseBuilder::size() const {
35   size_t len = BrowsePacket::kMinSize();
36   len += 1;  // Status
37   if (status_ != Status::NO_ERROR) {
38     return len;
39   }
40 
41   len += 4;  // Number of items in folder
42   return len;
43 }
44 
Serialize(const std::shared_ptr<::bluetooth::Packet> & pkt)45 bool ChangePathResponseBuilder::Serialize(const std::shared_ptr<::bluetooth::Packet>& pkt) {
46   ReserveSpace(pkt, size());
47 
48   BrowsePacketBuilder::PushHeader(pkt, size() - BrowsePacket::kMinSize());
49 
50   AddPayloadOctets1(pkt, (uint8_t)status_);
51   if (status_ != Status::NO_ERROR) {
52     return true;
53   }
54 
55   AddPayloadOctets4(pkt, base::ByteSwap(num_items_in_folder_));
56   return true;
57 }
58 
GetUidCounter() const59 uint16_t ChangePathRequest::GetUidCounter() const {
60   auto it = begin() + BrowsePacket::kMinSize();
61   return it.extractBE<uint16_t>();
62 }
63 
GetDirection() const64 Direction ChangePathRequest::GetDirection() const {
65   auto it = begin() + BrowsePacket::kMinSize() + static_cast<size_t>(2);
66   return static_cast<Direction>(*it);
67 }
68 
GetUid() const69 uint64_t ChangePathRequest::GetUid() const {
70   auto it = begin() + BrowsePacket::kMinSize() + static_cast<size_t>(3);
71   return it.extractBE<uint64_t>();
72 }
73 
IsValid() const74 bool ChangePathRequest::IsValid() const {
75   if (!BrowsePacket::IsValid()) {
76     return false;
77   }
78   // Change path request packets are always the same size
79   return size() == kMinSize();
80 }
81 
ToString() const82 std::string ChangePathRequest::ToString() const {
83   std::stringstream ss;
84   ss << "ChangePathRequestPacket: " << std::endl;
85   ss << "  └ PDU = " << GetPdu() << std::endl;
86   ss << "  └ Length = " << GetLength() << std::endl;
87   ss << "  └ UID Counter = " << loghex(GetUidCounter()) << std::endl;
88   ss << "  └ Direction = " << GetDirection() << std::endl;
89   ss << "  └ UID Requested = " << loghex(GetUid()) << std::endl;
90   ss << std::endl;
91 
92   return ss.str();
93 }
94 
MakeBuilder(uint16_t uid_counter,Direction direction,uint64_t folder_uid)95 std::unique_ptr<ChangePathRequestBuilder> ChangePathRequestBuilder::MakeBuilder(
96         uint16_t uid_counter, Direction direction, uint64_t folder_uid) {
97   std::unique_ptr<ChangePathRequestBuilder> builder(
98           new ChangePathRequestBuilder(uid_counter, direction, folder_uid));
99 
100   return builder;
101 }
102 
size() const103 size_t ChangePathRequestBuilder::size() const { return ChangePathRequest::kMinSize(); }
104 
Serialize(const std::shared_ptr<::bluetooth::Packet> & pkt)105 bool ChangePathRequestBuilder::Serialize(const std::shared_ptr<::bluetooth::Packet>& pkt) {
106   ReserveSpace(pkt, size());
107 
108   BrowsePacketBuilder::PushHeader(pkt, size() - BrowsePacket::kMinSize());
109 
110   AddPayloadOctets2(pkt, base::ByteSwap(uid_counter_));
111   AddPayloadOctets1(pkt, static_cast<uint8_t>(direction_));
112   AddPayloadOctets8(pkt, base::ByteSwap(folder_uid_));
113   return true;
114 }
115 
116 }  // namespace avrcp
117 }  // namespace bluetooth
118