• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_ct_notification.h"
17 
18 namespace OHOS {
19 namespace bluetooth {
AvrcCtNotifyPacket(uint8_t eventId,uint32_t interval)20 AvrcCtNotifyPacket::AvrcCtNotifyPacket(uint8_t eventId, uint32_t interval)
21     : AvrcCtVendorPacket(),
22       interval_(AVRC_PLAYBACK_INTERVAL_1_SEC),
23       playStatus_(AVRC_PLAY_STATUS_ERROR),
24       volume_(AVRC_ABSOLUTE_VOLUME_INVALID)
25 {
26     HILOGI("enter");
27 
28     crCode_ = AVRC_CT_CMD_CODE_NOTIFY;
29     pduId_ = AVRC_CT_PDU_ID_REGISTER_NOTIFICATION;
30     parameterLength_ = AVRC_CT_NOTIFY_PARAMETER_LENGTH;
31     eventId_ = eventId;
32     interval_ = interval;
33 }
34 
AvrcCtNotifyPacket(Packet * pkt)35 AvrcCtNotifyPacket::AvrcCtNotifyPacket(Packet *pkt)
36     : AvrcCtVendorPacket(),
37       interval_(AVRC_PLAYBACK_INTERVAL_1_SEC),
38       playStatus_(AVRC_PLAY_STATUS_ERROR),
39       volume_(AVRC_ABSOLUTE_VOLUME_INVALID)
40 {
41     HILOGI("enter");
42 
43     crCode_ = AVRC_CT_CMD_CODE_NOTIFY;
44     pduId_ = AVRC_CT_PDU_ID_REGISTER_NOTIFICATION;
45 
46     DisassemblePacket(pkt);
47 }
48 
~AvrcCtNotifyPacket()49 AvrcCtNotifyPacket::~AvrcCtNotifyPacket()
50 {
51     HILOGI("enter");
52 
53     attributes_.clear();
54     values_.clear();
55 }
56 
AssembleParameters(Packet * pkt)57 Packet *AvrcCtNotifyPacket::AssembleParameters(Packet *pkt)
58 {
59     HILOGI("enter");
60 
61     size_t bufferSize = AVRC_CT_VENDOR_PARAMETER_LENGTH_SIZE + AVRC_CT_NOTIFY_PARAMETER_LENGTH;
62     HILOGI("BufferMalloc: %{public}zu", bufferSize);
63 
64     auto buffer = BufferMalloc(bufferSize);
65     if (buffer == nullptr) {
66         HILOGE("BufferMalloc fail");
67         return pkt;
68     }
69     auto bufferPtr = static_cast<uint8_t *>(BufferPtr(buffer));
70 
71     uint16_t offset = 0x0000;
72     offset += PushOctets2((bufferPtr + offset), parameterLength_);
73     HILOGI("parameterLength_: %{public}d", parameterLength_);
74 
75     offset += PushOctets1((bufferPtr + offset), eventId_);
76     HILOGI("eventId_: %{public}x", eventId_);
77 
78     PushOctets4((bufferPtr + offset), interval_);
79     HILOGI("interval_: %{public}d", interval_);
80 
81     PacketPayloadAddLast(pkt, buffer);
82 
83     BufferFree(buffer);
84 
85     return pkt;
86 }
87 
DisassembleParameters(uint8_t * buffer)88 bool AvrcCtNotifyPacket::DisassembleParameters(uint8_t *buffer)
89 {
90     HILOGI("enter");
91 
92     isValid_ = false;
93 
94     uint16_t offset = AVRC_CT_VENDOR_PARAMETER_LENGTH_OFFSET;
95     uint64_t payload = 0x00;
96     offset += PopOctets2((buffer + offset), payload);
97     parameterLength_ = static_cast<uint16_t>(payload);
98     HILOGI("parameterLength_: %{public}d", parameterLength_);
99 
100     payload = 0x00;
101     PopOctets1((buffer + offset), payload);
102     eventId_ = static_cast<uint8_t>(payload);
103     HILOGI("eventId_: %{public}x", eventId_);
104 
105     switch (eventId_) {
106         case AVRC_CT_EVENT_ID_PLAYBACK_STATUS_CHANGED:
107             isValid_ = DisassemblePlaybackStatus(buffer);
108             break;
109         case AVRC_CT_EVENT_ID_TRACK_CHANGED:
110             isValid_ = DisassembleTrackChanged(buffer);
111             break;
112         case AVRC_CT_EVENT_ID_PLAYBACK_POS_CHANGED:
113             isValid_ = DisassemblePlaybackPosChanged(buffer);
114             break;
115         case AVRC_CT_EVENT_ID_PLAYER_APPLICATION_SETTING_CHANGED:
116             isValid_ = DisassemblePlayerApplicationSettingChanged(buffer);
117             break;
118         case AVRC_CT_EVENT_ID_ADDRESSED_PLAYER_CHANGED:
119             isValid_ = DisassembleAddressedPlayerChanged(buffer);
120             break;
121         case AVRC_CT_EVENT_ID_UIDS_CHANGED:
122             isValid_ = DisassembleUidsChanged(buffer);
123             break;
124         case AVRC_CT_EVENT_ID_VOLUME_CHANGED:
125             isValid_ = DisassembleVolumeChanged(buffer);
126             break;
127         case AVRC_CT_EVENT_ID_TRACK_REACHED_END:
128         case AVRC_CT_EVENT_ID_TRACK_REACHED_START:
129         case AVRC_CT_EVENT_ID_NOW_PLAYING_CONTENT_CHANGED:
130         case AVRC_CT_EVENT_ID_AVAILABLE_PLAYERS_CHANGED:
131             /// FALL THROUGH
132         default:
133             /// Do nothing!
134             isValid_ = true;
135             break;
136     }
137 
138     HILOGI("isValid_: %{public}d", isValid_);
139 
140     return isValid_;
141 }
142 
DisassemblePlaybackStatus(uint8_t * buffer)143 bool AvrcCtNotifyPacket::DisassemblePlaybackStatus(uint8_t *buffer)
144 {
145     HILOGI("enter");
146 
147     isValid_ = false;
148 
149     uint16_t offset = AVRC_CT_NOTIFY_EVENT_ID_OFFSET + AVRC_CT_NOTIFY_EVENT_ID_SIZE;
150     uint64_t payload = 0x00;
151     PopOctets1((buffer + offset), payload);
152     playStatus_ = static_cast<uint8_t>(payload);
153     HILOGI("playStatus_: %{public}x", playStatus_);
154 
155     isValid_ = true;
156 
157     return isValid_;
158 }
159 
DisassembleTrackChanged(uint8_t * buffer)160 bool AvrcCtNotifyPacket::DisassembleTrackChanged(uint8_t *buffer)
161 {
162     HILOGI("enter");
163 
164     isValid_ = false;
165 
166     uint16_t offset = AVRC_CT_NOTIFY_EVENT_ID_OFFSET + AVRC_CT_NOTIFY_EVENT_ID_SIZE;
167     uint64_t payload = 0x00;
168     PopOctets8((buffer + offset), payload);
169     uid_ = payload;
170     HILOGI("uid_: %{public}jx", uid_);
171 
172     isValid_ = true;
173 
174     return isValid_;
175 }
176 
DisassemblePlaybackPosChanged(uint8_t * buffer)177 bool AvrcCtNotifyPacket::DisassemblePlaybackPosChanged(uint8_t *buffer)
178 {
179     HILOGI("enter");
180 
181     isValid_ = false;
182 
183     uint16_t offset = AVRC_CT_NOTIFY_EVENT_ID_OFFSET + AVRC_CT_NOTIFY_EVENT_ID_SIZE;
184     uint64_t payload = 0x00;
185     PopOctets4((buffer + offset), payload);
186     playbackPos_ = static_cast<uint32_t>(payload);
187     HILOGI("playbackPos_: %{public}d", playbackPos_);
188 
189     isValid_ = true;
190 
191     return isValid_;
192 }
193 
DisassemblePlayerApplicationSettingChanged(uint8_t * buffer)194 bool AvrcCtNotifyPacket::DisassemblePlayerApplicationSettingChanged(uint8_t *buffer)
195 {
196     HILOGI("enter");
197 
198     isValid_ = false;
199 
200     receivedFragments_++;
201     HILOGI("receivedFragments_: %{public}d", receivedFragments_);
202 
203     uint16_t offset = AVRC_CT_NOTIFY_EVENT_ID_OFFSET + AVRC_CT_NOTIFY_EVENT_ID_SIZE;
204     uint64_t payload = 0x00;
205     offset += PopOctets1((buffer + offset), payload);
206     auto numOfAttributes = static_cast<uint8_t>(payload);
207     HILOGI("numOfAttributes: %{public}d", numOfAttributes);
208 
209     for (int i = 0; i < numOfAttributes; i++) {
210         payload = 0x00;
211         offset += PopOctets1((buffer + offset), payload);
212         attributes_.push_back(static_cast<uint8_t>(payload));
213         HILOGI("attribute: %{public}x", attributes_.back());
214 
215         offset += PopOctets1((buffer + offset), payload);
216         values_.push_back(static_cast<uint8_t>(payload));
217         HILOGI("value: %{public}x", values_.back());
218     }
219 
220     return isValid_;
221 }
222 
DisassembleAddressedPlayerChanged(uint8_t * buffer)223 bool AvrcCtNotifyPacket::DisassembleAddressedPlayerChanged(uint8_t *buffer)
224 {
225     HILOGI("enter");
226 
227     isValid_ = false;
228 
229     uint16_t offset = AVRC_CT_NOTIFY_EVENT_ID_OFFSET + AVRC_CT_NOTIFY_EVENT_ID_SIZE;
230     uint64_t payload = 0x00;
231     offset += PopOctets2((buffer + offset), payload);
232     playerId_ = static_cast<uint16_t>(payload);
233     HILOGI("playerId_: %{public}x", playerId_);
234 
235     payload = 0x00;
236     PopOctets2((buffer + offset), payload);
237     uidCounter_ = static_cast<uint16_t>(payload);
238     HILOGI("uidCounter_: %{public}x", uidCounter_);
239 
240     isValid_ = true;
241 
242     return isValid_;
243 }
244 
DisassembleUidsChanged(uint8_t * buffer)245 bool AvrcCtNotifyPacket::DisassembleUidsChanged(uint8_t *buffer)
246 {
247     HILOGI("enter");
248 
249     isValid_ = false;
250 
251     uint16_t offset = AVRC_CT_NOTIFY_EVENT_ID_OFFSET + AVRC_CT_NOTIFY_EVENT_ID_SIZE;
252     uint64_t payload = 0x00;
253     PopOctets2((buffer + offset), payload);
254     uidCounter_ = static_cast<uint16_t>(payload);
255     HILOGI("uidCounter_: %{public}x", uidCounter_);
256 
257     isValid_ = true;
258 
259     return isValid_;
260 }
261 
DisassembleVolumeChanged(uint8_t * buffer)262 bool AvrcCtNotifyPacket::DisassembleVolumeChanged(uint8_t *buffer)
263 {
264     HILOGI("enter");
265 
266     isValid_ = false;
267 
268     uint16_t offset = AVRC_CT_NOTIFY_EVENT_ID_OFFSET + AVRC_CT_NOTIFY_EVENT_ID_SIZE;
269     uint64_t payload = 0x00;
270     PopOctets1((buffer + offset), payload);
271     volume_ = static_cast<uint8_t>(payload) & 0b01111111;
272     HILOGI("volume_: %{public}d", volume_);
273 
274     isValid_ = true;
275 
276     return isValid_;
277 }
278 }  // namespace bluetooth
279 }  // namespace OHOS