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 <iostream>
20 
21 #include "hardware/avrcp/avrcp_common.h"
22 #include "hardware/avrcp/avrcp_logging_helper.h"
23 #include "packet/base/iterator.h"
24 #include "packet/base/packet.h"
25 #include "packet/base/packet_builder.h"
26 
27 namespace bluetooth {
28 namespace avrcp {
29 
30 class PacketBuilder : public ::bluetooth::PacketBuilder {
31 public:
32   virtual ~PacketBuilder() = default;
33 
34   static std::unique_ptr<PacketBuilder> MakeBuilder(
35           CType cType, uint8_t subunit_type, uint8_t subunit_id, Opcode opcode,
36           std::unique_ptr<::bluetooth::PacketBuilder> packet);
37 
38   virtual size_t size() const override;
39   virtual bool Serialize(const std::shared_ptr<::bluetooth::Packet>& pkt) override;
40 
41 protected:
42   CType c_type_;
43   uint8_t subunit_type_ : 5;
44   uint8_t subunit_id_ : 3;
45   Opcode opcode_;
46   std::unique_ptr<::bluetooth::PacketBuilder> payload_;
47 
48   void PushHeader(const std::shared_ptr<::bluetooth::Packet>& pkt);
49   bool PushCompanyId(const std::shared_ptr<::bluetooth::Packet>& pkt, uint32_t company_id);
50 
PacketBuilder(CType type,uint8_t subunit_type,uint8_t subunit_id,Opcode opcode)51   PacketBuilder(CType type, uint8_t subunit_type, uint8_t subunit_id, Opcode opcode)
52       : c_type_(type), subunit_type_(subunit_type), subunit_id_(subunit_id), opcode_(opcode) {}
53 };
54 
55 class Packet : public ::bluetooth::Packet {
56 public:
57   Packet(const Packet&) = delete;
58   Packet& operator=(const Packet&) = delete;
59 
60   virtual ~Packet() = default;
61 
62   // TODO (apanicke): Right now we can use this to build an AvrcpPacket from
63   // another packet type. In the future, we can remove this in favor of
64   // getting an AVRCP Packet directly from an AVCTP Packet
65   static std::shared_ptr<Packet> Parse(std::shared_ptr<::bluetooth::Packet> pkt);
66 
67   /**
68    * Avrcp Packet Layout
69    *   CType c_type_;
70    *   uint8_t subunit_type_ : 5;
71    *   uint8_t subunit_id_ : 3;
72    *   Opcode opcode_;
73    *   uint8_t[] payload_;
74    */
kMinSize()75   static constexpr size_t kMinSize() { return 3; }
76 
77   // Getter Functions
78   CType GetCType() const;
79   uint8_t GetSubunitType() const;
80   uint8_t GetSubunitId() const;
81   Opcode GetOpcode() const;
82 
83   // Overloaded Functions
84   virtual bool IsValid() const override;
85   virtual std::string ToString() const override;
86 
87 protected:
88   using ::bluetooth::Packet::Packet;
89 
PullCompanyId(Iterator it)90   static inline uint32_t PullCompanyId(Iterator it) {
91     uint32_t value = 0;
92     for (int i = 0; i < 3; i++) {
93       value <<= 8;
94       value |= *it++;
95     }
96     return value;
97   }
98 
99 private:
100   virtual std::pair<size_t, size_t> GetPayloadIndecies() const override;
101 };
102 
103 }  // namespace avrcp
104 }  // namespace bluetooth
105