• 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 #ifndef PBAP_PSE_STATE_MACHINE_H
17 #define PBAP_PSE_STATE_MACHINE_H
18 
19 #include <cstdint>
20 #include <cstring>
21 #include <functional>
22 #include <memory>
23 #include <vector>
24 #include "../obex/obex_headers.h"
25 #include "../obex/obex_session.h"
26 #include "../obex/obex_types.h"
27 #include "base_def.h"
28 #include "base_observer_list.h"
29 #include "bt_def.h"
30 #include "interface_profile_pbap_pse.h"
31 #include "pbap_pse_def.h"
32 #include "pbap_pse_header_msg.h"
33 #include "pbap_pse_vcard_manager.h"
34 #include "raw_address.h"
35 #include "state_machine.h"
36 #include "timer.h"
37 
38 namespace OHOS {
39 namespace bluetooth {
40 struct PbapPseStateMachineInfo {
41     ObexServerSession *obexSession_ = nullptr;
42     uint32_t connectId_ = 0;
43     // If the PbapPceSupportedFeatures parameter is not present, 0x00000003 shall be assumed for a remote PCE.
44     uint32_t pceFeatures_ = 0x00000003;
45     bool accepted_ = false;  // is accepted?
46     bool isBusy_ = false;    // is busy?
47 };
48 
49 struct PbapPsePhoneBookResOpt {
50     bool newMissedCall_ = false;
51     bool phonebookSize_ = false;
52     bool dbIdentifier_ = false;
53     bool folderVer_ = false;
54 };
55 
56 class PbapPseStateMachine : public utility::StateMachine {
57 public:
58     // const for state machine start
59     static const std::string PSE_WAITING_FOR_CONNECT_STATE;
60     static const std::string PSE_CONNECTED_STATE;
61     static const std::string PSE_CONNECTING_STATE;
62     static const std::string PSE_DISCONNECTED_STATE;
63     static const std::string PSE_DISCONNECTING_STATE;
64     /**
65      * @brief constructor
66      * construct PseConnecting instance
67      */
68     explicit PbapPseStateMachine(const RawAddress &device, BaseObserverList<IPbapPseObserver> &observerMgrList,
69         std::function<uint32_t()> getNextConnectIdFun);
70 
71     virtual ~PbapPseStateMachine();
72     /**
73      * @brief Init PbapPseStateMachine
74      * @details Init PbapPseStateMachine
75      */
76     void Init();
77 
78     /**
79      * Start Timer
80      * @brief callback callback
81      * @details ms time out
82      */
83     bool StartTimer(std::function<void()> callback, int ms);
84 
85     /**
86      * Stop Timer
87      * @brief callback callback
88      * @details ms time out
89      */
90     void StopTimer();
91 
92     /**
93      * @brief Get the Connect State object
94      *
95      * @return BTConnectState
96      */
97     BTConnectState GetConnectState() const;
98 
99     /**
100      * @brief get remote address
101      * @details get remote address
102      * @return RawAddress&
103      */
104     const RawAddress &GetDevice() const;
105     /**
106      * @brief Is Connected
107      * @details Is Connected
108      * @return bool
109      */
110     bool IsConnected() const;
111     /**
112      * @brief Is Accepted
113      * @details Is Accepted
114      * @return bool
115      */
116     bool IsAccepted() const;
117     void SetBusy(bool isBusy);
118     bool IsBusy() const;
119     PbapPseStateMachineInfo &GetStmInfo();
120 
121 private:
122     PbapPseStateMachineInfo stmInfo_ {};
123     const RawAddress device_ {""};  // remote device
124     BaseObserverList<IPbapPseObserver> &observerMgrList_;
125     std::unique_ptr<utility::Timer> timer_ = nullptr;
126     std::function<uint32_t()> getNextConnectIdFun_ {};
127     BT_DISALLOW_COPY_AND_ASSIGN(PbapPseStateMachine);
128 };
129 
130 /**
131  * @brief disconnected statemachine
132  * control disconnected state
133  */
134 class PseDisConnected : public utility::StateMachine::State {
135 public:
136     /**
137      * @brief constructor
138      * construct PceDisconnected instance
139      */
140     explicit PseDisConnected(
141         const std::string &name, PbapPseStateMachine &stm, BaseObserverList<IPbapPseObserver> &observerMgrList);
142     virtual ~PseDisConnected() = default;
143     /**
144      * @brief entry
145      * @details when become PseDisConnecting, call this
146      * @return void
147      */
148     void Entry() override;
149     /**
150      * @brief exit
151      * @details when leave PseDisConnecting, call this
152      * @return void
153      */
154     void Exit() override;
155     /**
156      * @brief Dispatch
157      * @details when Dispatch PseDisConnecting, call this
158      * @param msg message
159      * @return bool true:success false:failure
160      */
161     bool Dispatch(const utility::Message &msg) override;
162 
163 private:
164     PbapPseStateMachine &stm_;
165     BaseObserverList<IPbapPseObserver> &observerMgrList_;
166 };
167 /**
168  * @brief Connecting statemachine
169  * control Connecting state
170  */
171 class PseDisConnecting : public utility::StateMachine::State {
172 public:
173     /**
174      * @brief constructor
175      * construct PceDisconnected instance
176      */
177     explicit PseDisConnecting(
178         const std::string &name, PbapPseStateMachine &stm, BaseObserverList<IPbapPseObserver> &observerMgrList);
179     virtual ~PseDisConnecting() = default;
180     /**
181      * @brief entry
182      * @details when become PseDisConnecting, call this
183      * @return void
184      */
185     void Entry() override;
186     /**
187      * @brief exit
188      * @details when leave PseDisConnecting, call this
189      * @return void
190      */
191     void Exit() override;
192     /**
193      * @brief Dispatch
194      * @details when Dispatch PseDisConnecting, call this
195      * @param msg message
196      * @return bool true:success false:failure
197      */
198     bool Dispatch(const utility::Message &msg) override;
199 
200 private:
201     PbapPseStateMachine &stm_;
202     BaseObserverList<IPbapPseObserver> &observerMgrList_;
203 };
204 /**
205  * @brief WaitingForConnect statemachine
206  * control WaitingForConnect state
207  */
208 class PseWaitingForConnect : public utility::StateMachine::State {
209 public:
210     /**
211      * @brief constructor
212      * construct PceDisconnected instance
213      */
214     explicit PseWaitingForConnect(const std::string &name, PbapPseStateMachine &stm);
215     virtual ~PseWaitingForConnect() = default;
216     /**
217      * @brief entry
218      * @details when become WaitingForConnect, call this
219      * @return void
220      */
221     void Entry() override;
222     /**
223      * @brief exit
224      * @details when leave WaitingForConnect, call this
225      * @return void
226      */
227     void Exit() override;
228     /**
229      * @brief Dispatch
230      * @details when Dispatch WaitingForConnect, call this
231      * @param msg message
232      * @return bool true:success false:failure
233      */
234     bool Dispatch(const utility::Message &msg) override;
235 
236 private:
237     PbapPseStateMachine &stm_;
238     BT_DISALLOW_COPY_AND_ASSIGN(PseWaitingForConnect);
239 };
240 /**
241  * @brief Connecting statemachine
242  * control Connecting state
243  */
244 class PseConnecting : public utility::StateMachine::State {
245 public:
246     /**
247      * @brief constructor
248      * construct PseConnecting instance
249      */
250     explicit PseConnecting(const std::string &name, PbapPseStateMachine &stm,
251         BaseObserverList<IPbapPseObserver> &observerMgrList, std::function<uint32_t()> &getNextConnectIdFun);
252     virtual ~PseConnecting() = default;
253     /**
254      * @brief entry
255      * @details when become PseConnecting, call this
256      * @return void
257      */
258     void Entry() override;
259     /**
260      * @brief exit
261      * @details when leave PseConnecting, call this
262      * @return void
263      */
264     void Exit() override;
265     /**
266      * @brief Dispatch
267      * @details when Dispatch PseConnecting, call this
268      * @param msg message
269      * @return bool true:success false:failure
270      */
271     bool Dispatch(const utility::Message &msg) override;
272 
273 private:
274     void CheckConnectReq(const PbapPseObexMessage &obexMsg);
275     void CheckAuthChallenges(const ObexHeader &req, const ObexOptionalTlvHeader &authChallenges);
276     void PasswordInput(const PbapPsePasswordInputMsg &pwdInputMsg);
277 
278     bool CheckConnectHeader(const ObexHeader &req) const;
279     void ToDisconnect(ObexRspCode rspCode = ObexRspCode::NOT_ACCEPTABLE);
280     void SendSuccessResponse(const std::string &userId = "", const std::string &pwd = "");
281     void AcceptConnection();
282     void RejectConnection();
283     std::vector<uint8_t> authNonce_ {};
284     std::vector<uint8_t> authDescription_ {};
285     bool authChallenge_ = false;
286     uint8_t authUserCharset_ = 0;
287     bool authNeedUser_ = false;
288     bool authFullAccess_ = false;
289     bool waitingDisconnect_ = false;
290     PbapPseStateMachine &stm_;
291     BaseObserverList<IPbapPseObserver> &observerMgrList_;
292     ObexIncomingConnect *incomeConnect_ = nullptr;
293     std::function<uint32_t()> &getNextConnectIdFun_;
294     BT_DISALLOW_COPY_AND_ASSIGN(PseConnecting);
295 };
296 
297 class PseConnected : public utility::StateMachine::State {
298 public:
299     /**
300      * @brief constructor
301      * construct PseConnecting instance
302      */
303     explicit PseConnected(
304         const std::string &name, PbapPseStateMachine &stm, BaseObserverList<IPbapPseObserver> &observerMgrList);
305     virtual ~PseConnected() = default;
306     /**
307      * @brief entry
308      * @details when become disconnected, call this
309      * @return void
310      */
311     void Entry() override;
312     /**
313      * @brief exit
314      * @details when leave disconnected, call this
315      * @return void
316      */
317     void Exit() override;
318     /**
319      * @brief Dispatch
320      * @details when Dispatch PseConnecting, call this
321      * @param msg message
322      * @return bool true:success false:failure
323      */
324     bool Dispatch(const utility::Message &msg) override;
325 
326 private:
327     uint32_t GetSupportedFeatures() const;
328     void DisconnectObex(const PbapPseObexMessage &obexMsg) const;
329     void HandleGetRequest(const PbapPseObexMessage &obexMsg);
330     void HandleSetPathRequest(const PbapPseObexMessage &obexMsg);
331 
332     void PullPhoneBook(ObexServerSession &obexSession, const ObexHeader &req) const;
333     void PullvCardListing(ObexServerSession &obexSession, const ObexHeader &req) const;
334     void PullvCardEntry(ObexServerSession &obexSession, const ObexHeader &req) const;
335     bool CheckvCardEntryId(std::u16string &entryId) const;
336     void SendPhoneBookResponse(ObexServerSession &obexSession, const ObexHeader &req,
337         const PbapPseVcardManager::PhoneBookResult &pbResult, const PbapPsePhoneBookResOpt &opt) const;
338     bool IsVCardName(std::u16string &name) const;
339     std::u16string GetCurrentPath() const;
340     std::u16string GetFullPath(const std::vector<std::u16string> &paths) const;
341     std::vector<std::u16string> currentPath_ {};  // record current path the client are browsing
342     PbapPseStateMachine &stm_;
343     BaseObserverList<IPbapPseObserver> &observerMgrList_;
344 };
345 }  // namespace bluetooth
346 }  // namespace OHOS
347 #endif  // PBAP_PSE_STATE_MACHINE_H
348