1 /*
2  * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "avrcp_tg_pass_through.h"
17 
18 namespace OHOS {
19 namespace bluetooth {
AvrcTgPassPacket()20 AvrcTgPassPacket::AvrcTgPassPacket()
21     : stateFlag_(AVRC_KEY_STATE_INVALID), operationId_(AVRC_KEY_OPERATION_INVALID), label_(AVRC_DEFAULT_LABEL)
22 {
23     HILOGI("enter");
24 }
25 
AvrcTgPassPacket(uint8_t oper,uint8_t state,uint8_t label)26 AvrcTgPassPacket::AvrcTgPassPacket(uint8_t oper, uint8_t state, uint8_t label)
27     : stateFlag_(AVRC_KEY_STATE_INVALID), operationId_(AVRC_KEY_OPERATION_INVALID), label_(AVRC_DEFAULT_LABEL)
28 {
29     HILOGI("oper: %{public}d, state: %{public}d, label: %{public}d", oper, state, label);
30 
31     operationId_ = oper;
32     stateFlag_ = state;
33     label_ = label;
34 }
35 
AvrcTgPassPacket(Packet * pkt,uint8_t label)36 AvrcTgPassPacket::AvrcTgPassPacket(Packet *pkt, uint8_t label)
37     : stateFlag_(AVRC_KEY_STATE_INVALID), operationId_(AVRC_KEY_OPERATION_INVALID), label_(AVRC_DEFAULT_LABEL)
38 {
39     HILOGI("label: %{public}d", label);
40 
41     label_ = label;
42 
43     DisassemblePacket(pkt);
44 }
45 
~AvrcTgPassPacket(void)46 AvrcTgPassPacket::~AvrcTgPassPacket(void)
47 {
48     HILOGI("enter");
49 
50     if (pkt_ != nullptr) {
51         PacketFree(pkt_);
52         pkt_ = nullptr;
53     }
54 }
55 
AssemblePacket(void)56 const Packet *AvrcTgPassPacket::AssemblePacket(void)
57 {
58     HILOGI("enter");
59 
60     pkt_ = PacketMalloc(0x00, 0x00, AVRC_TG_PASS_RESPONSE_SIZE);
61     auto buffer = static_cast<uint8_t *>(BufferPtr(PacketContinuousPayload(pkt_)));
62 
63     uint16_t offset = 0x00;
64     offset += PushOctets1((buffer + offset), crCode_);
65     offset += PushOctets1((buffer + offset), (subunitType_ << AVRC_TG_OFFSET_THREE_BITS) | subunitId_);
66     offset += PushOctets1((buffer + offset), opCode_);
67     offset += PushOctets1((buffer + offset), (stateFlag_ << AVRC_TG_OFFSET_SEVEN_BITS) | operationId_);
68     PushOctets1((buffer + offset), operationDataFieldLength_);
69 
70     return pkt_;
71 }
72 
DisassemblePacket(Packet * pkt)73 bool AvrcTgPassPacket::DisassemblePacket(Packet *pkt)
74 {
75     HILOGI("enter");
76 
77     isValid_ = false;
78     size_t size = PacketPayloadSize(pkt);
79     if (size >= AVRC_TG_PASS_COMMAND_SIZE) {
80         auto buffer = static_cast<uint8_t *>(BufferPtr(PacketContinuousPayload(pkt)));
81 
82         // Only gets the company ID, because other operands are the default values.
83         uint16_t offset = AVRC_TG_PASS_OPERATION_ID_OFFSET;
84         uint64_t payload = 0x00;
85         PopOctets1((buffer + offset), payload);
86         stateFlag_ = (static_cast<uint8_t>(payload) >> AVRC_TG_OFFSET_SEVEN_BITS);
87         operationId_ = (static_cast<uint8_t>(payload) & 0b01111111);
88 
89         if (!IsSupportedKeyOperation()) {
90             crCode_ = AVRC_TG_RSP_CODE_NOT_IMPLEMENTED;
91         } else if (!IsValidKeyState()) {
92             crCode_ = AVRC_TG_RSP_CODE_REJECTED;
93         } else {
94             isValid_ = true;
95             crCode_ = AVRC_TG_RSP_CODE_ACCEPTED;
96         }
97     } else {
98         crCode_ = AVRC_TG_RSP_CODE_REJECTED;
99         HILOGI("The size of the packet is invalid! - actual size: %{public}zu valid min size: %{public}u",
100             size, AVRC_TG_PASS_COMMAND_SIZE);
101     }
102 
103     return isValid_;
104 }
105 
IsSupportedKeyOperation(void)106 bool AvrcTgPassPacket::IsSupportedKeyOperation(void)
107 {
108     HILOGI("enter");
109 
110     return IsSupportedKeyOperation(operationId_);
111 }
112 
IsValidKeyState(void)113 bool AvrcTgPassPacket::IsValidKeyState(void)
114 {
115     HILOGI("enter");
116 
117     return IsValidKeyState(stateFlag_);
118 }
119 
IsSupportedKeyOperation(uint8_t key)120 bool AvrcTgPassPacket::IsSupportedKeyOperation(uint8_t key)
121 {
122     HILOGI("key: %{public}d", key);
123 
124     bool rtnSts = true;
125 
126     switch (key) {
127         case AVRC_KEY_OPERATION_VOLUME_UP:
128         case AVRC_KEY_OPERATION_VOLUME_DOWN:
129         case AVRC_KEY_OPERATION_MUTE:
130         case AVRC_KEY_OPERATION_PLAY:
131         case AVRC_KEY_OPERATION_STOP:
132         case AVRC_KEY_OPERATION_PAUSE:
133         case AVRC_KEY_OPERATION_REWIND:
134         case AVRC_KEY_OPERATION_FAST_FORWARD:
135         case AVRC_KEY_OPERATION_FORWARD:
136         case AVRC_KEY_OPERATION_BACKWARD:
137             break;
138         default:
139             rtnSts = false;
140     }
141 
142     return rtnSts;
143 }
144 
IsValidKeyState(uint8_t state)145 bool AvrcTgPassPacket::IsValidKeyState(uint8_t state)
146 {
147     HILOGI("state: %{public}d", state);
148 
149     bool rtnSts = true;
150 
151     switch (state) {
152         case AVRC_KEY_STATE_PRESS:
153         case AVRC_KEY_STATE_RELEASE:
154             break;
155         default:
156             rtnSts = false;
157     }
158 
159     return rtnSts;
160 }
161 }  // namespace bluetooth
162 }  // namespace OHOS
163