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 #include "avrcp_ct_pass_through.h"
16 
17 namespace OHOS {
18 namespace bluetooth {
AvrcCtPassPacket(void)19 AvrcCtPassPacket::AvrcCtPassPacket(void) : stateFlag_(AVRC_KEY_STATE_INVALID), operationId_(AVRC_KEY_OPERATION_INVALID)
20 {
21     HILOGI("enter");
22 }
23 
AvrcCtPassPacket(uint8_t oper,uint8_t state)24 AvrcCtPassPacket::AvrcCtPassPacket(uint8_t oper, uint8_t state) : stateFlag_(state), operationId_(oper)
25 {
26     HILOGI("state: %{public}d", state);
27 
28     operationId_ = oper;
29     stateFlag_ = state;
30 }
31 
AvrcCtPassPacket(Packet * pkt)32 AvrcCtPassPacket::AvrcCtPassPacket(Packet *pkt)
33     : stateFlag_(AVRC_KEY_STATE_INVALID), operationId_(AVRC_KEY_OPERATION_INVALID)
34 {
35     HILOGI("enter");
36 
37     DisassemblePacket(pkt);
38 }
39 
~AvrcCtPassPacket(void)40 AvrcCtPassPacket::~AvrcCtPassPacket(void)
41 {
42     HILOGI("enter");
43 
44     if (pkt_ != nullptr) {
45         PacketFree(pkt_);
46         pkt_ = nullptr;
47     }
48 }
49 
AssemblePacket(void)50 const Packet *AvrcCtPassPacket::AssemblePacket(void)
51 {
52     HILOGI("enter");
53 
54     pkt_ = PacketMalloc(0x00, 0x00, AVRC_CT_PASS_COMMAND_SIZE);
55     auto buffer = static_cast<uint8_t *>(BufferPtr(PacketContinuousPayload(pkt_)));
56 
57     uint16_t offset = 0x00;
58     offset += PushOctets1((buffer + offset), crCode_);
59     offset += PushOctets1((buffer + offset), (subunitType_ << AVRC_CT_PASS_MOVE_BIT_3) | subunitId_);
60     offset += PushOctets1((buffer + offset), opCode_);
61     offset += PushOctets1((buffer + offset), (stateFlag_ << AVRC_CT_PASS_MOVE_BIT_7) | operationId_);
62     PushOctets1((buffer + offset), operationDataFieldLength_);
63 
64     return pkt_;
65 }
66 
DisassemblePacket(Packet * pkt)67 bool AvrcCtPassPacket::DisassemblePacket(Packet *pkt)
68 {
69     HILOGI("enter");
70 
71     bool isValid = false;
72     size_t size = PacketPayloadSize(pkt);
73     if (size >= AVRC_CT_PASS_COMMAND_SIZE) {
74         auto buffer = static_cast<uint8_t *>(BufferPtr(PacketContinuousPayload(pkt)));
75 
76         uint16_t offset = 0x00;
77         uint64_t payload = 0x00;
78         PopOctets1((buffer + offset), payload);
79         crCode_ = static_cast<uint8_t>(payload) & 0b00001111;
80 
81         /// Gets the company ID, because other operands are the default values.
82         offset = AVRC_CT_PASS_OPERATION_ID_OFFSET;
83         PopOctets1((buffer + offset), payload);
84         stateFlag_ = (static_cast<uint8_t>(payload) >> AVRC_CT_PASS_MOVE_BIT_7);
85         operationId_ = (static_cast<uint8_t>(payload) & 0b01111111);
86 
87         if (IsSupportedKeyOperation() && IsValidKeyState()) {
88             isValid = true;
89         }
90     } else {
91         crCode_ = AVRC_CT_RSP_CODE_REJECTED;
92         HILOGI("PacketPayloadRead Failed! size: %{public}zu < AVRC_CT_PASS_RESPONSE_SIZE: %{public}d",
93             size,
94             AVRC_CT_PASS_COMMAND_SIZE);
95     }
96 
97     return isValid;
98 }
99 
IsSupportedKeyOperation(void) const100 bool AvrcCtPassPacket::IsSupportedKeyOperation(void) const
101 {
102     HILOGI("enter");
103 
104     return IsSupportedKeyOperation(operationId_);
105 }
106 
IsValidKeyState(void) const107 bool AvrcCtPassPacket::IsValidKeyState(void) const
108 {
109     HILOGI("enter");
110 
111     return IsValidKeyState(stateFlag_);
112 }
113 
IsSupportedKeyOperation(uint8_t key)114 bool AvrcCtPassPacket::IsSupportedKeyOperation(uint8_t key)
115 {
116     HILOGI("key: %{public}d", key);
117 
118     bool rtnSts = true;
119 
120     switch (key) {
121         case AVRC_KEY_OPERATION_VOLUME_UP:
122         case AVRC_KEY_OPERATION_VOLUME_DOWN:
123         case AVRC_KEY_OPERATION_MUTE:
124         case AVRC_KEY_OPERATION_PLAY:
125         case AVRC_KEY_OPERATION_STOP:
126         case AVRC_KEY_OPERATION_PAUSE:
127         case AVRC_KEY_OPERATION_REWIND:
128         case AVRC_KEY_OPERATION_FAST_FORWARD:
129         case AVRC_KEY_OPERATION_FORWARD:
130         case AVRC_KEY_OPERATION_BACKWARD:
131             break;
132         default:
133             rtnSts = false;
134     }
135 
136     return rtnSts;
137 }
138 
IsValidKeyState(uint8_t state)139 bool AvrcCtPassPacket::IsValidKeyState(uint8_t state)
140 {
141     HILOGI("state: %{public}d", state);
142 
143     bool rtnSts = true;
144 
145     switch (state) {
146         case AVRC_KEY_STATE_PRESS:
147         case AVRC_KEY_STATE_RELEASE:
148             break;
149         default:
150             rtnSts = false;
151     }
152 
153     return rtnSts;
154 }
155 }  // namespace bluetooth
156 }  // namespace OHOS
157