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