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