1 /*
2 * Copyright (C) 2021 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 #include "pbap_pce_state_machine.h"
17 #include <codecvt>
18 #include <fstream>
19 #include <locale>
20 #include <sstream>
21 #include <vector>
22 #include "bt_def.h"
23 #include "btm.h"
24 #include "obex/obex_utils.h"
25 #include "pbap_pce_app_params.h"
26 #include "pbap_pce_connected_state.h"
27 #include "pbap_pce_connecting_state.h"
28 #include "pbap_pce_def.h"
29 #include "pbap_pce_disconnected_state.h"
30 #include "pbap_pce_disconnecting_state.h"
31 #include "pbap_pce_service.h"
32 #include "power_manager.h"
33
34 namespace OHOS {
35 namespace bluetooth {
PbapPceStateMachine(const RawAddress & dev,PbapPceService & pceService,PbapPceSdp & pbapPceSdp,BaseObserverList<IPbapPceObserver> & observerMgrList)36 PbapPceStateMachine::PbapPceStateMachine(const RawAddress &dev, PbapPceService &pceService, PbapPceSdp &pbapPceSdp,
37 BaseObserverList<IPbapPceObserver> &observerMgrList)
38 : device_(dev),
39 pceService_(&pceService),
40 pbapPceSdp_(pbapPceSdp),
41 observerMgrList_(observerMgrList),
42 targetState_(PCE_TARGET_STATE_UNKNOWN)
43 {
44 LOG_INFO("%{public}s start", __PRETTY_FUNCTION__);
45 std::unique_ptr<State> disconnected =
46 std::make_unique<PceDisconnectedState>(PCE_DISCONNECTED_STATE, *this, observerMgrList);
47 std::unique_ptr<State> connecting =
48 std::make_unique<PceConnectingState>(PCE_CONNECTING_STATE, *this, observerMgrList);
49 std::unique_ptr<State> disconnecting =
50 std::make_unique<PceDisconnectingState>(PCE_DISCONNECTING_STATE, *this, observerMgrList);
51 std::unique_ptr<State> connected = std::make_unique<PceConnectedState>(PCE_CONNECTED_STATE, *this, observerMgrList);
52 Move(disconnected);
53 Move(connecting);
54 Move(disconnecting);
55 Move(connected);
56
57 InitState(PCE_CONNECTING_STATE);
58 PBAP_PCE_LOG_INFO("%{public}s end", __PRETTY_FUNCTION__);
59 }
60
IsRepositorySupported(const std::u16string & name) const61 bool PbapPceStateMachine::IsRepositorySupported(const std::u16string &name) const
62 {
63 PBAP_PCE_LOG_INFO("%{public}s start", __PRETTY_FUNCTION__);
64 bool ret = false;
65 std::vector<std::u16string> localPhoneBook = {u"pb", u"ich", u"och", u"mch", u"cch", u"spd", u"fav"};
66 bool isLocalPhoneBook = false;
67 for (auto subpath : localPhoneBook) {
68 if (std::u16string::npos != name.find(subpath)) {
69 isLocalPhoneBook = true;
70 break;
71 }
72 }
73
74 bool isSim = name.find(u"SIM") != std::u16string::npos;
75 bool isFav = name.find(u"fav") != std::u16string::npos;
76 if (isLocalPhoneBook && (GetSupportedRes() & PBAP_PCE_SUPPORTED_REPOS_LOCALPB)) {
77 ret = true;
78 } else if (isSim && (GetSupportedRes() & PBAP_PCE_SUPPORTED_REPOS_SIMCARD)) {
79 ret = true;
80 } else if (isFav && (GetSupportedRes() & PBAP_PCE_SUPPORTED_REPOS_FAV)) {
81 ret = true;
82 } else {
83 ret = false;
84 }
85 PBAP_PCE_LOG_INFO("%{public}s end", __PRETTY_FUNCTION__);
86 return ret;
87 }
88
PullPhoneBook(const IPbapPullPhoneBookParam & param)89 void PbapPceStateMachine::PullPhoneBook(const IPbapPullPhoneBookParam ¶m)
90 {
91 PBAP_PCE_LOG_INFO("%{public}s start", __PRETTY_FUNCTION__);
92 if (pceObexClient_ == nullptr) {
93 PBAP_PCE_LOG_ERROR("%{public}s end, pceObexClient_ is null", __PRETTY_FUNCTION__);
94 return;
95 }
96 auto pbReqHeader = ObexHeader::CreateRequest(ObexOpeId::GET_FINAL);
97 pbReqHeader->AppendItemConnectionId(connectId_);
98 pbReqHeader->AppendItemType("x-bt/phonebook");
99 pbReqHeader->AppendItemName(param.GetName());
100 SetReqVcardFileName(param.GetName());
101 PbapPceAppParams appParams;
102 if (param.IsSpecified(IPbapPullPhoneBookParam::PROPERTY_SELECTOR)) {
103 appParams.SetPropertySelector(param.GetPropertySelector());
104 }
105 if (param.IsSpecified(IPbapPullPhoneBookParam::FORMAT)) {
106 appParams.SetFormat(param.GetFormat());
107 }
108 bool requestSize = false;
109 if (param.IsSpecified(IPbapPullPhoneBookParam::MAX_LIST_COUNT)) {
110 appParams.SetMaxListCount(param.GetMaxListCount());
111 requestSize = (param.GetMaxListCount() == 0);
112 }
113 if (param.IsSpecified(IPbapPullPhoneBookParam::LIST_START_OFFSET)) {
114 appParams.SetListStartOffset(param.GetListStartOffset());
115 }
116 if (param.IsSpecified(IPbapPullPhoneBookParam::RESET_NEW_MISSED_CALLS)) {
117 appParams.SetResetNewMissedCalls(param.GetResetNewMissedCalls());
118 }
119 if (param.IsSpecified(IPbapPullPhoneBookParam::VCARD_SELECTOR)) {
120 appParams.SetVcardSelector(param.GetvCardSelector());
121 }
122 if (param.IsSpecified(IPbapPullPhoneBookParam::VCARD_SELECTOROP)) {
123 appParams.SetVcardSelectorOperator(param.GetvCardSelectorOp());
124 }
125 PBAP_PCE_LOG_DEBUG("%{public}s, %{public}s", __PRETTY_FUNCTION__, param.ToDebugString().c_str());
126 appParams.AddToObexHeader(*pbReqHeader);
127 SetPowerStatusBusy(true);
128 pceObexClient_->Get(*pbReqHeader, requestSize ? PCE_REQ_PULLPHONEBOOKSIZE : PCE_REQ_PULLPHONEBOOK);
129 PBAP_PCE_LOG_INFO("%{public}s end", __PRETTY_FUNCTION__);
130 }
131
SetPhoneBook(const std::u16string & name,int flag)132 void PbapPceStateMachine::SetPhoneBook(const std::u16string &name, int flag)
133 {
134 PBAP_PCE_LOG_INFO("%{public}s start", __PRETTY_FUNCTION__);
135 std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
136 std::string nameStr = converter.to_bytes(name);
137 PBAP_PCE_LOG_DEBUG("%{public}s name=%{public}s, flag=%{public}d", __PRETTY_FUNCTION__, nameStr.c_str(), flag);
138 if (pceObexClient_ == nullptr) {
139 PBAP_PCE_LOG_ERROR("%{public}s end, pceObexClient_ is null", __PRETTY_FUNCTION__);
140 return;
141 }
142 SetPowerStatusBusy(true);
143 pceObexClient_->SetPath(flag, name);
144 PBAP_PCE_LOG_INFO("%{public}s end", __PRETTY_FUNCTION__);
145 }
146
PullvCardListing(const IPbapPullvCardListingParam & param)147 void PbapPceStateMachine::PullvCardListing(const IPbapPullvCardListingParam ¶m)
148 {
149 PBAP_PCE_LOG_INFO("%{public}s start", __PRETTY_FUNCTION__);
150 if (pceObexClient_ == nullptr) {
151 PBAP_PCE_LOG_ERROR("%{public}s pceObexClient_ is null", __PRETTY_FUNCTION__);
152 return;
153 }
154 auto pbReqHeader = ObexHeader::CreateRequest(ObexOpeId::GET_FINAL);
155 pbReqHeader->AppendItemConnectionId(connectId_);
156 pbReqHeader->AppendItemType("x-bt/vcard-listing");
157 pbReqHeader->AppendItemName(param.GetName());
158
159 PbapPceAppParams appParams;
160 if (param.IsSpecified(IPbapPullvCardListingParam::ORDER)) {
161 appParams.SetOrder(param.GetOrder());
162 }
163 if (param.IsSpecified(IPbapPullvCardListingParam::SEARCH_VALUE)) {
164 std::vector<uint8_t> searchValueUtf8;
165 std::string value = param.GetSearchValue();
166 searchValueUtf8.assign(value.begin(), value.end());
167 appParams.SetSearchValueUtf8(searchValueUtf8);
168 }
169 if (param.IsSpecified(IPbapPullvCardListingParam::SEARCH_PROPERTY)) {
170 appParams.SetSearchProperty(param.GetSearchProperty());
171 }
172 bool requestSize = false;
173 if (param.IsSpecified(IPbapPullvCardListingParam::MAX_LIST_COUNT)) {
174 appParams.SetMaxListCount(param.GetMaxListCount());
175 requestSize = (param.GetMaxListCount() == 0);
176 }
177 if (param.IsSpecified(IPbapPullvCardListingParam::LIST_START_OFFSET)) {
178 appParams.SetListStartOffset(param.GetListStartOffset());
179 }
180 if (param.IsSpecified(IPbapPullvCardListingParam::RESET_NEW_MISSED_CALLS)) {
181 appParams.SetResetNewMissedCalls(param.GetResetNewMissedCalls());
182 }
183 if (param.IsSpecified(IPbapPullvCardListingParam::VCARD_SELECTOR)) {
184 appParams.SetVcardSelector(param.GetvCardSelector());
185 }
186 if (param.IsSpecified(IPbapPullvCardListingParam::VCARD_SELECTOROP)) {
187 appParams.SetVcardSelectorOperator(param.GetvCardSelectorOp());
188 }
189 PBAP_PCE_LOG_DEBUG("%{public}s, %{public}s", __PRETTY_FUNCTION__, param.ToDebugString().c_str());
190 appParams.AddToObexHeader(*pbReqHeader);
191 SetPowerStatusBusy(true);
192 pceObexClient_->Get(*pbReqHeader, requestSize ? PCE_REQ_PULLVCARDLISTINGSIZE : PCE_REQ_PULLVCARDLISTING);
193 PBAP_PCE_LOG_INFO("%{public}s end", __PRETTY_FUNCTION__);
194 }
195
PullvCardEntry(const IPbapPullvCardEntryParam & param)196 void PbapPceStateMachine::PullvCardEntry(const IPbapPullvCardEntryParam ¶m)
197 {
198 PBAP_PCE_LOG_INFO("%{public}s start", __PRETTY_FUNCTION__);
199 if (pceObexClient_ == nullptr) {
200 PBAP_PCE_LOG_ERROR("%{public}s end, pceObexClient_ is null", __PRETTY_FUNCTION__);
201 return;
202 }
203 auto pbReqHeader = ObexHeader::CreateRequest(ObexOpeId::GET_FINAL);
204 pbReqHeader->AppendItemConnectionId(connectId_);
205 pbReqHeader->AppendItemType("x-bt/vcard");
206 pbReqHeader->AppendItemName(param.GetName());
207 SetReqVcardFileName(param.GetName());
208
209 PbapPceAppParams appParams;
210 if (param.IsSpecified(IPbapPullvCardEntryParam::PROPERTY_SELECTOR)) {
211 appParams.SetPropertySelector(param.GetPropertySelector());
212 }
213 if (param.IsSpecified(IPbapPullvCardEntryParam::FORMAT)) {
214 appParams.SetFormat(param.GetFormat());
215 }
216 PBAP_PCE_LOG_DEBUG("%{public}s, %{public}s", __PRETTY_FUNCTION__, param.ToDebugString().c_str());
217 appParams.AddToObexHeader(*pbReqHeader);
218 SetPowerStatusBusy(true);
219 pceObexClient_->Get(*pbReqHeader, PCE_REQ_PULLVCARDENTRY);
220 PBAP_PCE_LOG_INFO("%{public}s end", __PRETTY_FUNCTION__);
221 }
222
RemoveBTMLogging() const223 void PbapPceStateMachine::RemoveBTMLogging() const
224 {
225 BtAddr btAddr;
226 btAddr.type = BT_PUBLIC_DEVICE_ADDRESS;
227 GetDevice().ConvertToUint8(btAddr.addr, sizeof(btAddr.addr));
228 if (IsGoepL2capPSM()) {
229 BTM_RemoveRemoteL2capPsmForLogging(BTM_HCI_LOG_FILTER_MODULE_PBAP,
230 GetGapSecChannel().l2capPsm,
231 &btAddr);
232 } else {
233 BTM_RemoveRemoteRfcommScnChannelForLogging(BTM_HCI_LOG_FILTER_MODULE_PBAP,
234 GetGapSecChannel().rfcommChannel,
235 &btAddr);
236 }
237 }
238
GetTargetState() const239 int PbapPceStateMachine::GetTargetState() const
240 {
241 return targetState_;
242 }
243
SetTargetState(int targetState)244 void PbapPceStateMachine::SetTargetState(int targetState)
245 {
246 targetState_ = targetState;
247 }
248
TransitTargetState()249 void PbapPceStateMachine::TransitTargetState()
250 {
251 PBAP_PCE_LOG_INFO("%{public}s start target=%{public}d", __PRETTY_FUNCTION__, GetTargetState());
252 if (GetTargetState() == PCE_TARGET_STATE_CONNECTED) {
253 GetPceService().Connect(GetDevice());
254 SetTargetState(PCE_TARGET_STATE_UNKNOWN);
255 } else if (GetTargetState() == PCE_TARGET_STATE_DISCONNECTED) {
256 GetPceService().Disconnect(GetDevice());
257 SetTargetState(PCE_TARGET_STATE_UNKNOWN);
258 }
259 PBAP_PCE_LOG_INFO("%{public}s end", __PRETTY_FUNCTION__);
260 }
261
IsBusy() const262 bool PbapPceStateMachine::IsBusy() const
263 {
264 PBAP_PCE_LOG_DEBUG("%{public}s start", __PRETTY_FUNCTION__);
265 bool ret = false;
266 if (pceObexClient_ != nullptr) {
267 ret = pceObexClient_->IsBusy();
268 } else {
269 PBAP_PCE_LOG_ERROR("%{public}s end, pceObexClient_ OR pceObexClient_->observer_ is null", __PRETTY_FUNCTION__);
270 }
271 PBAP_PCE_LOG_DEBUG("%{public}s end", __PRETTY_FUNCTION__);
272 return ret;
273 }
274
SetBusy(bool isBusy)275 bool PbapPceStateMachine::SetBusy(bool isBusy)
276 {
277 PBAP_PCE_LOG_DEBUG("%{public}s start", __PRETTY_FUNCTION__);
278 bool ret = false;
279 if (pceObexClient_ != nullptr) {
280 pceObexClient_->SetBusy(isBusy);
281 ret = true;
282 } else {
283 PBAP_PCE_LOG_ERROR("%{public}s end, pceObexClient_ OR pceObexClient_->observer_ is null", __PRETTY_FUNCTION__);
284 }
285 PBAP_PCE_LOG_DEBUG("%{public}s end", __PRETTY_FUNCTION__);
286 return ret;
287 }
288
SetPowerStatusBusy(bool isBusy)289 void PbapPceStateMachine::SetPowerStatusBusy(bool isBusy)
290 {
291 PBAP_PCE_LOG_DEBUG("%{public}s start", __PRETTY_FUNCTION__);
292 if (powerStatusBusy_ == isBusy) {
293 return;
294 }
295 powerStatusBusy_ = isBusy;
296 if (isBusy) {
297 HILOGI("[%{public}s] PowerStatusUpdate -> BUSY", GetEncryptAddr(device_.GetAddress()).c_str());
298 IPowerManager::GetInstance().StatusUpdate(RequestStatus::BUSY, PROFILE_NAME_PBAP_PCE, device_);
299 } else {
300 HILOGI("[%{public}s] PowerStatusUpdate -> IDLE", GetEncryptAddr(device_.GetAddress()).c_str());
301 IPowerManager::GetInstance().StatusUpdate(RequestStatus::IDLE, PROFILE_NAME_PBAP_PCE, device_);
302 }
303 PBAP_PCE_LOG_DEBUG("%{public}s end", __PRETTY_FUNCTION__);
304 return;
305 }
306
AbortDownloading()307 int PbapPceStateMachine::AbortDownloading()
308 {
309 PBAP_PCE_LOG_DEBUG("%{public}s start", __PRETTY_FUNCTION__);
310 if (pceObexClient_ == nullptr) {
311 PBAP_PCE_LOG_ERROR("%{public}s end, pceObexClient_ is null", __PRETTY_FUNCTION__);
312 return RET_BAD_STATUS;
313 }
314 PBAP_PCE_LOG_DEBUG("%{public}s end", __PRETTY_FUNCTION__);
315 SetPowerStatusBusy(true);
316 return pceObexClient_->Abort();
317 }
318
SetConnectId(uint32_t connectId)319 void PbapPceStateMachine::SetConnectId(uint32_t connectId)
320 {
321 connectId_ = connectId;
322 }
323
ReqDisconnect(bool withObexReq) const324 int PbapPceStateMachine::ReqDisconnect(bool withObexReq) const
325 {
326 PBAP_PCE_LOG_DEBUG("%{public}s start", __PRETTY_FUNCTION__);
327 if ((pceObexClient_ == nullptr)) {
328 PBAP_PCE_LOG_ERROR("%{public}s end, pceObexClient_ is null", __PRETTY_FUNCTION__);
329 return RET_BAD_STATUS;
330 }
331 pceObexClient_->Disconnect(withObexReq);
332 PBAP_PCE_LOG_DEBUG("%{public}s end", __PRETTY_FUNCTION__);
333 return BT_SUCCESS;
334 }
335
ObexHeaderToDataResult(const ObexHeader & resp,int actionType,IPbapPhoneBookData & retResult)336 bool PbapPceStateMachine::ObexHeaderToDataResult(const ObexHeader &resp, int actionType, IPbapPhoneBookData &retResult)
337 {
338 PBAP_PCE_LOG_DEBUG("%{public}s start", __PRETTY_FUNCTION__);
339
340 bool ret = false;
341 if (resp.GetItemAppParams() != nullptr) {
342 PbapPceAppParams appParams;
343 if (appParams.Init(*(resp.GetItemAppParams()->GetTlvParamters()))) {
344 if (appParams.GetPhonebookSize() != nullptr) {
345 retResult.phoneBookSize_ = *(appParams.GetPhonebookSize());
346 }
347 retResult.primaryFolderVersion_ = appParams.GetPrimaryFolderVersion();
348 retResult.secondaryFolderVersion_ = appParams.GetSecondaryFolderVersion();
349 retResult.databaseIdentifier_ = appParams.GetDatabaseIdentifier();
350 }
351 } else {
352 PBAP_PCE_LOG_INFO("%{public}s resp.GetItemAppParams() is null", __PRETTY_FUNCTION__);
353 }
354 auto &extendBody = resp.GetExtendBodyObject();
355 if (extendBody) {
356 if (actionType != PBAP_ACTION_PULLPHONEBOOK) {
357 const int bufSize = 100;
358 uint8_t buf[bufSize] = {0};
359 size_t cnt = 0;
360 while ((cnt = extendBody->Read(buf, bufSize)) > 0) {
361 retResult.result_.insert(retResult.result_.end(), buf, buf + cnt);
362 }
363 }
364 extendBody->Close();
365 }
366 ret = true;
367 PBAP_PCE_LOG_DEBUG("%{public}s end", __PRETTY_FUNCTION__);
368 return ret;
369 }
370
SplitFilePath(const std::u16string & filePath,std::u16string & retPath,std::u16string & retFileName)371 bool PbapPceStateMachine::SplitFilePath(
372 const std::u16string &filePath, std::u16string &retPath, std::u16string &retFileName)
373 {
374 bool ret = false;
375 size_t pos = filePath.find_last_of(u'/');
376 if (pos != std::u16string::npos) {
377 retPath = filePath.substr(0, pos);
378 retFileName = filePath.substr(pos + 1);
379 ret = true;
380 }
381 return ret;
382 }
383
Replace(const std::string & str,const std::string & oldStr,const std::string & newStr)384 std::string PbapPceStateMachine::Replace(const std::string &str, const std::string &oldStr, const std::string &newStr)
385 {
386 std::string strRet = str;
387 for (std::string::size_type pos = 0; pos != std::string::npos; pos += newStr.length()) {
388 pos = strRet.find(oldStr, pos);
389 if (pos != std::string::npos) {
390 strRet.replace(pos, oldStr.length(), newStr);
391 } else {
392 break;
393 }
394 }
395 return strRet;
396 }
397
U16ToStr(const std::u16string & str)398 std::string PbapPceStateMachine::U16ToStr(const std::u16string &str)
399 {
400 std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
401 return converter.to_bytes(str);
402 }
403
IsResponeOK(uint8_t respCode) const404 bool PbapPceStateMachine::IsResponeOK(uint8_t respCode) const
405 {
406 if ((respCode == static_cast<uint8_t>(ObexRspCode::SUCCESS)) ||
407 (respCode == static_cast<uint8_t>(ObexRspCode::CONTINUE))) {
408 return true;
409 }
410 return false;
411 }
412
HandlePhoneBookSizeActionCompleted(const utility::Message & msg)413 void PbapPceStateMachine::HandlePhoneBookSizeActionCompleted(const utility::Message &msg)
414 {
415 PBAP_PCE_LOG_INFO("%{public}s start", __PRETTY_FUNCTION__);
416 PbapPceActionObexMessage *pceObexMsg = static_cast<PbapPceActionObexMessage *>(msg.arg2_);
417 if (pceObexMsg == nullptr) {
418 PBAP_PCE_LOG_INFO("%{public}s end, pceObexMsg == nullptr!", __PRETTY_FUNCTION__);
419 return;
420 }
421 const ObexHeader *resp = pceObexMsg->GetObexHeader();
422 std::string respTxt;
423 IPbapPhoneBookData result;
424 uint8_t respCode = resp->GetFieldCode();
425 if (respCode == static_cast<uint8_t>(ObexRspCode::SUCCESS)) {
426 ObexHeaderToDataResult(*resp, PBAP_ACTION_PULLPHONEBOOKSIZE, result);
427 respTxt = "PhoneBookSize Success!";
428 }
429 if (IsResponeOK(respCode)) {
430 PBAP_PCE_LOG_INFO("%{public}s respCode:0x%x, respTxt:%{public}s",
431 __PRETTY_FUNCTION__, respCode, respTxt.c_str());
432 } else {
433 respTxt = "PhoneBookSize Error!";
434 PBAP_PCE_LOG_ERROR("%{public}s respCode:0x%x, respTxt:%{public}s",
435 __PRETTY_FUNCTION__, respCode, respTxt.c_str());
436 }
437 auto &device = GetDevice();
438 observerMgrList_.ForEach([device, respCode, result](IPbapPceObserver &observer) {
439 observer.OnActionCompleted(device, static_cast<int>(respCode), PBAP_ACTION_PULLPHONEBOOKSIZE, result);
440 });
441 PBAP_PCE_LOG_INFO("%{public}s end", __PRETTY_FUNCTION__);
442 }
443
HandlePullvCardListingSizeActionCompleted(const utility::Message & msg)444 void PbapPceStateMachine::HandlePullvCardListingSizeActionCompleted(const utility::Message &msg)
445 {
446 PBAP_PCE_LOG_INFO("%{public}s start", __PRETTY_FUNCTION__);
447 PbapPceActionObexMessage *pceObexMsg = static_cast<PbapPceActionObexMessage *>(msg.arg2_);
448 if (pceObexMsg == nullptr) {
449 PBAP_PCE_LOG_INFO("%{public}s end, pceObexMsg == nullptr!", __PRETTY_FUNCTION__);
450 return;
451 }
452 const ObexHeader *resp = pceObexMsg->GetObexHeader();
453 std::string respTxt;
454 IPbapPhoneBookData result;
455 uint8_t respCode = resp->GetFieldCode();
456 if (respCode == static_cast<uint8_t>(ObexRspCode::SUCCESS)) {
457 ObexHeaderToDataResult(*resp, PBAP_ACTION_PULLVCARDLISTINGSIZE, result);
458 respTxt = "PullvCardListingSize Success!";
459 }
460 if (IsResponeOK(respCode)) {
461 PBAP_PCE_LOG_INFO("%{public}s respCode:0x%x, respTxt:%{public}s",
462 __PRETTY_FUNCTION__, respCode, respTxt.c_str());
463 } else {
464 respTxt = "PullvCardListingSize Error!";
465 PBAP_PCE_LOG_ERROR("%{public}s respCode:0x%x, respTxt:%{public}s",
466 __PRETTY_FUNCTION__, respCode, respTxt.c_str());
467 }
468 auto &device = GetDevice();
469 observerMgrList_.ForEach([device, respCode, result](IPbapPceObserver &observer) {
470 observer.OnActionCompleted(device, static_cast<int>(respCode), PBAP_ACTION_PULLVCARDLISTINGSIZE, result);
471 });
472 PBAP_PCE_LOG_INFO("%{public}s end", __PRETTY_FUNCTION__);
473 }
474
HandlePullPhoneBookActionCompleted(const utility::Message & msg)475 void PbapPceStateMachine::HandlePullPhoneBookActionCompleted(const utility::Message &msg)
476 {
477 PBAP_PCE_LOG_INFO("%{public}s start", __PRETTY_FUNCTION__);
478 PbapPceActionObexMessage *pceObexMsg = static_cast<PbapPceActionObexMessage *>(msg.arg2_);
479 if (pceObexMsg == nullptr) {
480 PBAP_PCE_LOG_INFO("%{public}s end, pceObexMsg == nullptr!", __PRETTY_FUNCTION__);
481 return;
482 }
483 const ObexHeader *resp = pceObexMsg->GetObexHeader();
484 uint8_t respCode = resp->GetFieldCode();
485 std::string respTxt;
486 std::string respBodyObject;
487 IPbapPhoneBookData result;
488 InitIPbapPhoneBookData(result);
489 if (respCode == static_cast<uint8_t>(ObexRspCode::SUCCESS)) {
490 if (ObexHeaderToDataResult(*resp, PBAP_ACTION_PULLPHONEBOOK, result)) {
491 #ifdef PBAP_PCE_RECEIVED_BY_OBEX_ARRAY
492 respBodyObject.assign(result.result_.begin(), result.result_.end());
493 respTxt = "PullPhoneBook Completed:\n" + respBodyObject;
494 #else
495 result.resultLoaded_ = 0;
496 result.result_.clear();
497 respTxt = "PullPhoneBook Completed:\n";
498 #endif // PBAP_PCE_RECEIVED_BY_OBEX_ARRAY
499 }
500 }
501
502 if (IsResponeOK(respCode)) {
503 PBAP_PCE_LOG_INFO("%{public}s respCode:0x%x, respTxt:%{public}s",
504 __PRETTY_FUNCTION__, respCode, respTxt.c_str());
505 } else {
506 respTxt = "PullPhoneBook Error!";
507 PBAP_PCE_LOG_ERROR("%{public}s respCode:0x%x, respTxt:%{public}s",
508 __PRETTY_FUNCTION__, respCode, respTxt.c_str());
509 }
510
511 auto &device = GetDevice();
512 observerMgrList_.ForEach([device, respCode, result](IPbapPceObserver &observer) {
513 observer.OnActionCompleted(device, static_cast<int>(respCode), PBAP_ACTION_PULLPHONEBOOK, result);
514 });
515 PBAP_PCE_LOG_INFO("%{public}s end", __PRETTY_FUNCTION__);
516 }
517
HandleSetPhoneBookActionCompleted(const utility::Message & msg)518 void PbapPceStateMachine::HandleSetPhoneBookActionCompleted(const utility::Message &msg)
519 {
520 PBAP_PCE_LOG_INFO("%{public}s start", __PRETTY_FUNCTION__);
521 PbapPceActionObexMessage *pceObexMsg = static_cast<PbapPceActionObexMessage *>(msg.arg2_);
522 if (pceObexMsg == nullptr) {
523 PBAP_PCE_LOG_INFO("%{public}s end, pceObexMsg == nullptr!", __PRETTY_FUNCTION__);
524 return;
525 }
526 const ObexHeader *resp = pceObexMsg->GetObexHeader();
527 std::string respTxt;
528 uint8_t respCode = resp->GetFieldCode();
529 std::u16string name = pceObexMsg->GetName();
530 if (respCode == static_cast<uint8_t>(ObexRspCode::SUCCESS)) {
531 // PBAP v1.2.3
532 // go up - bit0=1; go down - bit0=0; go to root - bit0=0 && Name is empty.
533 const uint8_t flagMask = 0x01;
534 if (name.find(u'/') != std::u16string::npos) {
535 SetCurrentPath(name);
536 } else if (pceObexMsg->GetFlags() & flagMask) {
537 // go up
538 std::u16string currentPath = GetCurrentPath();
539 size_t pos = currentPath.find_last_of(u'/');
540 if (pos != std::u16string::npos) {
541 currentPath = currentPath.substr(0, pos);
542 SetCurrentPath(currentPath);
543 } else {
544 SetCurrentPath(u""); // root
545 }
546 } else {
547 // go to root
548 if (name.empty()) {
549 SetCurrentPath(name);
550 }
551 }
552 respTxt = "SetPhoneBook completed!";
553 }
554 if (IsResponeOK(respCode)) {
555 PBAP_PCE_LOG_INFO("%{public}s respCode:0x%x, respTxt:%{public}s",
556 __PRETTY_FUNCTION__, respCode, respTxt.c_str());
557 } else {
558 respTxt = "SetPhoneBook Error!";
559 PBAP_PCE_LOG_ERROR("%{public}s respCode:0x%x, respTxt:%{public}s",
560 __PRETTY_FUNCTION__, respCode, respTxt.c_str());
561 }
562 IPbapPhoneBookData result;
563 auto &device = GetDevice();
564 observerMgrList_.ForEach([device, respCode, result](IPbapPceObserver &observer) {
565 observer.OnActionCompleted(device, static_cast<int>(respCode), PBAP_ACTION_SETPHONEBOOK, result);
566 });
567 PBAP_PCE_LOG_INFO("%{public}s end", __PRETTY_FUNCTION__);
568 }
569
HandlePullvCardListingActionCompleted(const utility::Message & msg)570 void PbapPceStateMachine::HandlePullvCardListingActionCompleted(const utility::Message &msg)
571 {
572 PBAP_PCE_LOG_INFO("%{public}s start", __PRETTY_FUNCTION__);
573 PbapPceActionObexMessage *pceObexMsg = static_cast<PbapPceActionObexMessage *>(msg.arg2_);
574 if (pceObexMsg == nullptr) {
575 PBAP_PCE_LOG_INFO("%{public}s end, pceObexMsg == nullptr!", __PRETTY_FUNCTION__);
576 return;
577 }
578
579 const ObexHeader *resp = pceObexMsg->GetObexHeader();
580 std::string respTxt;
581 std::string respBodyObject;
582 IPbapPhoneBookData result;
583 uint8_t respCode = resp->GetFieldCode();
584 if (respCode == static_cast<uint8_t>(ObexRspCode::SUCCESS)) {
585 if (ObexHeaderToDataResult(*resp, PBAP_ACTION_PULLVCARDLISTING, result)) {
586 respBodyObject.assign(result.result_.begin(), result.result_.end());
587 respTxt = "PullvCardListing Completed:\n" + respBodyObject;
588 }
589 }
590 if (IsResponeOK(respCode)) {
591 PBAP_PCE_LOG_INFO("%{public}s respCode:0x%x, respTxt:%{public}s",
592 __PRETTY_FUNCTION__, respCode, respTxt.c_str());
593 } else {
594 respTxt = "PullvCardListing Error!";
595 PBAP_PCE_LOG_ERROR("%{public}s respCode:0x%x, respTxt:%{public}s",
596 __PRETTY_FUNCTION__, respCode, respTxt.c_str());
597 }
598 auto &device = GetDevice();
599 observerMgrList_.ForEach([device, respCode, result](IPbapPceObserver &observer) {
600 observer.OnActionCompleted(device, static_cast<int>(respCode), PBAP_ACTION_PULLVCARDLISTING, result);
601 });
602 PBAP_PCE_LOG_INFO("%{public}s end", __PRETTY_FUNCTION__);
603 }
604
HandlePullvCardEntryActionCompleted(const utility::Message & msg)605 void PbapPceStateMachine::HandlePullvCardEntryActionCompleted(const utility::Message &msg)
606 {
607 PBAP_PCE_LOG_INFO("%{public}s start", __PRETTY_FUNCTION__);
608 PbapPceActionObexMessage *pceObexMsg = static_cast<PbapPceActionObexMessage *>(msg.arg2_);
609 if (pceObexMsg == nullptr) {
610 PBAP_PCE_LOG_INFO("%{public}s end, pceObexMsg == nullptr!", __PRETTY_FUNCTION__);
611 return;
612 }
613
614 const ObexHeader *resp = pceObexMsg->GetObexHeader();
615 IPbapPhoneBookData result;
616 uint8_t respCode = resp->GetFieldCode();
617 std::string respTxt;
618 std::string respBodyObject;
619 if (respCode == static_cast<uint8_t>(ObexRspCode::SUCCESS)) {
620 if (ObexHeaderToDataResult(*resp, PBAP_ACTION_PULLVCARDENTRY, result)) {
621 respBodyObject.assign(result.result_.begin(), result.result_.end());
622 }
623 respTxt = "PullvCardEntry Completed:\n" + respBodyObject;
624 }
625 if (IsResponeOK(respCode)) {
626 PBAP_PCE_LOG_INFO("%{public}s respCode:0x%x, respTxt:%{public}s",
627 __PRETTY_FUNCTION__, respCode, respTxt.c_str());
628 } else {
629 respTxt = "PullvCardEntry Error!";
630 PBAP_PCE_LOG_ERROR("%{public}s respCode:0x%x, respTxt:%{public}s",
631 __PRETTY_FUNCTION__, respCode, respTxt.c_str());
632 }
633 auto &device = GetDevice();
634 observerMgrList_.ForEach([device, respCode, result](IPbapPceObserver &observer) {
635 observer.OnActionCompleted(device, static_cast<int>(respCode), PBAP_ACTION_PULLVCARDENTRY, result);
636 });
637
638 PBAP_PCE_LOG_INFO("%{public}s end", __PRETTY_FUNCTION__);
639 }
640
InitIPbapPhoneBookData(IPbapPhoneBookData & retResult)641 void PbapPceStateMachine::InitIPbapPhoneBookData(IPbapPhoneBookData &retResult)
642 {
643 std::u16string vcardPath, vcardFileName;
644 SplitFilePath(GetReqVcardFileName(), vcardPath, vcardFileName);
645 retResult.deviceAddr_ = Replace(GetDevice().GetAddress(), ":", "_");
646 retResult.vcardPath_ = Replace(U16ToStr(vcardPath), "/", "_");
647 retResult.vcardFileName_ = Replace(U16ToStr(vcardFileName), "/", "_");
648 retResult.resultLoaded_ = 0;
649 }
650
HandleAbortDownloadingActionCompleted(const utility::Message & msg)651 void PbapPceStateMachine::HandleAbortDownloadingActionCompleted(const utility::Message &msg)
652 {
653 PBAP_PCE_LOG_INFO("%{public}s start", __PRETTY_FUNCTION__);
654 PbapPceActionObexMessage *pceObexMsg = static_cast<PbapPceActionObexMessage *>(msg.arg2_);
655 if (pceObexMsg == nullptr) {
656 PBAP_PCE_LOG_INFO("%{public}s end, pceObexMsg == nullptr!", __PRETTY_FUNCTION__);
657 return;
658 }
659
660 const ObexHeader *resp = pceObexMsg->GetObexHeader();
661 uint8_t respCode = resp->GetFieldCode();
662 std::string respTxt;
663 IPbapPhoneBookData result;
664 InitIPbapPhoneBookData(result);
665 if (IsResponeOK(respCode)) {
666 respTxt = "AbortDownloading Completed!";
667 PBAP_PCE_LOG_INFO("%{public}s respCode:0x%x, respTxt:%{public}s",
668 __PRETTY_FUNCTION__, respCode, respTxt.c_str());
669 } else {
670 respTxt = "AbortDownloading Error!";
671 PBAP_PCE_LOG_ERROR("%{public}s respCode:0x%x, respTxt:%{public}s",
672 __PRETTY_FUNCTION__, respCode, respTxt.c_str());
673 }
674
675 auto &device = GetDevice();
676 observerMgrList_.ForEach([device, respCode, result](IPbapPceObserver &observer) {
677 observer.OnActionCompleted(device, static_cast<int>(respCode), PBAP_ACTION_ABORT, result);
678 });
679
680 PBAP_PCE_LOG_INFO("%{public}s end", __PRETTY_FUNCTION__);
681 }
682
TryReleasePbapMsg(const utility::Message & msg) const683 void PbapPceStateMachine::TryReleasePbapMsg(const utility::Message &msg) const
684 {
685 if (msg.what_ == PCE_SDP_FINISH) {
686 std::unique_ptr<PbapPceHeaderSdpMsg> sdpMsg(static_cast<PbapPceHeaderSdpMsg *>(msg.arg2_));
687 PBAP_PCE_LOG_ERROR("%{public}s msg.what_=[%{public}d] release memory", __PRETTY_FUNCTION__, msg.what_);
688 }
689 if (msg.what_ == PCE_PASSWORD_INPUT) {
690 std::unique_ptr<PbapPcePasswordInputMsg> pwdInputMsg(static_cast<PbapPcePasswordInputMsg *>(msg.arg2_));
691 PBAP_PCE_LOG_ERROR("%{public}s msg.what_=[%{public}d] release memory", __PRETTY_FUNCTION__, msg.what_);
692 }
693 }
694
GetDevice() const695 const RawAddress &PbapPceStateMachine::GetDevice() const
696 {
697 return this->device_;
698 }
699
GetPceService() const700 PbapPceService &PbapPceStateMachine::GetPceService() const
701 {
702 return *pceService_;
703 }
704
GetObexClient() const705 PbapPceObexClient &PbapPceStateMachine::GetObexClient() const
706 {
707 return *pceObexClient_;
708 }
709
SetVersionNumber(uint16_t versionNumber)710 void PbapPceStateMachine::SetVersionNumber(uint16_t versionNumber)
711 {
712 versionNumber_ = versionNumber;
713 }
714
GetVersionNumber() const715 uint16_t PbapPceStateMachine::GetVersionNumber() const
716 {
717 return versionNumber_;
718 }
719
SetSupportedRes(uint8_t supportedRes)720 void PbapPceStateMachine::SetSupportedRes(uint8_t supportedRes)
721 {
722 supportedRes_ = supportedRes;
723 }
724
GetSupportedRes() const725 uint8_t PbapPceStateMachine::GetSupportedRes() const
726 {
727 return supportedRes_;
728 }
729
SetSupportedFeature(uint32_t supportedFeature)730 void PbapPceStateMachine::SetSupportedFeature(uint32_t supportedFeature)
731 {
732 supportedFeature_ = supportedFeature;
733 }
734
GetSupportedFeature() const735 uint32_t PbapPceStateMachine::GetSupportedFeature() const
736 {
737 return supportedFeature_;
738 }
739
SetPassword(const std::string & password)740 void PbapPceStateMachine::SetPassword(const std::string &password)
741 {
742 this->password_ = password;
743 }
744
GetPassword() const745 const std::string &PbapPceStateMachine::GetPassword() const
746 {
747 return password_;
748 }
749
IsGoepL2capPSM() const750 bool PbapPceStateMachine::IsGoepL2capPSM() const
751 {
752 return isGoepL2capPSM_;
753 }
754
SetGoepL2capPSM(bool goepL2capPSM)755 void PbapPceStateMachine::SetGoepL2capPSM(bool goepL2capPSM)
756 {
757 isGoepL2capPSM_ = goepL2capPSM;
758 }
759
GetGapSecChannel() const760 const GapSecChannel PbapPceStateMachine::GetGapSecChannel() const
761 {
762 return gapSecChannel_;
763 }
764
SetGapSecChannel(const GapSecChannel & gapSecChannel)765 void PbapPceStateMachine::SetGapSecChannel(const GapSecChannel &gapSecChannel)
766 {
767 gapSecChannel_ = gapSecChannel;
768 }
769
GetFeatureFlag() const770 bool PbapPceStateMachine::GetFeatureFlag() const
771 {
772 return featureFlag_;
773 }
774
SetFeatureFlag(bool featureFlag)775 void PbapPceStateMachine::SetFeatureFlag(bool featureFlag)
776 {
777 featureFlag_ = featureFlag;
778 }
779
GetSdp() const780 PbapPceSdp &PbapPceStateMachine::GetSdp() const
781 {
782 return pbapPceSdp_;
783 }
784
GetGap() const785 PbapPceGap *PbapPceStateMachine::GetGap() const
786 {
787 return pbapPceGap_.get();
788 }
789
SetGap(PbapPceGap & gap)790 void PbapPceStateMachine::SetGap(PbapPceGap &gap)
791 {
792 pbapPceGap_.reset(&gap);
793 }
794
SetUserId(const std::string & userId)795 void PbapPceStateMachine::SetUserId(const std::string &userId)
796 {
797 this->userId_ = userId;
798 }
799
GetUserId() const800 const std::string &PbapPceStateMachine::GetUserId() const
801 {
802 return userId_;
803 }
804
GetCurrentPath() const805 const std::u16string &PbapPceStateMachine::GetCurrentPath() const
806 {
807 return currentPath_;
808 }
809
SetCurrentPath(const std::u16string & path)810 void PbapPceStateMachine::SetCurrentPath(const std::u16string &path)
811 {
812 currentPath_ = path;
813 }
814
GetDownloadFileName() const815 std::string PbapPceStateMachine::GetDownloadFileName() const
816 {
817 std::u16string vcardPath, vcardFileName;
818 SplitFilePath(GetReqVcardFileName(), vcardPath, vcardFileName);
819 std::string device = Replace(GetDevice().GetAddress(), ":", "_");
820 std::string strPath = Replace(U16ToStr(vcardPath), "/", "_");
821 std::string strVcardFileName = Replace(U16ToStr(vcardFileName), "/", "_");
822 std::string strRet = device + strPath + strVcardFileName;
823 return strRet;
824 }
825
GetReqVcardFileName() const826 const std::u16string &PbapPceStateMachine::GetReqVcardFileName() const
827 {
828 return reqVcardFileName_;
829 }
830
SetReqVcardFileName(const std::u16string & reqVcardFileName)831 void PbapPceStateMachine::SetReqVcardFileName(const std::u16string &reqVcardFileName)
832 {
833 reqVcardFileName_ = reqVcardFileName;
834 }
835
~PbapPceStateMachine()836 PbapPceStateMachine::~PbapPceStateMachine()
837 {
838 PBAP_PCE_LOG_INFO("%{public}s start", __PRETTY_FUNCTION__);
839 PBAP_PCE_LOG_INFO("%{public}s end", __PRETTY_FUNCTION__);
840 }
841
CreatePceObexClient(const ObexClientConfig & obexConfig)842 void PbapPceStateMachine::CreatePceObexClient(const ObexClientConfig &obexConfig)
843 {
844 PBAP_PCE_LOG_INFO("%{public}s start", __PRETTY_FUNCTION__);
845 if (pceService_ == nullptr) {
846 PBAP_PCE_LOG_ERROR("pceService_ == nullptr");
847 return;
848 }
849 this->pceObexClient_ = std::make_unique<PbapPceObexClient>(obexConfig, *pceService_);
850 PBAP_PCE_LOG_INFO("%{public}s end", __PRETTY_FUNCTION__);
851 }
852 } // namespace bluetooth
853 } // namespace OHOS
854