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 #ifndef HFP_AG_SDP_CLIENT_H
17 #define HFP_AG_SDP_CLIENT_H
18 
19 #include <cstdint>
20 #include <map>
21 #include <mutex>
22 #include <string>
23 #include <vector>
24 
25 #include "base_def.h"
26 #include "hfp_ag_defines.h"
27 #include "sdp.h"
28 
29 namespace OHOS {
30 namespace bluetooth {
31 typedef struct {
32     uint16_t attributeId {0};
33     SdpDataType type {SDP_TYPE_UINT_8};
34     uint16_t attributeValue {0};
35 } HfpAgSdpAttribute;
36 
37 typedef struct {
38     std::vector<SdpProtocolDescriptor> descriptors {};        // HF protocol descriptor
39     std::vector<SdpProfileDescriptor> profileDescriptors {};  // HF profile descriptor
40     std::vector<HfpAgSdpAttribute> attributes {};             // HF attribute descriptor
41 } HfpAgRemoteSdpService;
42 
43 typedef struct {
44     std::vector<HfpAgRemoteSdpService> services {};  // HF service descriptor
45 } HfpAgRemoteSdpServiceArray;
46 
47 /**
48  * @brief Class for discovery remote HF device's SDP server and finding out
49  *        related SDP info required by HFP AG role.
50  */
51 class HfpAgSdpClient {
52 public:
53     /**
54      * @brief Construct a new HfpAgSdpClient object.
55      */
56     HfpAgSdpClient() = default;
57 
58     /**
59      * @brief Destroy the HfpAgSdpClient object.
60      */
61     ~HfpAgSdpClient();
62 
63     /**
64      * @brief Callback function of SDP discovery.
65      *
66      * @param addr Remote device address defined bt stack.
67      * @param serviceAry Array of services discovered.
68      * @param serviceNum Number of services discovered.
69      * @param context Upper layer context.
70      */
71     static void SdpCallback(const BtAddr *addr, const SdpService *serviceAry, uint16_t serviceNum, void *context);
72 
73     /**
74      * @brief Start a service discovery job.
75      *
76      * @param remoteAddr Remote device address.
77      * @param role Role in connection.
78      * @return Returns the error code of the discovery result.
79      */
80     int DoDiscovery(const std::string &remoteAddr, int role);
81 
82     /**
83      * @brief Callback function of SDP discovery for HSP HS.
84      *
85      * @param addr Remote device address defined bt stack.
86      * @param serviceAry Array of services discovered.
87      * @param serviceNum Number of services discovered.
88      * @param context Upper layer context.
89      */
90     static void SdpHspHsCallback(const BtAddr *addr, const SdpService *serviceAry, uint16_t serviceNum, void *context);
91 
92     /**
93      * @brief Start a service discovery job for HSP HS.
94      *
95      * @param remoteAddr Remote device address.
96      * @return Returns the error code of the discovery result.
97      */
98     int DoHspHsDiscovery(const std::string &remoteAddr);
99 
100     /**
101      * @brief Start a find service attributes job.
102      *
103      * @param remoteAddr Remote device address.
104      * @param role Role in connection.
105      * @return Returns <b>true</b> if the operation is successful; returns <b>false</b> if the operation fails.
106      */
107     bool FindAttributes(const std::string &remoteAddr, int role);
108 
109     /**
110      * @brief Get the Remote Sdp Info object.
111      *
112      * @return Returns the HfpAgRemoteSdpInfo object.
113      */
114     HfpAgRemoteSdpInfo GetRemoteSdpInfo() const;
115 
116 private:
117     /**
118      * @brief Cache SDP result data locally.
119      *
120      * @param remoteAddr Remote device address.
121      * @param serviceAry Array of services discovered.
122      * @param serviceNum Number of services discovered.
123      */
124     static void CopySdpServiceArray(const std::string &remoteAddr, const SdpService *serviceAry, uint16_t serviceNum);
125 
126     /**
127      * @brief Delete local cached SDP result data.
128      *
129      * @param array Array of services reserved.
130      */
131     static void DeleteSdpServiceArray(HfpAgRemoteSdpServiceArray &array);
132 
133     /**
134      * @brief Loop all protocol to find rfcomm scn.
135      *
136      * @param loopNum Loop Number.
137      * @param array Remote HF device SDP service array.
138      * @param scn Server channel number.
139      * @return Returns <b>true</b> if the operation is successful; returns <b>false</b> if the operation fails.
140      */
141     bool LoopAllProtocolRfcomm(uint16_t &loopNum, const HfpAgRemoteSdpServiceArray &array, uint8_t &scn) const;
142 
143     /**
144      * @brief Find out remote server channel number.
145      *
146      * @param protocols Protocol descriptors.
147      * @param scn[out] Remote server channel number.
148      * @return Returns <b>true</b> if the operation is successful; returns <b>false</b> if the operation fails.
149      */
150     static bool FindProtocolRfcomm(const std::vector<SdpProtocolDescriptor> &protocols, uint8_t &scn);
151 
152     /**
153      * @brief Find out remote profile version.
154      *
155      * @param profiles Profile descriptors.
156      * @param version[out] Remote profile version.
157      * @return Returns <b>true</b> if the operation is successful; returns <b>false</b> if the operation fails.
158      */
159     static bool FindProfileVersion(const std::vector<SdpProfileDescriptor> &profiles, uint16_t &version);
160 
161     /**
162      * @brief Find out remote HF features.
163      *
164      * @param attributes Attribute descriptors.
165      * @param features[out] Remote HF features.
166      * @return Returns <b>true</b> if the operation is successful; returns <b>false</b> if the operation fails.
167      */
168     static bool FindProfileFeatures(const std::vector<HfpAgSdpAttribute> &attributes, uint16_t &features);
169 
170     inline static constexpr uint16_t HFP_AG_CLIENT_CLASSID_NUM = 1;
171     inline static constexpr uint16_t HFP_AG_CLIENT_INITIATOR_ATTR_NUM = 4;
172     inline static constexpr uint16_t HFP_AG_CLIENT_ACCEPTOR_ATTR_NUM = 3;
173 
174     // Remote device SDP info after DoDiscovery()
175     static std::map<std::string, HfpAgRemoteSdpServiceArray> g_remoteSdpServiceArrays;
176 
177     // Attribute occupy one byte
178     inline static constexpr int ATTRIBUTE_LENGTH_UINT8 = 1;
179 
180     // Attribute occupy two bytes
181     inline static constexpr int ATTRIBUTE_LENGTH_UINT16 = 2;
182 
183     inline static constexpr int SERVICE_CLASS_ID_LIST_INDEX = 0;
184     inline static constexpr int PROTOCOL_DESCRIPTOR_LIST_INDEX = 1;
185     inline static constexpr int INITIATOR_PROFILE_DESCRIPTOR_LIST_INDEX = 2;
186     inline static constexpr int ACCEPTER_PROFILE_DESCRIPTOR_LIST_INDEX = 1;
187     inline static constexpr int INITIATOR_SUPPORTED_FEATURES_INDEX = 3;
188     inline static constexpr int ACCEPTER_SUPPORTED_FEATURES_INDEX = 2;
189 
190     // Current remote device address
191     std::string currentAddr_ {""};
192 
193     // Remote device SDP info after last FindAttributes()
194     HfpAgRemoteSdpInfo remoteSdpInfo_ {};
195 
196     // The mutex variable
197     static std::recursive_mutex g_hfpSdpMutex;
198 
199     int hspState_ = 1;
200 
201     BT_DISALLOW_COPY_AND_ASSIGN(HfpAgSdpClient);
202 };
203 }  // namespace bluetooth
204 }  // namespace OHOS
205 #endif // HFP_AG_SDP_CLIENT_H