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