• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &param)
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 &param)
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 &param)
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