• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 #include "opp_service.h"
17 
18 #include "../obex/obex_types.h"
19 #include "adapter_config.h"
20 #include "class_creator.h"
21 #include "log.h"
22 #include "profile_service_manager.h"
23 #include "rfcomm.h"
24 
25 namespace OHOS {
26 namespace bluetooth {
OppService()27 OppService::OppService() : utility::Context(PROFILE_NAME_OPP, "1.2.1")
28 {
29     HILOGI("[OPP Service]%{public}s:%{public}s Create", PROFILE_NAME_OPP.c_str(), Name().c_str());
30 }
31 
~OppService()32 OppService::~OppService()
33 {
34     HILOGI("[OPP Service]%{public}s:%{public}s Destroy", PROFILE_NAME_OPP.c_str(), Name().c_str());
35 }
36 
GetContext()37 utility::Context *OppService::GetContext()
38 {
39     return this;
40 }
41 
GetService()42 OppService *OppService::GetService()
43 {
44     auto servManager = IProfileManager::GetInstance();
45     return static_cast<OppService *>(servManager->GetProfileService(PROFILE_NAME_OPP));
46 }
47 
RegisterObserver(IOppObserver & oppObserver)48 void OppService::RegisterObserver(IOppObserver &oppObserver)
49 {
50     HILOGI("[OPP Service] Enter");
51 
52     oppObservers_.Register(oppObserver);
53 }
54 
DeregisterObserver(IOppObserver & oppObserver)55 void OppService::DeregisterObserver(IOppObserver &oppObserver)
56 {
57     HILOGI("[OPP Service] Enter");
58 
59     oppObservers_.Deregister(oppObserver);
60 }
61 
NotifyStateChanged(const RawAddress & device,int state)62 void OppService::NotifyStateChanged(const RawAddress &device, int state)
63 {
64     HILOGI("[OPP Service] Enter newState=%{public}d",
65         stateMap_.at(state));
66 }
67 
NotifyReceiveIncomingFile(IOppTransferInformation info)68 void OppService::NotifyReceiveIncomingFile(IOppTransferInformation info)
69 {
70     HILOGI("[OPP Service] Enter");
71 
72     oppObservers_.ForEach([info](IOppObserver &observer) {
73         observer.OnReceiveIncomingFile(info);
74     });
75 }
76 
NotifyTransferStateChanged(IOppTransferInformation info)77 void OppService::NotifyTransferStateChanged(IOppTransferInformation info)
78 {
79     HILOGI("[OPP Service] Enter");
80 
81     oppObservers_.ForEach([info](IOppObserver &observer) {
82         observer.OnTransferStateChange(info);
83     });
84 }
85 
Enable(void)86 void OppService::Enable(void)
87 {
88     HILOGI("[OPP Service] Enter");
89 
90     OppMessage event(OPP_SERVICE_STARTUP_EVT);
91     PostEvent(event);
92 }
93 
Disable(void)94 void OppService::Disable(void)
95 {
96     HILOGI("[OPP Service] Enter");
97 
98     OppMessage event(OPP_SERVICE_SHUTDOWN_EVT);
99     PostEvent(event);
100 }
101 
StartUp()102 void OppService::StartUp()
103 {
104     HILOGI("[OPP Service]:==========<start>==========");
105     if (isStarted_) {
106         GetContext()->OnEnable(PROFILE_NAME_OPP, true);
107         HILOGW("[OPP Service]:OppService has already been started before.");
108         return;
109     }
110     LoadOppConfig();
111     uint8_t rfcommScn = RFCOMM_AssignServerNum();
112 
113     oppSdpServer_ = std::make_unique<OppSdpServer>();
114     oppGapServer_ = std::make_unique<OppGapServer>(rfcommScn, OPP_GOEP_L2CAP_PSM);
115     ObexServerConfig config;
116     config.useL2cap_ = true;
117     config.l2capPsm_ = OPP_GOEP_L2CAP_PSM;
118     config.l2capMtu_ = oppConfig_.l2capMtu;
119     config.useRfcomm_ = true;
120     config.rfcommScn_ = rfcommScn;
121     config.rfcommMtu_ = oppConfig_.rfcommMtu;
122     config.isSupportSrm_ = true;
123     config.isSupportReliableSession_ = false;
124     oppObexServer_ = std::make_unique<OppObexServer>(config, *GetDispatcher());
125     if ((oppSdpServer_->Register(rfcommScn, OPP_GOEP_L2CAP_PSM) == BT_NO_ERROR) &&
126         (oppGapServer_->Register() == BT_NO_ERROR) &&
127         (oppObexServer_->StartUp() == BT_NO_ERROR)) {
128         GetContext()->OnEnable(PROFILE_NAME_OPP, true);
129         isStarted_ = true;
130         HILOGI("[OPP Service]:PanService started");
131     } else {
132         oppSdpServer_ = nullptr;
133         oppObexServer_ = nullptr;
134         GetContext()->OnEnable(PROFILE_NAME_OPP, false);
135         HILOGE("[OPP Service]:Sdp register or obex start failed!");
136     }
137 }
138 
ShutDown()139 void OppService::ShutDown()
140 {
141     HILOGI("[OPP Service]:==========<start>==========");
142     if (!isStarted_) {
143         GetContext()->OnDisable(PROFILE_NAME_OPP, true);
144         HILOGW("[OPP Service]:OppService has already been shutdown before.");
145         return;
146     }
147 
148     while (!oppTransferList_.empty()) {
149         oppTransferList_.front()->OnTransferStateChange(OPP_TRANSFER_STATUS_FAILD, OPP_TRANSFER_FAILED_PROTOCOL);
150         oppTransferList_.pop_front();
151     }
152 
153     isShuttingDown_ = true;
154     bool isDisconnected = false;
155     for (auto it = stateMachines_.begin(); it != stateMachines_.end(); ++it) {
156         if ((it->second != nullptr) && (it->second->GetDeviceStateInt() > OPP_STATE_DISCONNECTED)) {
157             Disconnect(RawAddress(it->first));
158             isDisconnected = true;
159         }
160     }
161 
162     if (!isDisconnected) {
163         ShutDownDone(true);
164     }
165 }
166 
ShutDownDone(bool isAllDisconnected)167 void OppService::ShutDownDone(bool isAllDisconnected)
168 {
169     HILOGI("[OPP Service]:==========<start>==========");
170     if (!isAllDisconnected) {
171         for (auto it = stateMachines_.begin(); it != stateMachines_.end(); ++it) {
172             if ((it->second != nullptr) && (it->second->GetDeviceStateInt() > OPP_STATE_DISCONNECTED)) {
173                 return;
174             }
175         }
176     }
177 
178     stateMachines_.clear();
179     if (oppSdpServer_) {
180         oppSdpServer_->Deregister();
181     }
182     oppSdpServer_ = nullptr;
183     if (oppGapServer_) {
184         oppGapServer_->Deregister();
185     }
186     oppGapServer_ = nullptr;
187     oppObexServer_->ShutDown();
188     oppObexServer_ = nullptr;
189 
190     GetContext()->OnDisable(PROFILE_NAME_OPP, true);
191     isStarted_ = false;
192     HILOGI("[OPP Service]:OppService shutdown");
193     isShuttingDown_ = false;
194 }
195 
SendFile(const RawAddress & device,const std::vector<std::string> filePaths,const std::vector<std::string> mimeTypes)196 int OppService::SendFile(const RawAddress &device, const std::vector<std::string> filePaths,
197     const std::vector<std::string> mimeTypes)
198 {
199     std::lock_guard<std::recursive_mutex> lk(mutex_);
200     HILOGI("[OPP Service] Enter");
201     std::string address = device.GetAddress();
202 
203     std::shared_ptr<OppTransfer> oppTransfer = std::make_shared<OppTransfer>(
204         address, filePaths, mimeTypes, OPP_TRANSFER_DIRECTION_OUTBOND);
205     if (oppTransfer->GetFileNumber() <= 0) {
206         HILOGE("[OPP Service]:Send file size is 0");
207         return RET_BAD_STATUS;
208     }
209     oppTransferList_.push_back(oppTransfer);
210 
211     if (oppTransferList_.size() == 1) {
212         OppMessage event(OPP_CONNECT_REQ_EVT);
213         event.dev_ = address;
214         PostEvent(event);
215     }
216     return RET_NO_ERROR;
217 }
218 
SetIncomingFileConfirmation(const bool accept)219 int OppService::SetIncomingFileConfirmation(const bool accept)
220 {
221     std::lock_guard<std::recursive_mutex> lk(mutex_);
222     HILOGI("[OPP Service] Enter");
223 
224     if (!oppTransferList_.empty()) {
225         return oppTransferList_.front()->SetIncomingFileConfirmation(accept);
226     }
227     return RET_BAD_STATUS;
228 }
229 
GetCurrentTransferInformation()230 IOppTransferInformation OppService::GetCurrentTransferInformation()
231 {
232     std::lock_guard<std::recursive_mutex> lk(mutex_);
233     HILOGI("[OPP Service] Enter");
234 
235     if (!oppTransferList_.empty()) {
236         return oppTransferList_.front()->GetCurrentTransferInformation();
237     }
238     IOppTransferInformation ret;
239     HILOGE("[OPP Service]:Current transfer is null");
240     return ret;
241 }
242 
CancelTransfer()243 int OppService::CancelTransfer()
244 {
245     std::lock_guard<std::recursive_mutex> lk(mutex_);
246     HILOGI("[OPP Service] Enter");
247 
248     if (!oppTransferList_.empty()) {
249         return oppTransferList_.front()->CancelTransfer();
250     }
251     return RET_BAD_STATUS;
252 }
253 
CancelTransfer(const std::string & device)254 int OppService::CancelTransfer(const std::string &device)
255 {
256     std::lock_guard<std::recursive_mutex> lk(mutex_);
257     HILOGI("[OPP Service] Enter");
258 
259     if (!oppTransferList_.empty()) {
260         if (oppTransferList_.front()->GetDeviceAddress() == device) {
261             return oppTransferList_.front()->CancelTransfer();
262         } else {
263             HILOGE("[OPP Service]:not current device");
264         }
265     }
266     return RET_BAD_STATUS;
267 }
268 
ConnectObex(const std::string & device,const ObexClientConfig & config)269 void OppService::ConnectObex(const std::string &device, const ObexClientConfig &config)
270 {
271     if (!oppTransferList_.empty()) {
272         if (oppTransferList_.front()->GetDeviceAddress() == device) {
273             oppTransferList_.front()->ConnectObex(config, *GetDispatcher());
274         } else {
275             HILOGE("[OPP Service]:not current device");
276         }
277     } else {
278         HILOGE("[OPP Service]:not find transfer");
279     }
280 }
281 
DisconnectObex(const std::string & device)282 void OppService::DisconnectObex(const std::string &device)
283 {
284     if (!oppTransferList_.empty()) {
285         if (oppTransferList_.front()->GetDeviceAddress() == device) {
286             oppTransferList_.front()->DisconnectObex();
287         } else {
288             HILOGE("[OPP Service]:not current device");
289         }
290     } else {
291         HILOGE("[OPP Service]:not find transfer");
292     }
293 }
294 
OnReceiveIncomingConnect(ObexServerSession & session,uint32_t connectId)295 void OppService::OnReceiveIncomingConnect(ObexServerSession &session, uint32_t connectId)
296 {
297     HILOGI("[OPP Service] is inbond,creat a transfer");
298     for (std::list<std::shared_ptr<OppTransfer>>::iterator iter = oppTransferList_.begin();
299         iter != oppTransferList_.end(); iter++) {
300         if ((*iter)->GetDirection() == OPP_TRANSFER_DIRECTION_INBOND) {
301             HILOGE("[OPP Service]:Had a inbond connect,reject incoming connect");
302             auto header = ObexHeader::CreateResponse(ObexRspCode::SERVICE_UNAVAILABLE, true);
303             session.SendResponse(*header);
304             session.Disconnect();
305             return;
306         }
307     }
308     std::vector<std::string> filePaths;
309     std::vector<std::string> mimeTypes;
310     std::shared_ptr<OppTransfer> oppTransfer = std::make_shared<OppTransfer>(
311         session.GetRemoteAddr().GetAddress(), filePaths, mimeTypes, OPP_TRANSFER_DIRECTION_INBOND);
312     oppTransfer->OnReceiveIncomingConnect(session, connectId);
313     oppTransferList_.push_back(oppTransfer);
314 
315     if (oppTransferList_.size() == 1) {
316         oppTransferList_.front()->AcceptConnect();
317     }
318 }
319 
OnReceiveIncomingFile(IOppTransferInformation info)320 void OppService::OnReceiveIncomingFile(IOppTransferInformation info)
321 {
322     if (!oppTransferList_.empty() && (oppTransferList_.front()->GetDeviceAddress() == info.GetDeviceAddress())) {
323         oppTransferList_.front()->OnReceiveIncomingFile(info);
324     } else {
325         HILOGE("[OPP Service]:not current device");
326     }
327 }
328 
OnObexConnected(const std::string & device)329 void OppService::OnObexConnected(const std::string &device)
330 {
331     int ret = RET_NO_ERROR;
332     if (!oppTransferList_.empty() && (oppTransferList_.front()->GetDeviceAddress() == device)) {
333         ret = oppTransferList_.front()->StartTransfer();
334         if (ret != RET_NO_ERROR) {
335             oppTransferList_.front()->OnTransferStateChange(
336                 OPP_TRANSFER_STATUS_FAILD, OPP_TRANSFER_FAILED_PROTOCOL);
337         }
338     } else {
339         HILOGE("[OPP Service]:not current device");
340     }
341 }
342 
OnObexDisconnected(const std::string & device)343 void OppService::OnObexDisconnected(const std::string &device)
344 {
345     if (oppTransferList_.empty()) {
346         HILOGE("[OPP Service]:Transfer list_ is empty");
347         return;
348     }
349     std::list<std::shared_ptr<OppTransfer>>::iterator iter = oppTransferList_.begin();
350     for (; iter != oppTransferList_.end(); iter++) {
351         if ((*iter)->GetDeviceAddress() == device) {
352             break;
353         }
354     }
355     if (iter == oppTransferList_.end()) {
356         HILOGE("[OPP Service]:Not find transfer");
357         return;
358     }
359     if (iter == oppTransferList_.begin()) {
360         GetDispatcher()->PostTask(std::bind(&OppService::StartNextTransfer, this));
361     }
362     (*iter)->OnObexDisconnected();
363     oppTransferList_.erase(iter);
364 }
365 
OnTransferStateChange(const std::string & device,int state,int reason)366 void OppService::OnTransferStateChange(const std::string &device, int state, int reason)
367 {
368     if (oppTransferList_.empty()) {
369         HILOGE("[OPP Service]:Transfer list_ is empty");
370         return;
371     }
372     std::list<std::shared_ptr<OppTransfer>>::iterator iter = oppTransferList_.begin();
373     for (; iter != oppTransferList_.end(); iter++) {
374         if ((*iter)->GetDeviceAddress() == device) {
375             break;
376         }
377     }
378     if (iter == oppTransferList_.end()) {
379         HILOGE("[OPP Service]:Not find transfer");
380         return;
381     }
382     (*iter)->OnTransferStateChange(state, reason);
383 }
384 
OnTransferPositionChange(const std::string & device,size_t position)385 void OppService::OnTransferPositionChange(const std::string &device, size_t position)
386 {
387     if (oppTransferList_.empty()) {
388         HILOGE("[OPP Service]:Transfer list_ is empty");
389         return;
390     }
391     std::list<std::shared_ptr<OppTransfer>>::iterator iter = oppTransferList_.begin();
392     for (; iter != oppTransferList_.end(); iter++) {
393         if ((*iter)->GetDeviceAddress() == device) {
394             break;
395         }
396     }
397     if (iter == oppTransferList_.end()) {
398         HILOGE("[OPP Service]:Not find transfer");
399         return;
400     }
401     (*iter)->OnTransferPositionChange(position);
402 }
403 
StartNextTransfer()404 void OppService::StartNextTransfer()
405 {
406     if (oppTransferList_.size() > 0) {
407         if (oppTransferList_.front()->GetDirection() == OPP_TRANSFER_DIRECTION_OUTBOND) {
408             OppMessage event(OPP_CONNECT_REQ_EVT);
409             event.dev_ = oppTransferList_.front()->GetDeviceAddress();
410             PostEvent(event);
411         } else {
412             oppTransferList_.front()->AcceptConnect();
413         }
414     } else {
415         HILOGI("[OPP Service] No more file to transfer");
416     }
417 }
418 
RemoveStateMachine(const std::string & device)419 void OppService::RemoveStateMachine(const std::string &device)
420 {
421     OppMessage event(OPP_REMOVE_STATE_MACHINE_EVT);
422     event.dev_ = device;
423     PostEvent(event);
424 }
425 
PostEvent(const OppMessage & event)426 void OppService::PostEvent(const OppMessage &event)
427 {
428     GetDispatcher()->PostTask(std::bind(&OppService::ProcessEvent, this, event));
429 }
430 
ProcessEvent(const OppMessage & event)431 void OppService::ProcessEvent(const OppMessage &event)
432 {
433     std::lock_guard<std::recursive_mutex> lk(mutex_);
434     std::string address = event.dev_;
435     HILOGI("[OPP Service]:address[%{public}s] event_no[%{public}d]",
436         address.c_str(), event.what_);
437     switch (event.what_) {
438         case OPP_SERVICE_STARTUP_EVT:
439             StartUp();
440             break;
441         case OPP_SERVICE_SHUTDOWN_EVT:
442             ShutDown();
443             break;
444         case OPP_CONNECT_REQ_EVT:
445         case OPP_CONNECTED_EVT:
446             ProcessConnectEvent(event);
447             break;
448         case OPP_REMOVE_STATE_MACHINE_EVT:
449             ProcessRemoveStateMachine(event.dev_);
450             break;
451         default:
452             ProcessDefaultEvent(event);
453             break;
454     }
455 }
456 
ProcessConnectEvent(const OppMessage & event)457 void OppService::ProcessConnectEvent(const OppMessage &event)
458 {
459     auto it = stateMachines_.find(event.dev_);
460     if (it != stateMachines_.end() && it->second != nullptr && it->second->IsRemoving()) {
461         // peer device may send connect request before we remove statemachine for last connection.
462         // so post this connect request, process it after we remove statemachine completely.
463         PostEvent(event);
464     } else if (it == stateMachines_.end() || it->second == nullptr) {
465         stateMachines_[event.dev_] = std::make_unique<OppStateMachine>(event.dev_);
466         stateMachines_[event.dev_]->Init();
467         stateMachines_[event.dev_]->ProcessMessage(event);
468     } else {
469         it->second->ProcessMessage(event);
470     }
471 }
472 
ProcessRemoveStateMachine(const std::string & address)473 void OppService::ProcessRemoveStateMachine(const std::string &address)
474 {
475     stateMachines_.erase(address);
476     if (isShuttingDown_) {
477         ShutDownDone(false);
478     }
479 }
480 
ProcessDefaultEvent(const OppMessage & event) const481 void OppService::ProcessDefaultEvent(const OppMessage &event) const
482 {
483     auto it = stateMachines_.find(event.dev_);
484     if ((it != stateMachines_.end()) && (it->second != nullptr)) {
485         it->second->ProcessMessage(event);
486     } else {
487         HILOGE("[OPP Service]:invalid address[%{public}s]", event.dev_.c_str());
488     }
489 }
490 
LoadOppConfig()491 void OppService::LoadOppConfig()
492 {
493     IAdapterConfig *adpterConfig = AdapterConfig::GetInstance();
494     if (!adpterConfig->GetValue(SECTION_OPP_SERVICE, PROPERTY_RFCOMM_MTU, oppConfig_.rfcommMtu)) {
495         LOG_ERROR("[OPP Service]%{public}s():Load config %{public}s failure",
496             __FUNCTION__, PROPERTY_RFCOMM_MTU.c_str());
497         oppConfig_.rfcommMtu = OBEX_DEFAULT_MTU;
498     }
499     if (!adpterConfig->GetValue(SECTION_OPP_SERVICE, PROPERTY_L2CAP_MTU, oppConfig_.l2capMtu)) {
500         LOG_ERROR("[OPP Service]%{public}s():Load config %{public}s failure",
501             __FUNCTION__, PROPERTY_L2CAP_MTU.c_str());
502         oppConfig_.l2capMtu = OBEX_DEFAULT_MTU;
503     }
504     LOG_INFO("[OPP Service]%{public}s():rfcommMtu = 0x%X, l2capMtu = 0x%X",
505         __FUNCTION__, oppConfig_.rfcommMtu, oppConfig_.l2capMtu);
506 }
507 
GetOppConfig()508 OppConfig &OppService::GetOppConfig()
509 {
510     return oppConfig_;
511 }
512 
Connect(const RawAddress & device)513 int OppService::Connect(const RawAddress &device)
514 {
515     HILOGI("[OPP Service] Enter");
516     // DO NOTHING
517     return RET_NO_ERROR;
518 }
519 
Disconnect(const RawAddress & device)520 int OppService::Disconnect(const RawAddress &device)
521 {
522     HILOGI("[OPP Service] Enter");
523     // DO NOTHING
524     return RET_NO_ERROR;
525 }
526 
GetConnectDevices(void)527 std::list<RawAddress> OppService::GetConnectDevices(void)
528 {
529     HILOGI("[OPP Service] Enter");
530     std::list<RawAddress> devList;
531     return devList;
532 }
533 
GetDevicesByStates(std::vector<int> states)534 std::vector<RawAddress> OppService::GetDevicesByStates(std::vector<int> states)
535 {
536     HILOGI("[OPP Service] Enter");
537     std::vector<RawAddress> devList;
538     return devList;
539 }
540 
GetDeviceState(const RawAddress & device)541 int OppService::GetDeviceState(const RawAddress &device)
542 {
543     HILOGI("[OPP Service] Enter");
544     return PROFILE_STATE_DISCONNECTED;
545 }
546 
GetConnectState(void)547 int OppService::GetConnectState(void)
548 {
549     HILOGI("[OPP Service] Enter");
550     return PROFILE_STATE_DISCONNECTED;
551 }
552 
GetMaxConnectNum(void)553 int OppService::GetMaxConnectNum(void)
554 {
555     HILOGI("[OPP Service] Enter");
556     return 0;
557 }
558 
559 REGISTER_CLASS_CREATOR(OppService);
560 }  // namespace bluetooth
561 }  // namespace OHOS