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