• 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 "log_util.h"
23 #include "profile_service_manager.h"
24 #include "rfcomm.h"
25 
26 namespace OHOS {
27 namespace bluetooth {
OppService()28 OppService::OppService() : utility::Context(PROFILE_NAME_OPP, "1.2.1")
29 {
30     HILOGI("[OPP Service]%{public}s:%{public}s Create", PROFILE_NAME_OPP.c_str(), Name().c_str());
31 }
32 
~OppService()33 OppService::~OppService()
34 {
35     HILOGI("[OPP Service]%{public}s:%{public}s Destroy", PROFILE_NAME_OPP.c_str(), Name().c_str());
36 }
37 
GetContext()38 utility::Context *OppService::GetContext()
39 {
40     return this;
41 }
42 
GetService()43 OppService *OppService::GetService()
44 {
45     auto servManager = IProfileManager::GetInstance();
46     return static_cast<OppService *>(servManager->GetProfileService(PROFILE_NAME_OPP));
47 }
48 
RegisterObserver(IOppObserver & oppObserver)49 void OppService::RegisterObserver(IOppObserver &oppObserver)
50 {
51     HILOGI("[OPP Service] Enter");
52 
53     oppObservers_.Register(oppObserver);
54 }
55 
DeregisterObserver(IOppObserver & oppObserver)56 void OppService::DeregisterObserver(IOppObserver &oppObserver)
57 {
58     HILOGI("[OPP Service] Enter");
59 
60     oppObservers_.Deregister(oppObserver);
61 }
62 
NotifyStateChanged(const RawAddress & device,int state)63 void OppService::NotifyStateChanged(const RawAddress &device, int state)
64 {
65     HILOGI("[OPP Service] Enter newState=%{public}d",
66         stateMap_.at(state));
67 }
68 
NotifyReceiveIncomingFile(IOppTransferInformation info)69 void OppService::NotifyReceiveIncomingFile(IOppTransferInformation info)
70 {
71     HILOGI("[OPP Service] Enter");
72 
73     oppObservers_.ForEach([info](IOppObserver &observer) {
74         observer.OnReceiveIncomingFile(info);
75     });
76 }
77 
NotifyTransferStateChanged(IOppTransferInformation info)78 void OppService::NotifyTransferStateChanged(IOppTransferInformation info)
79 {
80     HILOGI("[OPP Service] Enter");
81 
82     oppObservers_.ForEach([info](IOppObserver &observer) {
83         observer.OnTransferStateChange(info);
84     });
85 }
86 
Enable(void)87 void OppService::Enable(void)
88 {
89     HILOGI("[OPP Service] Enter");
90 
91     OppMessage event(OPP_SERVICE_STARTUP_EVT);
92     PostEvent(event);
93 }
94 
Disable(void)95 void OppService::Disable(void)
96 {
97     HILOGI("[OPP Service] Enter");
98 
99     OppMessage event(OPP_SERVICE_SHUTDOWN_EVT);
100     PostEvent(event);
101 }
102 
StartUp()103 void OppService::StartUp()
104 {
105     HILOGI("[OPP Service]:==========<start>==========");
106     if (isStarted_) {
107         GetContext()->OnEnable(PROFILE_NAME_OPP, true);
108         HILOGW("[OPP Service]:OppService has already been started before.");
109         return;
110     }
111     LoadOppConfig();
112     uint8_t rfcommScn = RFCOMM_AssignServerNum();
113 
114     oppSdpServer_ = std::make_unique<OppSdpServer>();
115     oppGapServer_ = std::make_unique<OppGapServer>(rfcommScn, OPP_GOEP_L2CAP_PSM);
116     ObexServerConfig config;
117     config.useL2cap_ = true;
118     config.l2capPsm_ = OPP_GOEP_L2CAP_PSM;
119     config.l2capMtu_ = oppConfig_.l2capMtu;
120     config.useRfcomm_ = true;
121     config.rfcommScn_ = rfcommScn;
122     config.rfcommMtu_ = oppConfig_.rfcommMtu;
123     config.isSupportSrm_ = true;
124     config.isSupportReliableSession_ = false;
125     oppObexServer_ = std::make_unique<OppObexServer>(config, *GetDispatcher());
126     if ((oppSdpServer_->Register(rfcommScn, OPP_GOEP_L2CAP_PSM) == BT_SUCCESS) &&
127         (oppGapServer_->Register() == BT_SUCCESS) &&
128         (oppObexServer_->StartUp() == BT_SUCCESS)) {
129         GetContext()->OnEnable(PROFILE_NAME_OPP, true);
130         isStarted_ = true;
131         HILOGI("[OPP Service]:PanService started");
132     } else {
133         oppSdpServer_ = nullptr;
134         oppObexServer_ = nullptr;
135         GetContext()->OnEnable(PROFILE_NAME_OPP, false);
136         HILOGE("[OPP Service]:Sdp register or obex start failed!");
137     }
138 }
139 
ShutDown()140 void OppService::ShutDown()
141 {
142     HILOGI("[OPP Service]:==========<start>==========");
143     if (!isStarted_) {
144         GetContext()->OnDisable(PROFILE_NAME_OPP, true);
145         HILOGW("[OPP Service]:OppService has already been shutdown before.");
146         return;
147     }
148 
149     while (!oppTransferList_.empty()) {
150         oppTransferList_.front()->OnTransferStateChange(OPP_TRANSFER_STATUS_FAILD, OPP_TRANSFER_FAILED_PROTOCOL);
151         oppTransferList_.pop_front();
152     }
153 
154     isShuttingDown_ = true;
155     bool isDisconnected = false;
156     for (auto it = stateMachines_.begin(); it != stateMachines_.end(); ++it) {
157         if ((it->second != nullptr) && (it->second->GetDeviceStateInt() > OPP_STATE_DISCONNECTED)) {
158             Disconnect(RawAddress(it->first));
159             isDisconnected = true;
160         }
161     }
162 
163     if (!isDisconnected) {
164         ShutDownDone(true);
165     }
166 }
167 
ShutDownDone(bool isAllDisconnected)168 void OppService::ShutDownDone(bool isAllDisconnected)
169 {
170     HILOGI("[OPP Service]:==========<start>==========");
171     if (!isAllDisconnected) {
172         for (auto it = stateMachines_.begin(); it != stateMachines_.end(); ++it) {
173             if ((it->second != nullptr) && (it->second->GetDeviceStateInt() > OPP_STATE_DISCONNECTED)) {
174                 return;
175             }
176         }
177     }
178 
179     stateMachines_.clear();
180     if (oppSdpServer_) {
181         oppSdpServer_->Deregister();
182     }
183     oppSdpServer_ = nullptr;
184     if (oppGapServer_) {
185         oppGapServer_->Deregister();
186     }
187     oppGapServer_ = nullptr;
188     oppObexServer_->ShutDown();
189     oppObexServer_ = nullptr;
190 
191     GetContext()->OnDisable(PROFILE_NAME_OPP, true);
192     isStarted_ = false;
193     HILOGI("[OPP Service]:OppService shutdown");
194     isShuttingDown_ = false;
195 }
196 
SendFile(const RawAddress & device,const std::vector<std::string> filePaths,const std::vector<std::string> mimeTypes)197 int OppService::SendFile(const RawAddress &device, const std::vector<std::string> filePaths,
198     const std::vector<std::string> mimeTypes)
199 {
200     std::lock_guard<std::recursive_mutex> lk(mutex_);
201     HILOGI("[OPP Service] Enter");
202     std::string address = device.GetAddress();
203 
204     std::shared_ptr<OppTransfer> oppTransfer = std::make_shared<OppTransfer>(
205         address, filePaths, mimeTypes, OPP_TRANSFER_DIRECTION_OUTBOND);
206     if (oppTransfer->GetFileNumber() <= 0) {
207         HILOGE("[OPP Service]:Send file size is 0");
208         return RET_BAD_STATUS;
209     }
210     oppTransferList_.push_back(oppTransfer);
211 
212     if (oppTransferList_.size() == 1) {
213         OppMessage event(OPP_CONNECT_REQ_EVT);
214         event.dev_ = address;
215         PostEvent(event);
216     }
217     return BT_SUCCESS;
218 }
219 
SetIncomingFileConfirmation(const bool accept)220 int OppService::SetIncomingFileConfirmation(const bool accept)
221 {
222     std::lock_guard<std::recursive_mutex> lk(mutex_);
223     HILOGI("[OPP Service] Enter");
224 
225     if (!oppTransferList_.empty()) {
226         return oppTransferList_.front()->SetIncomingFileConfirmation(accept);
227     }
228     return RET_BAD_STATUS;
229 }
230 
GetCurrentTransferInformation()231 IOppTransferInformation OppService::GetCurrentTransferInformation()
232 {
233     std::lock_guard<std::recursive_mutex> lk(mutex_);
234     HILOGI("[OPP Service] Enter");
235 
236     if (!oppTransferList_.empty()) {
237         return oppTransferList_.front()->GetCurrentTransferInformation();
238     }
239     IOppTransferInformation ret;
240     HILOGE("[OPP Service]:Current transfer is null");
241     return ret;
242 }
243 
CancelTransfer()244 int OppService::CancelTransfer()
245 {
246     std::lock_guard<std::recursive_mutex> lk(mutex_);
247     HILOGI("[OPP Service] Enter");
248 
249     if (!oppTransferList_.empty()) {
250         return oppTransferList_.front()->CancelTransfer();
251     }
252     return RET_BAD_STATUS;
253 }
254 
CancelTransfer(const std::string & device)255 int OppService::CancelTransfer(const std::string &device)
256 {
257     std::lock_guard<std::recursive_mutex> lk(mutex_);
258     HILOGI("[OPP Service] Enter");
259 
260     if (!oppTransferList_.empty()) {
261         if (oppTransferList_.front()->GetDeviceAddress() == device) {
262             return oppTransferList_.front()->CancelTransfer();
263         } else {
264             HILOGE("[OPP Service]:not current device");
265         }
266     }
267     return RET_BAD_STATUS;
268 }
269 
ConnectObex(const std::string & device,const ObexClientConfig & config)270 void OppService::ConnectObex(const std::string &device, const ObexClientConfig &config)
271 {
272     if (!oppTransferList_.empty()) {
273         if (oppTransferList_.front()->GetDeviceAddress() == device) {
274             oppTransferList_.front()->ConnectObex(config, *GetDispatcher());
275         } else {
276             HILOGE("[OPP Service]:not current device");
277         }
278     } else {
279         HILOGE("[OPP Service]:not find transfer");
280     }
281 }
282 
DisconnectObex(const std::string & device)283 void OppService::DisconnectObex(const std::string &device)
284 {
285     if (!oppTransferList_.empty()) {
286         if (oppTransferList_.front()->GetDeviceAddress() == device) {
287             oppTransferList_.front()->DisconnectObex();
288         } else {
289             HILOGE("[OPP Service]:not current device");
290         }
291     } else {
292         HILOGE("[OPP Service]:not find transfer");
293     }
294 }
295 
OnReceiveIncomingConnect(ObexServerSession & session,uint32_t connectId)296 void OppService::OnReceiveIncomingConnect(ObexServerSession &session, uint32_t connectId)
297 {
298     HILOGI("[OPP Service] is inbond,creat a transfer");
299     for (std::list<std::shared_ptr<OppTransfer>>::iterator iter = oppTransferList_.begin();
300         iter != oppTransferList_.end(); iter++) {
301         if ((*iter)->GetDirection() == OPP_TRANSFER_DIRECTION_INBOND) {
302             HILOGE("[OPP Service]:Had a inbond connect,reject incoming connect");
303             auto header = ObexHeader::CreateResponse(ObexRspCode::SERVICE_UNAVAILABLE, true);
304             session.SendResponse(*header);
305             session.Disconnect();
306             return;
307         }
308     }
309     std::vector<std::string> filePaths;
310     std::vector<std::string> mimeTypes;
311     std::shared_ptr<OppTransfer> oppTransfer = std::make_shared<OppTransfer>(
312         session.GetRemoteAddr().GetAddress(), filePaths, mimeTypes, OPP_TRANSFER_DIRECTION_INBOND);
313     oppTransfer->OnReceiveIncomingConnect(session, connectId);
314     oppTransferList_.push_back(oppTransfer);
315 
316     if (oppTransferList_.size() == 1) {
317         oppTransferList_.front()->AcceptConnect();
318     }
319 }
320 
OnReceiveIncomingFile(IOppTransferInformation info)321 void OppService::OnReceiveIncomingFile(IOppTransferInformation info)
322 {
323     if (!oppTransferList_.empty() && (oppTransferList_.front()->GetDeviceAddress() == info.GetDeviceAddress())) {
324         oppTransferList_.front()->OnReceiveIncomingFile(info);
325     } else {
326         HILOGE("[OPP Service]:not current device");
327     }
328 }
329 
OnObexConnected(const std::string & device)330 void OppService::OnObexConnected(const std::string &device)
331 {
332     int ret = BT_SUCCESS;
333     if (!oppTransferList_.empty() && (oppTransferList_.front()->GetDeviceAddress() == device)) {
334         ret = oppTransferList_.front()->StartTransfer();
335         if (ret != BT_SUCCESS) {
336             oppTransferList_.front()->OnTransferStateChange(
337                 OPP_TRANSFER_STATUS_FAILD, OPP_TRANSFER_FAILED_PROTOCOL);
338         }
339     } else {
340         HILOGE("[OPP Service]:not current device");
341     }
342 }
343 
OnObexDisconnected(const std::string & device)344 void OppService::OnObexDisconnected(const std::string &device)
345 {
346     if (oppTransferList_.empty()) {
347         HILOGE("[OPP Service]:Transfer list_ is empty");
348         return;
349     }
350     std::list<std::shared_ptr<OppTransfer>>::iterator iter = oppTransferList_.begin();
351     for (; iter != oppTransferList_.end(); iter++) {
352         if ((*iter)->GetDeviceAddress() == device) {
353             break;
354         }
355     }
356     if (iter == oppTransferList_.end()) {
357         HILOGE("[OPP Service]:Not find transfer");
358         return;
359     }
360     if (iter == oppTransferList_.begin()) {
361         GetDispatcher()->PostTask(std::bind(&OppService::StartNextTransfer, this));
362     }
363     (*iter)->OnObexDisconnected();
364     oppTransferList_.erase(iter);
365 }
366 
OnTransferStateChange(const std::string & device,int state,int reason)367 void OppService::OnTransferStateChange(const std::string &device, int state, int reason)
368 {
369     if (oppTransferList_.empty()) {
370         HILOGE("[OPP Service]:Transfer list_ is empty");
371         return;
372     }
373     std::list<std::shared_ptr<OppTransfer>>::iterator iter = oppTransferList_.begin();
374     for (; iter != oppTransferList_.end(); iter++) {
375         if ((*iter)->GetDeviceAddress() == device) {
376             break;
377         }
378     }
379     if (iter == oppTransferList_.end()) {
380         HILOGE("[OPP Service]:Not find transfer");
381         return;
382     }
383     (*iter)->OnTransferStateChange(state, reason);
384 }
385 
OnTransferPositionChange(const std::string & device,size_t position)386 void OppService::OnTransferPositionChange(const std::string &device, size_t position)
387 {
388     if (oppTransferList_.empty()) {
389         HILOGE("[OPP Service]:Transfer list_ is empty");
390         return;
391     }
392     std::list<std::shared_ptr<OppTransfer>>::iterator iter = oppTransferList_.begin();
393     for (; iter != oppTransferList_.end(); iter++) {
394         if ((*iter)->GetDeviceAddress() == device) {
395             break;
396         }
397     }
398     if (iter == oppTransferList_.end()) {
399         HILOGE("[OPP Service]:Not find transfer");
400         return;
401     }
402     (*iter)->OnTransferPositionChange(position);
403 }
404 
StartNextTransfer()405 void OppService::StartNextTransfer()
406 {
407     if (oppTransferList_.size() > 0) {
408         if (oppTransferList_.front()->GetDirection() == OPP_TRANSFER_DIRECTION_OUTBOND) {
409             OppMessage event(OPP_CONNECT_REQ_EVT);
410             event.dev_ = oppTransferList_.front()->GetDeviceAddress();
411             PostEvent(event);
412         } else {
413             oppTransferList_.front()->AcceptConnect();
414         }
415     } else {
416         HILOGI("[OPP Service] No more file to transfer");
417     }
418 }
419 
RemoveStateMachine(const std::string & device)420 void OppService::RemoveStateMachine(const std::string &device)
421 {
422     OppMessage event(OPP_REMOVE_STATE_MACHINE_EVT);
423     event.dev_ = device;
424     PostEvent(event);
425 }
426 
PostEvent(const OppMessage & event)427 void OppService::PostEvent(const OppMessage &event)
428 {
429     GetDispatcher()->PostTask(std::bind(&OppService::ProcessEvent, this, event));
430 }
431 
ProcessEvent(const OppMessage & event)432 void OppService::ProcessEvent(const OppMessage &event)
433 {
434     std::lock_guard<std::recursive_mutex> lk(mutex_);
435     std::string address = event.dev_;
436     HILOGI("[OPP Service] address[%{public}s] event_no[%{public}d]", GetEncryptAddr(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]", GetEncryptAddr(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 BT_SUCCESS;
518 }
519 
Disconnect(const RawAddress & device)520 int OppService::Disconnect(const RawAddress &device)
521 {
522     HILOGI("[OPP Service] Enter");
523     // DO NOTHING
524     return BT_SUCCESS;
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