1 /*
2 * Copyright (C) 2021 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_packet.h"
17 #include "securec.h"
18
19 namespace OHOS {
20 namespace bluetooth {
PushOctets1(uint8_t * pkt,uint8_t payload)21 uint16_t AvrcTgPacket::PushOctets1(uint8_t *pkt, uint8_t payload)
22 {
23 HILOGI("payload:%{public}d", payload);
24
25 return PushOctetsUpto8(pkt, sizeof(uint8_t) * AVRC_TG_OFFSET_ONE_BIT, payload);
26 }
27
PushOctets2(uint8_t * pkt,uint16_t payload)28 uint16_t AvrcTgPacket::PushOctets2(uint8_t *pkt, uint16_t payload)
29 {
30 HILOGI("payload:%{public}d", payload);
31
32 return PushOctetsUpto8(pkt, sizeof(uint8_t) * AVRC_TG_OFFSET_TWO_BITS, payload);
33 }
34
PushOctets3(uint8_t * pkt,uint32_t payload)35 uint16_t AvrcTgPacket::PushOctets3(uint8_t *pkt, uint32_t payload)
36 {
37 HILOGI("payload:%{public}u", payload);
38
39 return PushOctetsUpto8(pkt, sizeof(uint8_t) * AVRC_TG_OFFSET_THREE_BITS, payload);
40 }
41
PushOctets4(uint8_t * pkt,uint32_t payload)42 uint16_t AvrcTgPacket::PushOctets4(uint8_t *pkt, uint32_t payload)
43 {
44 HILOGI("payload:%{public}u", payload);
45
46 return PushOctetsUpto8(pkt, sizeof(uint8_t) * AVRC_TG_OFFSET_FOUR_BITS, payload);
47 }
48
PushOctets8(uint8_t * pkt,uint64_t payload)49 uint16_t AvrcTgPacket::PushOctets8(uint8_t *pkt, uint64_t payload)
50 {
51 HILOGI("payload:%{public}llu", static_cast<unsigned long long>(payload));
52
53 return PushOctetsUpto8(pkt, sizeof(uint8_t) * AVRC_TG_OFFSET_EIGHT_BITS, payload);
54 }
55
PushOctets(uint8_t * pkt,uint8_t * playload,uint16_t length)56 uint16_t AvrcTgPacket::PushOctets(uint8_t *pkt, uint8_t *playload, uint16_t length)
57 {
58 HILOGI("length:%{public}d", length);
59
60 (void)memcpy_s(pkt, length, playload, length);
61
62 return length;
63 }
64
PopOctets1(uint8_t * pkt,uint64_t & payload)65 uint16_t AvrcTgPacket::PopOctets1(uint8_t *pkt, uint64_t &payload)
66 {
67 HILOGI("enter");
68
69 uint64_t tmpPayload = 0x00;
70 uint16_t octets = PopOctetsUpto8(pkt, sizeof(uint8_t) * AVRC_TG_OFFSET_ONE_BIT, tmpPayload);
71 payload = tmpPayload;
72
73 return octets;
74 }
75
PopOctets2(uint8_t * pkt,uint64_t & payload)76 uint16_t AvrcTgPacket::PopOctets2(uint8_t *pkt, uint64_t &payload)
77 {
78 HILOGI("enter");
79
80 uint64_t tmpPayload = 0x00;
81 uint16_t octets = PopOctetsUpto8(pkt, sizeof(uint8_t) * AVRC_TG_OFFSET_TWO_BITS, tmpPayload);
82 payload = tmpPayload;
83
84 return octets;
85 }
86
PopOctets3(uint8_t * pkt,uint64_t & payload)87 uint16_t AvrcTgPacket::PopOctets3(uint8_t *pkt, uint64_t &payload)
88 {
89 HILOGI("enter");
90
91 uint64_t tmpPayload = 0x00;
92 uint16_t octets = PopOctetsUpto8(pkt, sizeof(uint8_t) * AVRC_TG_OFFSET_THREE_BITS, tmpPayload);
93 payload = tmpPayload;
94
95 return octets;
96 }
97
PopOctets4(uint8_t * pkt,uint64_t & payload)98 uint16_t AvrcTgPacket::PopOctets4(uint8_t *pkt, uint64_t &payload)
99 {
100 HILOGI("enter");
101
102 uint64_t tmpPayload = 0x00;
103 uint16_t octets = PopOctetsUpto8(pkt, sizeof(uint8_t) * AVRC_TG_OFFSET_FOUR_BITS, tmpPayload);
104 payload = tmpPayload;
105
106 return octets;
107 }
108
PopOctets8(uint8_t * pkt,uint64_t & payload)109 uint16_t AvrcTgPacket::PopOctets8(uint8_t *pkt, uint64_t &payload)
110 {
111 HILOGI("enter");
112
113 uint64_t tmpPayload = 0x00;
114 uint16_t octets = PopOctetsUpto8(pkt, sizeof(uint8_t) * AVRC_TG_OFFSET_EIGHT_BITS, tmpPayload);
115 payload = tmpPayload;
116
117 return octets;
118 }
119
PopOctets(uint8_t * pkt,uint8_t * playload,uint16_t length)120 uint16_t AvrcTgPacket::PopOctets(uint8_t *pkt, uint8_t *playload, uint16_t length)
121 {
122 HILOGI("length:%{public}d", length);
123
124 (void)memcpy_s(playload, length, pkt, length);
125
126 return length;
127 }
128
GetOpCode(Packet * pkt)129 uint8_t AvrcTgPacket::GetOpCode(Packet *pkt)
130 {
131 HILOGI("enter");
132
133 uint8_t opCode = AVRC_TG_OP_CODE_INVALID;
134 if (PacketPayloadRead(pkt, &opCode, AVRC_TG_AVC_COMMON_OPCODE_OFFSET, 1) != 1) {
135 opCode = AVRC_TG_OP_CODE_INVALID;
136 }
137
138 return opCode;
139 }
140
GetVendorPdu(Packet * pkt)141 uint8_t AvrcTgPacket::GetVendorPdu(Packet *pkt)
142 {
143 HILOGI("enter");
144
145 uint8_t pduId = AVRC_TG_PDU_ID_INVALID;
146 if (PacketPayloadRead(pkt, &pduId, AVRC_TG_AVC_COMMON_VENDOR_PDU_ID_OFFSET, 1) != 1) {
147 pduId = AVRC_TG_PDU_ID_INVALID;
148 }
149
150 return pduId;
151 }
152
GetBrowsePdu(Packet * pkt)153 uint8_t AvrcTgPacket::GetBrowsePdu(Packet *pkt)
154 {
155 HILOGI("enter");
156
157 uint8_t pduId = AVRC_TG_PDU_ID_INVALID;
158 if (PacketPayloadRead(pkt, &pduId, AVRC_TG_AVC_COMMON_BROWSE_PDU_ID_OFFSET, 1) != 1) {
159 pduId = AVRC_TG_PDU_ID_INVALID;
160 }
161
162 return pduId;
163 }
164
IsValidOpCode(uint8_t code)165 bool AvrcTgPacket::IsValidOpCode(uint8_t code)
166 {
167 HILOGI("code:%{public}d", code);
168
169 bool rtnSts = true;
170
171 switch (code) {
172 case AVRC_TG_OP_CODE_UNIT_INFO:
173 case AVRC_TG_OP_CODE_SUB_UNIT_INFO:
174 case AVRC_TG_OP_CODE_PASS_THROUGH:
175 case AVRC_TG_OP_CODE_VENDOR:
176 break;
177 default:
178 rtnSts = false;
179 }
180
181 return rtnSts;
182 }
183
PushOctetsUpto8(uint8_t * pkt,size_t size,uint64_t payload)184 uint16_t AvrcTgPacket::PushOctetsUpto8(uint8_t *pkt, size_t size, uint64_t payload)
185 {
186 HILOGI("payload:%{public}llu", static_cast<unsigned long long>(payload));
187
188 if (size <= sizeof(uint64_t)) {
189 for (size_t i = 0; i < size; i++) {
190 pkt[i] = payload >> ((sizeof(uint64_t) * (size - (i + 1))) & 0xFF);
191 }
192 }
193
194 return static_cast<uint16_t>(size);
195 }
196
PopOctetsUpto8(uint8_t * pkt,size_t size,uint64_t & payload)197 uint16_t AvrcTgPacket::PopOctetsUpto8(uint8_t *pkt, size_t size, uint64_t &payload)
198 {
199 HILOGI("enter");
200
201 if (size <= sizeof(uint64_t)) {
202 for (size_t i = 0; i < size; i++) {
203 uint64_t tmpPayload = pkt[i] & 0xFF;
204 payload |= (tmpPayload << (sizeof(uint64_t) * (size - (i + 1))));
205 }
206 }
207
208 return static_cast<uint16_t>(size);
209 }
210 } // namespace bluetooth
211 } // namespace OHOS
212