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