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 /**
17  * @file a2dp_profile.h
18  *
19  * @brief Declares the class of the a2dp profile, including attributes, and methods.
20  *
21  * @since 6
22  */
23 
24 #ifndef A2DP_PROFILE_H
25 #define A2DP_PROFILE_H
26 
27 #include <cstdint>
28 #include <map>
29 #include <string>
30 
31 #include "a2dp_codec/include/a2dp_codec_constant.h"
32 #include "a2dp_def.h"
33 #include "a2dp_profile_peer.h"
34 #include "a2dp_sdp.h"
35 #include "base_def.h"
36 #include "btstack.h"
37 #include "gap_if.h"
38 #include "interface_profile_a2dp_src.h"
39 #include "message.h"
40 #include "a2dp_shared_buffer.h"
41 #include "../../../stack/platform/include/queue.h"
42 
43 namespace OHOS {
44 namespace bluetooth {
45 /**
46  * @brief This class provides a set of methods to notify the service about status changed
47  *
48  * @since 6.0
49  */
50 class A2dpProfileObserver {
51 public:
52     /**
53      * @brief A function to notify the service the connect status changed.
54      *
55      * @param[in]   addr: The address of peer device
56      * @param[in]   state: The state of connection
57      * @param[in]   context: the detail information of this callback
58      * @since 6.0
59      */
60     virtual void OnConnectStateChanged(const BtAddr &addr, const int state, void *context) = 0;
61 
62     /**
63      * @brief A function to notify the service the codec status changed.
64      *
65      * @param[in]   addr: The address of peer device
66      * @param[in]   codecInfo: The codec information of stream
67      * @param[in]   context: the detail information of this callback
68      * @since 6.0
69      */
70     virtual void OnCodecStateChanged(const BtAddr &addr, const A2dpSrcCodecStatus codecInfo, void *context) = 0;
71 
72     /**
73      * @brief A function to notify the service the connect status changed.
74      *
75      * @param[in]   addr: The address of peer device
76      * @param[in]   state: The state of stream
77      * @param[in]   context: the detail information of this callback
78      * @since 6.0
79      */
80     virtual void OnAudioStateChanged(const BtAddr &addr, const int state, void *context) = 0;
81 
82     /**
83      * @brief A destructor used to delete the <b>A2dpProfileObserver</b> instance.
84      *
85      * @since 6.0
86      */
87     virtual ~A2dpProfileObserver() = default;
88 };
89 
90 /**
91  * @brief This class provides a set of methods of a2dp profile
92  *
93  * @since 6.0
94  */
95 class A2dpProfile {
96 public:
97     /**
98      * @brief A constructor used to create an <b>A2dpProfile</b> instance.
99      *
100      * @since 6.0
101      */
102     explicit A2dpProfile(const uint8_t role);
103 
104     /**
105      * @brief A desstructor used to delete an <b>A2dpProfile</b> instance.
106      *
107      * @since 6.0
108      */
109     virtual ~A2dpProfile();
110 
111     /**
112      * @brief A function used to enable the a2dp profile
113      *
114      * @since 6.0
115      */
116     void Enable();
117 
118     /**
119      * @brief A function used to disable the a2dp profile
120      *
121      * @since 6.0
122      */
123     void Disable();
124 
125     /**
126      * @brief A function used to connect the peer device
127      *
128      * @param[in] device The address of peer device
129      * @return 0 Success; Otherwise is failed to connect
130      * @since 6.0
131      */
132     int Connect(const BtAddr &device);
133 
134     /**
135      * @brief A function used to disconnect the peer device
136      *
137      * @param[in] device The address of peer device
138      * @return 0 Success; Otherwise is failed to connect
139      * @since 6.0
140      */
141     int Disconnect(const BtAddr &device);
142 
143     /**
144      * @brief A function used to suspend the stream
145      *
146      * @param[in] handle The local handle of stream
147      * @param[in] suspend TRUE: Stop the stream;
148      *                    FALSE: Suspend the stream
149      * @return 0 Success; Otherwise is failed to connect
150      * @since 6.0
151      */
152     int Stop(const uint16_t handle, const bool suspend);
153 
154     /**
155      * @brief A function used to start the stream
156      *
157      * @param[in] handle The local handle of stream
158      * @return 0 Success; Otherwise is failed to connect
159      * @since 6.0
160      */
161     int Start(const uint16_t handle);
162 
163     /**
164      * @brief A function used to close the stream
165      *
166      * @param[in] handle The local handle of stream
167      * @return 0 Success; Otherwise is failed to connect
168      * @since 6.0
169      */
170     int Close(const uint16_t handle) const;
171 
172     /**
173      * @brief True if it has a streaming channel
174      *
175      * @return True if it has a streaming channel, Otherwise false.
176      * @since 6.0
177      */
178     bool HasStreaming();
179 
180     /**
181      * @brief True if it has a open channel
182      *
183      * @return True if it has a open channel, Otherwise false.
184      * @since 6.0
185      */
186     bool HasOpen();
187 
188     /**
189      * @brief Set the tag of the disalbe.
190      *
191      * @since 6.0
192      */
193     void SetDisalbeTag(bool tag);
194 
195     /**
196      * @brief Get the tag of the disalbe.
197      *
198     * @return True if bt is disalbe, Otherwise false.
199      * @since 6.0
200      */
201     bool GetDisalbeTag();
202 
203     /**
204      * @brief A function used to close all the stream
205      *
206      * @since 6.0
207      */
208     void CloseAll();
209 
210     /**
211      * @brief A function used to feedback close the stream for pts
212      *
213      * @param[in] handle The local handle of stream
214      * @param[in] errorCode The error code of response of close
215      * @return 0 Success; Otherwise is failed to connect
216      * @since 6.0
217      */
218     int CloseRsp(const uint16_t handle, const uint8_t errorCode) const;
219 
220     /**
221      * @brief A function used to send stream for pts
222      *
223      * @param[in] handle The local handle of stream
224      * @return 0 Success; Otherwise is failed to connect
225      * @since 6.0
226      */
227     static int WriteStream(const uint16_t handle, const uint8_t config, const uint8_t bitpool);
228 
229     /**
230      * @brief A function used to send delay value to source,pts only
231      *
232      * @param[in] handle The local handle of stream
233      * @param[in] delayValue The value of delay of sync audio with video
234      * @return 0 Success; Otherwise is failed to connect
235      * @since 6.0
236      */
237     static int SendDelay(const uint16_t handle, const uint16_t delayValue);
238 
239     /**
240      * @brief A function used to reconfigrue the stream
241      *
242      * @param[in] handle The local handle of stream
243      * @param[in] codecInfo The configure information
244      * @return 0 Success; Otherwise is failed to connect
245      * @since 6.0
246      */
247     int Reconfigure(const uint16_t handle, uint8_t *codecInfo) const;
248 
249     /**
250      * @brief A function supplied to register observer of profile
251      *
252      * @param[in] observer The pointer of service callback function
253      * @since 6.0
254      */
255     void RegisterObserver(A2dpProfileObserver *observer);
256 
257     /**
258      * @brief A function to process service informaiton of peer
259      *
260      * @param[in] addr The address of peer device
261      * @param[in] context The realated content of this class
262      * @since 6.0
263      */
264     void ProcessSDPCallback(const BtAddr &addr, uint8_t result);
265 
266     /**
267      * @brief A function to get the role of this profile
268      *
269      * @return The role of a2dp
270      * @since 6.0
271      */
272     uint8_t GetRole() const;
273 
274     /**
275      * @brief A function to deregister the pointer of callback
276      *
277      * @param[in] The pointer of callback of service
278      * @since 6.0
279      */
280     static void DeregisterObserver(A2dpProfileObserver *observer);
281 
282     /**
283      * @brief A function to delete the profile peer of address
284      *
285      * @param[in] The address of peer device
286      * @return TRUE: SUCCESS; otherwise failed to delete
287      * @since 6.0
288      */
289     bool DeletePeer(const BtAddr &peerAddress);
290 
291     /**
292      * @brief A function to get the enable status of a2dp profile
293      *
294      * @return TRUE: Enable; otherwise disable
295      * @since 6.0
296      */
297     bool GetProfileEnable() const;
298 
299     /**
300      * @brief A function to set the enable status of a2dp profile
301      *
302      * @return TRUE: Enable; otherwise disable
303      * @since 6.0
304      */
305     void SetProfileEnable(bool value);
306 
307     /**
308      * @brief A function to get the enable status of a2dp profile
309      *
310      * @return TRUE: allowed to start; otherwise other stream is exited
311      * @since 6.0
312      */
313     bool JudgeAllowedStreaming() const;
314 
315     /**
316      * @brief A function to get the profile peer instance by peer addess
317      *
318      * @param[in] The address of peer device
319      * @return The pointer of peer informtion instance
320      * @since 6.0
321      */
322     A2dpProfilePeer *FindPeerByAddress(const BtAddr &peerAddress) const;
323 
324     /**
325      * @brief A function to get the profile peer instance by stream handle
326      *
327      * @param[in] The handle of stream
328      * @return The pointer of peer information instance
329      * @since 6.0
330      */
331     A2dpProfilePeer *FindPeerByHandle(uint16_t handle) const;
332 
333     /**
334      * @brief A function to get/create the profile peer instance by peer address
335      *
336      * @param[in] peerAddress The address of peer device
337      * @param[in] sepType
338      * @return The pointer of peer information instance
339      * @since 6.0
340      */
341     A2dpProfilePeer *FindOrCreatePeer(const BtAddr &peerAddress, uint8_t localRole);
342 
343     /**
344      * @brief A function to save the active device address of peer
345      *
346      * @param[in] The address of peer device
347      * @since 6.0
348      */
349     void SetActivePeer(const BtAddr &peer);
350 
351     /**
352      * @brief A function to get the active device address of peer
353      *
354      * @return The address of active device
355      * @since 6.0
356      */
357     const BtAddr &GetActivePeer() const;
358 
359     /**
360      * @brief A function to get the configure of active stream
361      *
362      * @param[in] The address of active device
363      * @return The configure of active stream
364      * @since 6.0
365      */
366     const ConfigureStream &GetConfigure() const;
367 
368     /**
369      * @brief A function to set the configure of active stream
370      *
371      * @param[in] The address of active device
372      * @since 6.0
373      */
374     void SetConfigure(const BtAddr &addr);
375 
376     /**
377      * @brief A function to build codec information
378      *
379      * @param[in] index The index of codec
380      * @param[out] data The codec information
381      * @since 6.0
382      */
383     static void BuildCodecInfo(A2dpCodecIndex index, uint8_t *data);
384 
385     /**
386      * @brief A function to create stream endpoint information of local profile
387      *
388      * @param[in] role The role of profile
389      * @param[out] cfg The sep information to regist to avdtp
390      * @since 6.0
391      */
392     static void CreateSEPConfigureInfo(uint8_t role);
393 
394     /**
395      * @brief A function to process the event of avdtp
396      *
397      * @param[in] addr The address of peer device
398      * @param[in] message The message from avdtp
399      * @since 6.0
400      */
401     void ProcessAvdtpCallback(const BtAddr &addr, const utility::Message &message);
402 
403     /**
404      * @brief A function to notify the service the connect status changed.
405      *
406      * @param[in]   addr: The address of peer device
407      * @param[in]   state: The state of connection
408      * @param[in]   context: the detail information of this callback
409      * @since 6.0
410      */
411     void ConnectStateChangedNotify(const BtAddr &addr, const int state, void *context);
412 
413     /**
414      * @brief A function to notify the service the connect status changed.
415      *
416      * @param[in]   addr: The address of peer device
417      * @param[in]   state: The state of connection
418      * @param[in]   context: the detail information of this callback
419      * @since 6.0
420      */
421     void AudioStateChangedNotify(const BtAddr &addr, const int state, void *context) const;
422 
423     /**
424      * @brief A function to notify the service the codec status changed.
425      *
426      * @param[in]   addr: The address of peer device
427      * @param[in]   context: the detail information of this callback
428      * @since 6.0
429      */
430     void CodecChangedNotify(const BtAddr &addr, void *context) const;
431 
432     /**
433      * @brief A function to process timeout this class
434      *
435      * @since 6.0
436      */
437     void ProcessSignalingTimeoutCallback(const BtAddr &addr) const;
438 
439     /**
440      * @brief A function to process timeout this class
441      *
442      * @param[in] addr: The address of peer device
443      * @param[in] info: User configure information
444      * @return Return the result setted.
445      * @since 6.0
446      */
447     int SetUserCodecConfigure(const BtAddr &addr, const A2dpSrcCodecInfo &info);
448 
449     /**
450      * @brief A function to judge the active device
451      *
452      * @param[in] addr: The address of peer device
453      * @since 6.0
454      */
455     bool IsActiveDevice(const BtAddr &addr) const;
456 
457     /**
458      * @brief A function to clear the active device
459      *
460      * @since 6.0
461      */
462     void ClearActiveDevice();
463 
464     /**
465      * @brief A function to enable/disable the active device
466      *
467      * @param[in] addr: The address of peer device
468      * @param[in] value: True is enable optional codec; False is disable optional codec.
469      * @since 6.0
470      */
471     bool EnableOptionalCodec(const BtAddr &addr, bool value);
472 
473     /**
474      * @brief Notify to encoder pcm data.
475      * @param[in] addr: The address of peer device
476      * @since 6.0
477      */
478     void NotifyEncoder(const BtAddr &addr) const;
479 
480     /**
481      * @brief Notify to decode frame data.
482      * @param[in] addr: The address of peer device
483      * @since 6.0
484      */
485     void NotifyDecoder(const BtAddr &addr) const;
486 
487     /**
488      * @brief Get the information of the current rendered position.
489      * @param[out] dalayValue is the delayed time
490      * @param[out] sendDataSize is the data size that has been sent
491      * @param[out] timeStamp is the current time stamp
492      * @since 6.0
493      */
494     void GetRenderPosition(uint32_t &delayValue, uint64_t &sendDataSize, uint32_t &timeStamp);
495 
496     /**
497      * @brief Enqueue the frame packet to the packet queue.
498      * @param[in] packet Pointer of the packet
499      * @param[in] frames Number of frames
500      * @param[in] bytes Size of bytes
501      * @param[in] pktTimeStamp The current time stamp
502      * @since 6.0
503      */
504     void EnqueuePacket(const Packet *packet, size_t frames, uint32_t bytes, uint32_t pktTimeStamp);
505 
506     /**
507      * @brief Dequeue the frame packet to the peer.
508      * @since 6.0
509      */
510     void DequeuePacket();
511 
512     /**
513      * @brief Set the pcm data to the shared buffer.
514      * @param buf The pointer of the data.
515      * @param size The size of the data
516      * @since 6.0
517      */
518     uint32_t SetPcmData(const uint8_t *buf, uint32_t size);
519 
520     /**
521      * @brief Get the pcm data from the shared buffer.
522      * @param buf The pointer of the data.
523      * @param size The size of the data
524      * @since 6.0
525      */
526     uint32_t GetPcmData(uint8_t *buf, uint32_t size);
527 
528     /**
529      * @brief A function to notify the delay report value changed.
530      *
531      * @param[in]   addr: The address of peer device
532      * @param[in]   delayValue: The delay value
533      */
534     void DelayReportNotify(const BtAddr &addr, const uint16_t delayValue);
535 private:
536     /**
537      * @brief Get the instance of SDP.
538      *
539      * @return return to the instance of SDP
540      * @since 6.0
541      */
542     A2dpSdpManager GetSDPInstance(void) const;
543 
544     /**
545      * @brief A function to update the number of peer device.
546      *
547      * @param[in]   true: add new device; false: disconnect the device
548      * @return true: Success;  false: The number of connected is max
549      * @since 6.0
550      */
551     static bool UpdateNumberPeerDevice(bool plus);
552 
553     /**
554      * @brief Get the number of connected peer devices.
555      *
556      * @return   The number of connected peer device
557      * @since 6.0
558      */
559     static uint8_t GetConnectedPeerDevice();
560 
561     /**
562      * @brief A function to clear the number of peer device.
563      *
564      * @since 6.0
565      */
566     static void ClearNumberPeerDevice();
567 
568     /**
569      * @brief A function to update the register of gap.
570      *
571      * @param[in]   true: Regist; false: Not regist
572      * @since 6.0
573      */
574     static void UpdateGapRegisterInfo(bool value);
575 
576     /**
577      * @brief A function to get the regist information of gap.
578      *
579      * @return   true: Regist; false: Not regist
580      * @since 6.0
581      */
582     static bool GetGapRegisterInfo();
583 
584     /**
585      * @brief The function is used to register the security of profile to GAP
586      *
587      * @param[in] direction The direction of incoming or outcoming
588      * @param[in] serviceId The source or sink service id of a2dp
589      * @param[in] protocolId The id of avdtp
590      * @param[in] channelId  The channel id
591      * @param[in] securityMode The mode of register security
592      * @return zero is successful
593      * @since 6.0
594      */
595     static int RegisterServiceSecurity(GAP_ServiceConnectDirection direction, GAP_Service serviceId,
596         GAP_SecMultiplexingProtocol protocolId, GapSecChannel channelId, uint16_t securityMode);
597 
598     /**
599      * @brief The function is used to deregister the security of profile to GAP
600      *
601      * @param[in] direction The direction of incoming or outcoming
602      * @param[in] serviceId The source or sink service id of a2dp
603      * @return zero is successful
604      * @since 6.0
605      */
606     static int DeregisterServiceSecurity(GAP_ServiceConnectDirection direction, GAP_Service serviceId);
607 
608     /**
609      * @brief A function to reset the delay report value.
610      *
611      * @param[in]   addr: The address of peer device
612      */
613     void ResetDelayValue(const BtAddr &device);
614 
615     BT_DISALLOW_COPY_AND_ASSIGN(A2dpProfile);
616     A2dpProfile() = delete;
617     bool enable_ = false;
618     uint8_t role_ = A2DP_ROLE_SOURCE;
619     static uint8_t g_linkNum;
620     static bool g_registGap;
621     BtAddr activePeer_ {};
622     std::map<std::string, A2dpProfilePeer *> peers_ {};
623     ConfigureStream configureStream_ = {};
624     A2dpSdpManager sdpInstance_ {};
625     A2dpProfileObserver *a2dpSvcCBack_ {nullptr};
626     Queue *packetQueue_ = nullptr; // queue of packets to be sent
627     A2dpSharedBuffer *buffer_ = nullptr;
628     bool isDoDisable_ = false;
629     uint16_t delayValue_ = 0;
630 };
631 /**
632  * @brief A function to receive stream data.
633  *
634  * @param[in] handle The handle of stream(after configured)
635  * @param[in] pkt The content of stream
636  * @param[in] timeStamp The timestamp of frame
637  * @param[in] pt The pakeckt type of frame
638  * @param[in] streamHandle The codec index
639  * @since 6.0
640  */
641 void ProcessSinkStream(uint16_t handle, Packet *pkt, uint32_t timeStamp, uint8_t pt, uint16_t streamHandle);
642 /**
643  * @brief A function to clean packet data.
644  *
645  * @param[in] data The packet data to be deleted
646  * @since 6.0
647  */
648 void CleanPacketData(void *data);
649 
650 struct PacketData {
651     Packet *packet;
652     size_t frames;
653     uint32_t bytes;
654     uint32_t pktTimeStamp;
655 };
656 }  // namespace bluetooth
657 }  // namespace OHOS
658 #endif  // A2DP_PROFILE_H