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