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  * @addtogroup bluetooth
18  * @file a2dp_service.h
19  *
20  * @brief Declare the interface and function implementation of A2DP service and profile.
21  *
22  * @since 6
23  */
24 
25 #ifndef A2DP_SERVICE_H
26 #define A2DP_SERVICE_H
27 
28 #include <cstdint>
29 #include <list>
30 #include <map>
31 #include <string>
32 
33 #include "a2dp_def.h"
34 #include "a2dp_profile.h"
35 #include "a2dp_service_connection.h"
36 #include "a2dp_service_device.h"
37 #include "a2dp_sink.h"
38 #include "a2dp_source.h"
39 #include "base_observer_list.h"
40 #include "btstack.h"
41 #include "context.h"
42 #include "interface_profile.h"
43 #include "interface_profile_a2dp_src.h"
44 #include "message.h"
45 #include "raw_address.h"
46 
47 namespace OHOS {
48 namespace bluetooth {
49 class ObserverProfile : public A2dpProfileObserver {
50 public:
51     /**
52      * @brief A constructor used to create an <b>ObserverProfile</b> instance.
53      *
54      * @param[in] role The role of profile
55      * @since 6.0
56      */
57     explicit ObserverProfile(uint8_t role);
58 
59     /**
60      * @brief A constructor used to create an <b>ObserverProfile</b> instance.
61      *
62      * @since 6.0
63      */
ObserverProfile()64     ObserverProfile()
65     {}
66 
67     /**
68      * @brief A desstructor used to create an <b>ObserverProfile</b> instance.
69      *
70      * @since 6.0
71      */
72     ~ObserverProfile() override = default;
73 
74     /**
75      * @brief The connection status changes from connected to disconnected.
76      * @param[in] addr  The address of Bluetooth remote device.
77      * @param[in] state  The connect state of Bluetooth remote device.
78      * @param[in] context  The context is used to send the event in the callback.
79      * @since 6.0
80      */
81     void OnConnectStateChanged(const BtAddr &addr, const int state, void *context) override;
82 
83     /**
84      * @brief Audio playing status change.
85      * @param[in] addr  The address of Bluetooth remote device.
86      * @param[in] state  The playing status of remote device after chang.
87      * @param[in] context  The context is used to send the event in the callback.
88      * @since 6.0
89      */
90     void OnAudioStateChanged(const BtAddr &addr, const int state, void *context) override;
91 
92     /**
93      * @brief Audio playing status change.
94      * @param[in] addr  The address of Bluetooth remote device.
95      * @param[in] codecInfo  Codec information after chang.
96      * @param[in] context  The context is used to send the event in the callback.
97      * @since 6.0
98      */
99     void OnCodecStateChanged(const BtAddr &addr, const A2dpSrcCodecStatus codecInfo, void *context) override;
100 
101 private:
102     /**
103      * @brief Process the message of  connect state changed .
104      *
105      * @param[in] btAddr The address of remote device
106      * @param[in] deviceInfo The information of remote device
107      * @return  The state of connected
108      * @since 6.0
109      */
110     int ProcessConnectStateMessage(
111         RawAddress btAddr, A2dpDeviceInfo *deviceInfo, const int connectPolicy, const int state, const uint16_t handle);
112 
113     /**
114      * @brief Process the a2dp hdf load .
115      *
116      * @param[in] state The connection state
117      * @return void
118      * @since 6.0
119      */
120     void ProcessA2dpHdfLoad(const int state) const;
121     /**
122      * @brief Update the stateinfo.
123      *
124      * @param[in] msgCMD The value of what for message
125      * @param[in] stateValue The value of state
126      * @param[out] msg The address of message
127      * @param[out] state The address of state
128      * @since 6.0
129      */
130     static void UpdateStateInformation(utility::Message &msg, int &state, const int msgCMD, const int stateValue);
131     uint8_t role_ {};
132 };
133 
134 /**
135  * @brief This class provides functions called by Framework API.
136  *
137  * @since 6.0
138  */
139 class A2dpService : public IProfileA2dp, public utility::Context {
140 public:
141     /**
142      * @brief A constructor used to create an a2dpservice instance.
143      *
144      * @param name Service name.
145      * @param version Profile version.
146      * @param role Profile role.
147      * @since 6.0
148      */
149     A2dpService(const std::string &name, const std::string version, const uint8_t role);
150 
151     /**
152      * @brief A destructor used to delete the a2dpservice instance.
153      *
154      * @since 6.0
155      */
156     ~A2dpService();
157 
158     /**
159      * @brief Enable the target service.
160      *
161      * @since 6.0
162      */
163     void Enable() override;
164 
165     /**
166      * @brief Disable the target service.
167      *
168      * @since 6.0
169      */
170     void Disable() override;
171 
172     /**
173      * @brief Get the instance of the A2DP source or sink object.
174      *
175      * @return Returns the instance of the A2DP source or sink object.
176      * @since 6.0
177      */
178     utility::Context *GetContext() override;
179 
180     /**
181      * @brief Connect to the peer bluetooth device.
182      *
183      * @param device The address of the peer bluetooth device.
184      * @return Returns <b>BT_SUCCESS</b> Perform normal connection processing.
185      *         Returns <b>RET_BAD_STATUS</b> Target device is on connected,or connecting.
186      *         Returns <b>RET_NO_SUPPORT</b> Target device is not allowed to connect,or the connection fails.
187      * @since 6.0
188      */
189     int Connect(const RawAddress &device) override;
190 
191     /**
192      * @brief Disconnect with the peer bluetooth service.
193      *
194      * @param device The address of the peer bluetooth device.
195      * @return Returns <b>BT_SUCCESS</b> if perform normal disconnection processing.
196      *         Returns <b>RET_BAD_PARAM</b> if target device is not in the device list.
197      *         Returns <b>BT_OPERATION_FAILED</b> if target device is on disconnected,or disconnecting.
198      *         Returns <b>RET_NO_SUPPORT</b> if disconnection fails.
199      * @since 6.0
200      */
201     int Disconnect(const RawAddress &device) override;
202 
203     /**
204      * @brief Get connected device.
205      *
206      * @return Returns Connected devices.
207      * @since 6.0
208      */
209     std::list<RawAddress> GetConnectDevices() override;
210 
211     /**
212      * @brief Get connect state of local device.
213      *
214      * @return Returns <b>PROFILE_STATE_DISCONNECTED</b> if device connection state is disconnected;
215      *         Returns <b>PROFILE_STATE_DISCONNECTING</b> if device connection state is disconnecting;
216      *         Returns <b>PROFILE_STATE_CONNECTED</b> if device connection state is connected;
217      *         Returns <b>PROFILE_STATE_CONNECTING</b> if device connection state is connecting;
218      * @since 6.0
219      */
220     int GetConnectState() override;
221 
222     /**
223      * @brief Get max number of connected device.
224      *
225      * @return Returns max connect number.
226      * @since 6.0
227      */
228     int GetMaxConnectNum() override;
229 
230     /**
231      * @brief Get devices by connection states.
232      *
233      * @param states The connection states of the bluetooth device.
234      * @return Returns devices that match the connection states.
235      * @since 6.0
236      */
237     std::vector<RawAddress> GetDevicesByStates(std::vector<int> &states) const override;
238 
239     /**
240      * @brief Get device connection state by address.
241      *
242      * @param device The address of the peer bluetooth device.
243      * @return Returns <b>DISCONNECTED</b> if device connect state is disconnected;
244      *         Returns <b>DISCONNECTING</b> if device connect state is disconnecting;
245      *         Returns <b>CONNECTED</b> if device connect state is connected;
246      *         Returns <b>CONNECTING</b> if device connect state is connecting;
247      *         Returns <b>INVALID_STATUS</b> if target device is not in device list;
248      * @since 6.0
249      */
250     int GetDeviceState(const RawAddress &device) const override;
251 
252     /**
253      * @brief Get device playing state by address when target device is on connected.
254      *
255      * @param device The address of the peer bluetooth device.
256      * @return Returns <b>1</b> if device is on playing;
257      *         Returns <b>0</b> if device is not on playing;
258      * @since 6.0
259      */
260     int GetPlayingState(const RawAddress &device, int &state) const override;
261 
262     /**
263      * @brief Set target device as active device.
264      *
265      * @param device The address of the peer bluetooth device.
266      * @return Returns <b>BT_SUCCESS</b> Target device has already been active, or perform normal setting processing.
267      *         Returns <b>RET_BAD_STATUS</b> Target device is not on connected, or not in device list.
268      * @since 6.0
269      */
270     int SetActiveSinkDevice(const RawAddress &device) override;
271 
272     /**
273      * @brief Get active device.
274      * @return Returns active device.
275      * @since 6.0
276      */
277     const RawAddress &GetActiveSinkDevice() const override;
278 
279     /**
280      * @brief Set connection strategy for peer bluetooth device.
281      *        If peer device is connected and the policy is set not allowed,then perform disconnect operation.
282      *        If peer device is disconnected and the policy is set allowed,then perform connect operation.
283      *
284      * @param device The address of the peer bluetooth device.
285      * @param strategy The device connect strategy.
286      * @return Returns <b>BT_SUCCESS</b> if the operation is successful.
287      *         Returns <b>RET_BAD_STATUS</b> if the operation fails.
288      * @since 6.0
289      */
290     int SetConnectStrategy(const RawAddress &device, int strategy) override;
291 
292     /**
293      * @brief Get connection strategy of peer bluetooth device.
294      *
295      * @param device The address of the peer bluetooth device.
296      * @return Returns <b>CONNECTION_ALLOWED</b> if the peer device is allowed to connect.
297      *         Returns <b>CONNECTION_FORBIDDEN</b> if the peer device is not allowed to connect.
298      *         Returns <b>CONNECTION_UNKNOWN</b> if the connection policy is unknown.
299      * @since 6.0
300      */
301     int GetConnectStrategy(const RawAddress &device) const override;
302 
303     /**
304      * @brief Send delay reporting.
305      *
306      * @param device The address of the peer bluetooth device.
307      * @param delayValue The delay value.
308      * @return Returns <b>BT_SUCCESS</b> if the operation is successful.
309      *         Returns <b>RET_BAD_STATUS</b> if the operation fails.
310      */
311     int SendDelay(const RawAddress &device, uint16_t delayValue) override;
312 
313     /**
314      * @brief Get codec status information of connected device.
315      *
316      * @param device The address of the bluetooth device.
317      * @return Returns codec status information of connected device.
318      * @since 6.0
319      */
320     A2dpSrcCodecStatus GetCodecStatus(const RawAddress &device) const override;
321 
322     /**
323      * @brief Set the codec encoding preferences of the specified device.
324      *
325      * @param device The address of the bluetooth device.
326      * @param info The codec encoding information.
327      * @return Return the result setted.
328      * @since 6.0
329      */
330     int SetCodecPreference(const RawAddress &device, const A2dpSrcCodecInfo &info) override;
331 
332     /**
333      * @brief Set whether the optional codec is valid.
334      *
335      * @param device The address of the bluetooth device.
336      * @param isEnable Set true if the optional codec is valid.
337      *                 Set false if the optional codec is invalid.
338      * @since 6.0
339      */
340     void SwitchOptionalCodecs(const RawAddress &device, bool isEnable) override;
341 
342     /**
343      * @brief Get whether the peer bluetooth device supports optional codec.
344      *
345      * @param device The address of the bluetooth device.
346      * @return Returns <b>A2DP_OPTIONAL_SUPPORT</b> The device supports optional codec.
347      *         Returns <b>A2DP_OPTIONAL_NOT_SUPPORT</b> The device doesn't support optional codec.
348      *         Returns <b>A2DP_OPTIONAL_SUPPORT_UNKNOWN</b> Don't know if the device support optional codec.
349      * @since 6.0
350      */
351     int GetOptionalCodecsSupportState(const RawAddress &device) const override;
352 
353     /**
354      * @brief Audio start streaming.
355      *
356      * @param device The address of the bluetooth device.
357      * @return Returns <b>BT_SUCCESS</b> if the operation is successful.
358      *         Returns <b>RET_BAD_STATUS</b> if the operation fails, or device is not in device list.
359      * @since 6.0
360      */
361     int StartPlaying(const RawAddress &device) override;
362 
363     /**
364      * @brief Audio suspend streaming.
365      *
366      * @param device The address of the bluetooth device.
367      * @return Returns <b>BT_SUCCESS</b> if the operation is successful.
368      *         Returns <b>RET_BAD_STATUS</b> if the operation fails, or device is not in device list.
369      * @since 6.0
370      */
371     int SuspendPlaying(const RawAddress &device) override;
372 
373     /**
374      * @brief Audio stop streaming.
375      *
376      * @param device The address of the bluetooth device.
377      * @return Returns <b>BT_SUCCESS</b> if the operation is successful.
378      *         Returns <b>RET_BAD_STATUS</b> if the operation fails, or device is not in device list.
379      * @since 6.0
380      */
381     int StopPlaying(const RawAddress &device) override;
382 
383     /**
384      * @brief Register observer function of framework.
385      *
386      * @param observer The observer function pointer of framework.
387      * @since 6.0
388      */
389     void RegisterObserver(IA2dpObserver *observer) override;
390 
391     /**
392      * @brief Deregister observer function of framework.
393      *
394      * @since 6.0
395      */
396     void DeregisterObserver(IA2dpObserver *observer) override;
397 
398     /**
399      * @brief Write PCM data to A2dp Service
400      * @param[in] data is the address of the input data
401      * @param[in] size is the size of the input data
402      * @since 6.0
403      */
404     int WriteFrame(const uint8_t *data, uint32_t size) override;
405 
406     /**
407      * @brief Get the information of the current rendered position.
408      * @param device The address of the bluetooth device.
409      * @param[out] dalayValue is the delayed time
410      * @param[out] sendDataSize is the data size that has been sent
411      * @param[out] timeStamp is the current time stamp
412      * @return Returns <b>BT_SUCCESS</b> if the operation is successful.
413      *         Returns <b>RET_BAD_STATUS</b> if the operation fails.
414      * @since 6.0
415      */
416     int GetRenderPosition(const RawAddress &device, uint32_t &delayValue, uint64_t &sendDataSize,
417                           uint32_t &timeStamp) override;
418     /**
419      * @brief Get boject pointer of A2dpConnectManager.
420      *
421      * @return Returns boject pointer of A2dpConnectManager.
422      * @since 6.0
423      */
424     A2dpConnectManager ConnectManager() const;
425 
426     /**
427      * @brief Process connect callback function pointer of framework.
428      * @param state The connection state of the bluetooth device.
429      * @param device The address of the bluetooth device.
430      * @since 6.0
431      */
432     void ProcessConnectFrameworkCallback(int state, const RawAddress &device);
433 
434     /**
435      * @brief Process playing callback function pointer of framework.
436      * @param playingState The new playing state of the bluetooth device.
437      * @param device The address of the bluetooth device.
438      * @param error The playing error state of the bluetooth device.
439      * @since 6.0
440      */
441     void ProcessPlayingFrameworkCallback(int playingState, int error, const RawAddress &device);
442 
443     /**
444      * @brief Process codec callback function pointer of framework.
445      * @param info The new codec config information of the bluetooth device.
446      * @param device The address of the bluetooth device.
447      * @param error The codec error state of the bluetooth device.
448      * @since 6.0
449      */
450     void ProcessCodecFrameworkCallback(const bluetooth::A2dpSrcCodecInfo &info, int error, const RawAddress &device);
451 
452     /**
453      * @brief Get device information from device list by device address.
454      *
455      * @param device The address of the bluetooth device.
456      * @return Returns device information from device list.
457      * @since 6.0
458      */
459     A2dpDeviceInfo *GetDeviceFromList(const RawAddress &device);
460 
461     /**
462      * @brief Get device list that saves devices information.
463      * @return Returns device list.
464      * @since 6.0
465      */
466     std::map<std::string, A2dpDeviceInfo *> GetDeviceList() const;
467 
468     /**
469      * @brief Add device information to device list.
470      *
471      * @param address The address of the bluetooth device.
472      * @param deviceInfo The device information.
473      * @since 6.0
474      */
475     void AddDeviceToList(std::string address, A2dpDeviceInfo *deviceInfo);
476 
477     /**
478      * @brief Delete device information from device list.
479      *
480      * @param device The address of the bluetooth device.
481      * @since 6.0
482      */
483     void DeleteDeviceFromList(const RawAddress &device);
484 
485     /**
486      * @brief : Post the events.
487      *
488      * @param event : The event of the a2dp
489      * @since 6.0
490      */
491     void PostEvent(utility::Message event, RawAddress &device);
492 
493     /**
494      * @brief Process the events.
495      *
496      * @param event : The event of the a2dp
497      * @since 6.0
498      */
499     void ProcessEvent(utility::Message event, RawAddress &device);
500 
501     /**
502      * @brief Update active device
503      *
504      * @param device The address of the peer device.
505      * @since 6.0
506      */
507     void UpdateActiveDevice(const RawAddress &device);
508 
509     /**
510      * @brief Update optional codec status.
511      *
512      * @param device The address of the bluetooth device.
513      * @since 6.0
514      */
515     void UpdateOptCodecStatus(const RawAddress &device);
516 
517     /**
518      * @brief Check if do disable, and clear device list when doing disable.
519      *
520      * @since 6.0
521      */
522     void CheckDisable();
523 
524     /**
525      * @brief  Activate remote device
526      *
527      * @since 6.0
528      */
529     void ActiveDevice();
530 
531 private:
532     /**
533      * @brief Process the events.
534      *
535      * @param event : The event of the a2dp
536      * @since 6.0
537      */
538     void ProcessMessage(const utility::Message &msg) const;
539 
540     /**
541      * @brief Enable the service.
542      *
543      * @since 6.0
544      */
545     void EnableService();
546 
547     /**
548      * @brief Disable the service
549      *
550      * @since 6.0
551      */
552     void DisableService();
553 
554     /**
555      * @brief Process profile's callback information.
556      *
557      * @param addr The address of the bluetooth device.
558      * @param message The message from avdtp
559      * @since 6.0
560      */
561     void ProcessAvdtpCallback(const BtAddr &addr, utility::Message &message) const;
562 
563     /**
564      * @brief Process profile's  timerout callback information.
565      *
566      * @param role The role of the bluetooth profile.
567      * @since 6.0
568      */
569     void ProcessTimeoutCallback(uint8_t role, const BtAddr &addr) const;
570 
571     /**
572      * @brief Process profile's callback information.
573      *
574      * @param addr The address of the bluetooth device.
575      * @param context The pointer of profile.
576      * @since 6.0
577      */
578     void ProcessSDPFindCallback(const BtAddr &addr, const uint8_t result, A2dpProfile *instance) const;
579 
580     /**
581      * @brief Set whether the peer bluetooth device supports optional codec.
582      *
583      * @param device The address of the bluetooth device.
584      * @param Returns <b>A2DP_OPTIONAL_SUPPORT</b> The device supports optional codec.
585      *         Returns <b>A2DP_OPTIONAL_NOT_SUPPORT</b> The device doesn't support optional codec.
586      *         Returns <b>A2DP_OPTIONAL_SUPPORT_UNKNOWN</b> Don't know if the device support optional codec.
587      * @since 6.0
588      */
589     void SetOptionalCodecsSupportState(const RawAddress &device, int state);
590 
591     /**
592      * @brief Find the state matched
593      *
594      * @param states The states searched
595      * @param connectState The state of device connected
596      * @return Returns <b>true</b> if the codec configuration is valid.
597      *         Returns <b>false</b> if the codec configuration is invalid.
598      * @since 6.0
599      */
600     bool FindStateMatched(std::vector<int> states, int connectState) const;
601 
602     /**
603      * @brief Check if other codec configuration is similar with current configuration.
604      *
605      * @param codecInfo  codec configuration saved.
606      * @param newInfo  Another codec configuration.
607      * @return Returns <b>true</b> if other codec configuration is similar with current configuration.
608      *         Returns <b>false</b> if other codec configuration is not similar with current configuration.
609      * @since 6.0
610      */
611     bool IsSimilarCodecConfig(A2dpSrcCodecInfo codecInfo, A2dpSrcCodecInfo newInfo) const;
612 
613     /**
614      * @brief Check if the codec information matches local information.
615      *
616      * @param codecInfo The codec information.
617      * @param codecStatus The codec status information of local device.
618      * @return Returns <b>true</b> codec information matches confirmed information.
619      *         Returns <b>false</b> codec information doesn't match local information.
620      * @since 6.0
621      */
622     bool IsLocalCodecInfo(A2dpSrcCodecStatus codecStatus, A2dpSrcCodecInfo codecInformation) const;
623 
624     int maxConnectNumSnk_ = A2DP_CONNECT_NUM_MAX;             // max number of connected peer device
625     uint8_t role_ = A2DP_ROLE_SOURCE;                         // A2DP role
626     uint32_t profileId_ = PROFILE_ID_A2DP_SRC;                // profile ID
627     RawAddress activeDevice_ {};                               // Address to active device
628     A2dpConnectManager connectManager_ {};                     // A2dpConnectManager's object pointer.
629     ObserverProfile profileObserver_ {};                       // Observer pointer of profile.
630     std::string name_ = "";                                   // service name
631     std::string version_ = "";                                // profile's version
632     std::map<std::string, A2dpDeviceInfo *> a2dpDevices_ {};   // devicelist
633     BaseObserverList<IA2dpObserver> a2dpFramworkCallback_ {};  // callback of framework.
634     bool isDoDisable = false;                                 // if device will disable
635 };
636 
637 /**
638  * @brief A function to get profile instance
639  *
640  * @param[in] role The role of profile
641  * @since 6.0
642  */
643 A2dpProfile *GetProfileInstance(uint8_t role);
644 
645 /**
646  * @brief A function to get profile instance
647  *
648  * @param[in] role The role of profile
649  * @since 6.0
650  */
651 A2dpService *GetServiceInstance(uint8_t role);
652 }  // namespace bluetooth
653 }  // namespace OHOS
654 #endif  // A2DP_SERVICE_H