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 "pan_service.h"
17 #include "sdp.h"
18
19 namespace OHOS {
20 namespace bluetooth {
PanService()21 PanService::PanService() : utility::Context(PROFILE_NAME_PAN, "1.0")
22 {
23 LOG_DEBUG("[PAN Service]%{public}s:%{public}s Create", PROFILE_NAME_PAN.c_str(), Name().c_str());
24 }
25
~PanService()26 PanService::~PanService()
27 {
28 LOG_DEBUG("[PAN Service]%{public}s:%{public}s Destroy", PROFILE_NAME_PAN.c_str(), Name().c_str());
29 }
30
GetContext()31 utility::Context *PanService::GetContext()
32 {
33 return this;
34 }
35
GetService()36 PanService *PanService::GetService()
37 {
38 auto servManager = IProfileManager::GetInstance();
39 return static_cast<PanService *>(servManager->GetProfileService(PROFILE_NAME_PAN));
40 }
41
RegisterObserver(IPanObserver & panObserver)42 void PanService::RegisterObserver(IPanObserver &panObserver)
43 {
44 LOG_DEBUG("[PAN Service]%{public}s Enter", __PRETTY_FUNCTION__);
45
46 panObservers_.Register(panObserver);
47 }
48
DeregisterObserver(IPanObserver & panObserver)49 void PanService::DeregisterObserver(IPanObserver &panObserver)
50 {
51 LOG_DEBUG("[PAN Service]%{public}s Enter", __PRETTY_FUNCTION__);
52
53 panObservers_.Deregister(panObserver);
54 }
55
NotifyStateChanged(const RawAddress & device,int state)56 void PanService::NotifyStateChanged(const RawAddress &device, int state)
57 {
58 LOG_DEBUG("[PAN Service]%{public}s Enter", __PRETTY_FUNCTION__);
59 int newState = stateMap_.at(state);
60
61 panObservers_.ForEach([device, newState](IPanObserver &observer) {
62 observer.OnConnectionStateChanged(device, newState);
63 });
64 }
65
Enable(void)66 void PanService::Enable(void)
67 {
68 LOG_DEBUG("[PAN Service]%{public}s Enter", __PRETTY_FUNCTION__);
69
70 PanMessage event(PAN_SERVICE_STARTUP_EVT);
71 PostEvent(event);
72 }
73
Disable(void)74 void PanService::Disable(void)
75 {
76 LOG_DEBUG("[PAN Service]%{public}s Enter", __PRETTY_FUNCTION__);
77
78 PanMessage event(PAN_SERVICE_SHUTDOWN_EVT);
79 PostEvent(event);
80 }
81
StartUp()82 void PanService::StartUp()
83 {
84 LOG_DEBUG("[PAN Service]%{public}s():==========<start>==========", __FUNCTION__);
85 if (isStarted_) {
86 GetContext()->OnEnable(PROFILE_NAME_PAN, true);
87 LOG_WARN("[PAN Service]%{public}s():PanService has already been started before.", __FUNCTION__);
88 return;
89 }
90
91 maxConnectionsNum_ = GetMaxConnectionsDeviceNum();
92
93 int resultSdp = BT_SUCCESS;
94 int resultBnep = BT_SUCCESS;
95 panSdp_ = std::make_unique<PanSdp>();
96 resultSdp = panSdp_->Register();
97 resultBnep = PanBnep::Startup();
98 if (resultSdp == BT_SUCCESS && resultBnep == BT_SUCCESS) {
99 GetContext()->OnEnable(PROFILE_NAME_PAN, true);
100 isStarted_ = true;
101 LOG_DEBUG("[PAN Service]%{public}s():PanService started", __FUNCTION__);
102 } else {
103 GetContext()->OnEnable(PROFILE_NAME_PAN, false);
104 }
105 }
106
ShutDown()107 void PanService::ShutDown()
108 {
109 LOG_DEBUG("[PAN Service]%{public}s():==========<start>==========", __FUNCTION__);
110 if (!isStarted_) {
111 GetContext()->OnDisable(PROFILE_NAME_PAN, true);
112 LOG_WARN("[PAN Service]%{public}s():PanService has already been shutdown before.", __FUNCTION__);
113 return;
114 }
115
116 isShuttingDown_ = true;
117 bool isDisconnected = false;
118 for (auto it = stateMachines_.begin(); it != stateMachines_.end(); ++it) {
119 if ((it->second != nullptr) && (it->second->GetDeviceStateInt() > PAN_STATE_DISCONNECTED)) {
120 Disconnect(RawAddress(it->first));
121 isDisconnected = true;
122 }
123 }
124
125 if (!isDisconnected) {
126 ShutDownDone(true);
127 }
128 }
129
ShutDownDone(bool isAllDisconnected)130 void PanService::ShutDownDone(bool isAllDisconnected)
131 {
132 LOG_DEBUG("[PAN Service]%{public}s():==========<start>==========", __FUNCTION__);
133 if (!isAllDisconnected) {
134 for (auto it = stateMachines_.begin(); it != stateMachines_.end(); ++it) {
135 if ((it->second != nullptr) && (it->second->GetDeviceStateInt() > PAN_STATE_DISCONNECTED)) {
136 return;
137 }
138 }
139 }
140
141 stateMachines_.clear();
142 panSdp_->Deregister();
143 GetContext()->OnDisable(PROFILE_NAME_PAN, true);
144 isStarted_ = false;
145 LOG_DEBUG("[PAN Service]%{public}s():PanService shutdown", __FUNCTION__);
146 isShuttingDown_ = false;
147 }
148
Connect(const RawAddress & device)149 int PanService::Connect(const RawAddress &device)
150 {
151 LOG_DEBUG("[PAN Service]%{public}s Enter", __PRETTY_FUNCTION__);
152 // DO NOTHING AT THIS TIME
153 return PAN_SUCCESS;
154 }
155
Disconnect(const RawAddress & device)156 int PanService::Disconnect(const RawAddress &device)
157 {
158 LOG_DEBUG("[PAN Service]%{public}s Enter", __PRETTY_FUNCTION__);
159
160 std::lock_guard<std::recursive_mutex> lk(mutex_);
161 std::string address = device.GetAddress();
162 auto it = stateMachines_.find(address);
163 if (it == stateMachines_.end() || it->second == nullptr) {
164 LOG_DEBUG("[PAN Service]%{public}s():The state machine is not available!", __FUNCTION__);
165 return PAN_FAILURE;
166 }
167
168 int slcState = it->second->GetDeviceStateInt();
169 if ((slcState != PAN_STATE_CONNECTING) && (slcState < PAN_STATE_CONNECTED)) {
170 LOG_DEBUG("[PAN Service]%{public}s():slcState:%{public}d", __FUNCTION__, slcState);
171 return PAN_FAILURE;
172 }
173
174 PanMessage event(PAN_API_CLOSE_EVT);
175 event.dev_ = address;
176 PostEvent(event);
177 return PAN_SUCCESS;
178 }
179
SetTethering(bool enable)180 bool PanService::SetTethering(bool enable)
181 {
182 LOG_DEBUG("[PAN Service]%{public}s Enter", __PRETTY_FUNCTION__);
183
184 std::lock_guard<std::recursive_mutex> lk(mutex_);
185 if (!enable && (isTetheringOn_ != enable)) {
186 for (auto it = stateMachines_.begin(); it != stateMachines_.end(); it++) {
187 if ((it->second != nullptr) && (it->second->GetDeviceStateInt() == PAN_STATE_CONNECTED)) {
188 PanMessage event(PAN_API_CLOSE_EVT);
189 event.dev_ = it->first;
190 PostEvent(event);
191 }
192 }
193 }
194 isTetheringOn_ = enable;
195 return true;
196 }
197
IsTetheringOn()198 bool PanService::IsTetheringOn()
199 {
200 return isTetheringOn_;
201 }
202
OpenNetwork()203 void PanService::OpenNetwork()
204 {
205 if (panNetwork_ == nullptr) {
206 panNetwork_ = std::make_unique<PanNetwork>();
207 }
208 panNetwork_->Open();
209 }
210
CloseNetwork(std::string device)211 void PanService::CloseNetwork(std::string device)
212 {
213 if (panNetwork_ == nullptr) {
214 LOG_ERROR("[PAN Service]%{public}s():panNetwork_ is null", __FUNCTION__);
215 return;
216 }
217 for (auto it = stateMachines_.begin(); it != stateMachines_.end(); it++) {
218 if ((it->second == nullptr) && (it->second->GetDeviceStateInt() == PAN_STATE_CONNECTED) &&
219 (it->first != device)) {
220 LOG_DEBUG("[PAN Service]%{public}s had other connected device", __PRETTY_FUNCTION__);
221 return;
222 }
223 }
224 panNetwork_->Close();
225 panNetwork_ = nullptr;
226 }
227
ReceiveRemoteBusy(bool isBusy)228 int PanService::ReceiveRemoteBusy(bool isBusy)
229 {
230 if (panNetwork_ == nullptr) {
231 LOG_ERROR("[PAN Service]%{public}s():panNetwork_ is null", __FUNCTION__);
232 return PAN_FAILURE;
233 }
234 panNetwork_->ReceiveRemoteBusy(isBusy);
235 return PAN_SUCCESS;
236 }
237
WriteNetworkData(std::string address,EthernetHeader head,uint8_t * data,int len)238 void PanService::WriteNetworkData(std::string address, EthernetHeader head, uint8_t *data, int len)
239 {
240 if (head.destAddr[0] & 0x01) {
241 LOG_DEBUG("[PAN Service]%{public}s is broadcast,also forward to other device", __PRETTY_FUNCTION__);
242 for (auto it = stateMachines_.begin(); it != stateMachines_.end(); it++) {
243 if ((it->second != nullptr) && (it->second->GetDeviceStateInt() == PAN_STATE_CONNECTED)
244 && (it->first != address)) {
245 PanSendData(it->first, head, data, len);
246 }
247 }
248 } else {
249 uint8_t bluetoothDestAddr[BT_ADDRESS_LENGTH];
250 ReverseAddress(head.destAddr, bluetoothDestAddr);
251 std::string destAddr = RawAddress::ConvertToString(bluetoothDestAddr).GetAddress();
252 auto it = stateMachines_.find(destAddr);
253 if ((it != stateMachines_.end()) && (it->second == nullptr) &&
254 (it->second->GetDeviceStateInt() == PAN_STATE_CONNECTED)) {
255 LOG_DEBUG("[PAN Service]%{public}s():destination address is other connected device!", __FUNCTION__);
256 PanSendData(it->first, head, data, len);
257 return;
258 }
259 }
260 if (panNetwork_ == nullptr) {
261 LOG_ERROR("[PAN Service]%{public}s():panNetwork_ is null", __FUNCTION__);
262 return;
263 }
264 panNetwork_->WriteData(head, data, len);
265 }
266
PanSendData(EthernetHeader head,uint8_t * data,int len)267 int PanService::PanSendData(EthernetHeader head, uint8_t *data, int len)
268 {
269 int isBroadcast = head.destAddr[0] & 1;
270 uint8_t bluetoothDestAddr[BT_ADDRESS_LENGTH];
271 uint8_t bluetoothSrcAddr[BT_ADDRESS_LENGTH];
272 ReverseAddress(head.destAddr, bluetoothDestAddr);
273 ReverseAddress(head.srcAddr, bluetoothSrcAddr);
274 std::string destAddr = RawAddress::ConvertToString(bluetoothDestAddr).GetAddress();
275 std::string srcAddr = RawAddress::ConvertToString(bluetoothSrcAddr).GetAddress();
276
277 for (auto it = stateMachines_.begin(); it != stateMachines_.end(); it++) {
278 if ((it->second->GetDeviceStateInt() == PAN_STATE_CONNECTED) &&
279 (isBroadcast || (destAddr == it->first) || (srcAddr == it->first))) {
280 PanSendData(it->first, head, data, len);
281 }
282 }
283 return PAN_SUCCESS;
284 }
285
ReverseAddress(uint8_t * oldAddr,uint8_t * newAddr)286 void PanService::ReverseAddress(uint8_t *oldAddr, uint8_t *newAddr)
287 {
288 for (int i = 0; i < BT_ADDRESS_LENGTH; i++) {
289 newAddr[i] = oldAddr[BT_ADDRESS_LENGTH - i - 1];
290 }
291 }
292
PanSendData(std::string address,EthernetHeader head,uint8_t * data,int len)293 void PanService::PanSendData(std::string address, EthernetHeader head, uint8_t *data, int len)
294 {
295 PanMessage event(PAN_API_WRITE_DATA_EVT);
296 event.dev_ = address;
297 event.ethernetHeader_ = head;
298 if ((len > 0) && (data != nullptr)) {
299 event.dataLength_ = len;
300 std::unique_ptr<uint8_t[]> buff = std::make_unique<uint8_t[]>(event.dataLength_);
301 if (memcpy_s(buff.get(), len, data, len) != EOK) {
302 LOG_ERROR("[PAN Service]%{public}s(): memcpy error", __FUNCTION__);
303 return;
304 }
305 event.data_ = std::make_shared<std::unique_ptr<uint8_t[]>>(std::move(buff));
306 }
307 PostEvent(event);
308 }
309
IsConnected(const std::string & address) const310 bool PanService::IsConnected(const std::string &address) const
311 {
312 LOG_DEBUG("[PAN Service]%{public}s Enter", __PRETTY_FUNCTION__);
313
314 auto it = stateMachines_.find(address);
315 if (it == stateMachines_.end() || it->second == nullptr) {
316 HILOGE("[PAN Service] Invalid Device address:%{public}s", GetEncryptAddr(address).c_str());
317 return false;
318 }
319 if (it->second->GetDeviceStateInt() < PAN_STATE_CONNECTED) {
320 LOG_DEBUG("[PAN Service]%{public}s():It's not connected!", __FUNCTION__);
321 return false;
322 }
323 return true;
324 }
325
GetDevicesByStates(std::vector<int> states)326 std::vector<RawAddress> PanService::GetDevicesByStates(std::vector<int> states)
327 {
328 LOG_DEBUG("[PAN Service]%{public}s Enter", __PRETTY_FUNCTION__);
329
330 std::lock_guard<std::recursive_mutex> lk(mutex_);
331 std::vector<RawAddress> devices;
332 for (auto it = stateMachines_.begin(); it != stateMachines_.end(); ++it) {
333 RawAddress device(it->first);
334 for (size_t i = 0; i < states.size(); i++) {
335 if (GetDeviceState(device) == states[i]) {
336 devices.push_back(device);
337 break;
338 }
339 }
340 }
341 return devices;
342 }
343
GetDeviceState(const RawAddress & device)344 int PanService::GetDeviceState(const RawAddress &device)
345 {
346 LOG_DEBUG("[PAN Service]%{public}s():==========<start>==========", __FUNCTION__);
347 std::lock_guard<std::recursive_mutex> lk(mutex_);
348 std::string address = device.GetAddress();
349 auto it = stateMachines_.find(address);
350 if (it == stateMachines_.end() || it->second == nullptr) {
351 LOG_DEBUG("[PAN Service]%{public}s():The state machine is not available!", __FUNCTION__);
352 return stateMap_.at(PAN_STATE_DISCONNECTED);
353 }
354
355 if (it->second->GetDeviceStateInt() >= PAN_STATE_CONNECTED) {
356 return stateMap_.at(PAN_STATE_CONNECTED);
357 } else {
358 return stateMap_.at(it->second->GetDeviceStateInt());
359 }
360 }
361
GetConnectDevices(void)362 std::list<RawAddress> PanService::GetConnectDevices(void)
363 {
364 LOG_DEBUG("[PAN Service]%{public}s Enter", __PRETTY_FUNCTION__);
365
366 std::lock_guard<std::recursive_mutex> lk(mutex_);
367 std::list<RawAddress> devList;
368 for (auto it = stateMachines_.begin(); it != stateMachines_.end(); ++it) {
369 if ((it->second != nullptr) && (it->second->GetDeviceStateInt() >= PAN_STATE_CONNECTED)) {
370 devList.push_back(RawAddress(it->first));
371 }
372 }
373 return devList;
374 }
375
GetConnectState(void)376 int PanService::GetConnectState(void)
377 {
378 LOG_DEBUG("[PAN Service]%{public}s Enter", __PRETTY_FUNCTION__);
379
380 int result = 0;
381 std::lock_guard<std::recursive_mutex> lk(mutex_);
382 for (auto it = stateMachines_.begin(); it != stateMachines_.end(); ++it) {
383 if (it->second == nullptr) {
384 result |= PROFILE_STATE_DISCONNECTED;
385 } else if (it->second->GetDeviceStateInt() >= PAN_STATE_CONNECTED) {
386 result |= PROFILE_STATE_CONNECTED;
387 } else if (it->second->GetDeviceStateInt() == PAN_STATE_CONNECTING) {
388 result |= PROFILE_STATE_CONNECTING;
389 } else if (it->second->GetDeviceStateInt() == PAN_STATE_DISCONNECTING) {
390 result |= PROFILE_STATE_DISCONNECTING;
391 } else if (it->second->GetDeviceStateInt() == PAN_STATE_DISCONNECTED) {
392 result |= PROFILE_STATE_DISCONNECTED;
393 }
394 }
395 return result;
396 }
397
GetMaxConnectNum(void)398 int PanService::GetMaxConnectNum(void)
399 {
400 LOG_DEBUG("[PAN Service]%{public}s Enter", __PRETTY_FUNCTION__);
401
402 std::lock_guard<std::recursive_mutex> lk(mutex_);
403 return maxConnectionsNum_;
404 }
405
GetConnectionsDeviceNum() const406 int PanService::GetConnectionsDeviceNum() const
407 {
408 int size = 0;
409 for (auto iter = stateMachines_.begin(); iter != stateMachines_.end(); ++iter) {
410 if (iter->second != nullptr) {
411 auto connectionState = iter->second->GetDeviceStateInt();
412 if ((connectionState == PAN_STATE_CONNECTING) || (connectionState >= PAN_STATE_CONNECTED)) {
413 size++;
414 }
415 }
416 }
417 return size;
418 }
419
GetMaxConnectionsDeviceNum() const420 int PanService::GetMaxConnectionsDeviceNum() const
421 {
422 int number = PAN_MAX_DEFAULT_CONNECTIONS_NUMR;
423 if (!AdapterConfig::GetInstance()->GetValue(SECTION_PAN_SERVICE, PROPERTY_MAX_CONNECTED_DEVICES, number)) {
424 LOG_DEBUG("[PAN Service]%{public}s():It's failed to get the max connection number", __FUNCTION__);
425 }
426 return number;
427 }
428
RemoveStateMachine(const std::string & device)429 void PanService::RemoveStateMachine(const std::string &device)
430 {
431 PanMessage event(PAN_REMOVE_STATE_MACHINE_EVT);
432 event.dev_ = device;
433 PostEvent(event);
434 }
435
PostEvent(const PanMessage & event)436 void PanService::PostEvent(const PanMessage &event)
437 {
438 GetDispatcher()->PostTask(std::bind(&PanService::ProcessEvent, this, event));
439 }
440
ProcessEvent(const PanMessage & event)441 void PanService::ProcessEvent(const PanMessage &event)
442 {
443 std::lock_guard<std::recursive_mutex> lk(mutex_);
444 std::string address = event.dev_;
445 HILOGE("[PAN Service] address[%{public}s] event_no[%{public}d]", GetEncryptAddr(address).c_str(), event.what_);
446 switch (event.what_) {
447 case PAN_SERVICE_STARTUP_EVT:
448 StartUp();
449 break;
450 case PAN_SERVICE_SHUTDOWN_EVT:
451 ShutDown();
452 break;
453 case PAN_INT_OPEN_EVT:
454 case BNEP_L2CAP_CONNECT_REQ_EVT:
455 ProcessConnectEvent(event);
456 break;
457 case PAN_REMOVE_STATE_MACHINE_EVT:
458 ProcessRemoveStateMachine(event.dev_);
459 break;
460 default:
461 ProcessDefaultEvent(event);
462 break;
463 }
464 }
465
ProcessConnectEvent(const PanMessage & event)466 void PanService::ProcessConnectEvent(const PanMessage &event)
467 {
468 if (GetConnectionsDeviceNum() < maxConnectionsNum_) {
469 auto it = stateMachines_.find(event.dev_);
470 if (it != stateMachines_.end() && it->second != nullptr && it->second->IsRemoving()) {
471 // peer device may send connect request before we remove statemachine for last connection.
472 // so post this connect request, process it after we remove statemachine completely.
473 PostEvent(event);
474 } else if (it == stateMachines_.end() || it->second == nullptr) {
475 stateMachines_[event.dev_] = std::make_unique<PanStateMachine>(event.dev_);
476 stateMachines_[event.dev_]->Init();
477 stateMachines_[event.dev_]->ProcessMessage(event);
478 if (event.what_ == BNEP_L2CAP_CONNECT_REQ_EVT) {
479 stateMachines_[event.dev_]->ProcessL2capConnectionEvent(event);
480 }
481 } else {
482 it->second->ProcessMessage(event);
483 if (event.what_ == BNEP_L2CAP_CONNECT_REQ_EVT) {
484 it->second->ProcessL2capConnectionEvent(event);
485 }
486 }
487 }
488 }
489
PanFindDeviceByLcid(uint16_t lcid)490 std::string PanService::PanFindDeviceByLcid(uint16_t lcid)
491 {
492 std::string ret;
493
494 std::lock_guard<std::recursive_mutex> lk(mutex_);
495 for (auto it = stateMachines_.begin(); it != stateMachines_.end(); ++it) {
496 if ((it->second != nullptr) && ((it->second->GetDeviceLcid() == lcid))) {
497 return it->first;
498 }
499 }
500 return ret;
501 }
502
GetLocalAddress()503 std::string PanService::GetLocalAddress()
504 {
505 auto adapterClassic = IAdapterManager::GetInstance()->GetClassicAdapterInterface();
506 if (adapterClassic != nullptr) {
507 return adapterClassic->GetLocalAddress();
508 }
509 return std::string();
510 }
511
ProcessRemoveStateMachine(const std::string & address)512 void PanService::ProcessRemoveStateMachine(const std::string &address)
513 {
514 stateMachines_.insert_or_assign(address, nullptr);
515 if (isShuttingDown_) {
516 ShutDownDone(false);
517 }
518 }
519
ProcessDefaultEvent(const PanMessage & event) const520 void PanService::ProcessDefaultEvent(const PanMessage &event) const
521 {
522 auto it = stateMachines_.find(event.dev_);
523 if ((it != stateMachines_.end()) && (it->second != nullptr)) {
524 if ((event.what_ > BNEP_L2CAP_START_EVT) && (event.what_ < BNEP_L2CAP_END_EVT)) {
525 it->second->ProcessL2capConnectionEvent(event);
526 } else {
527 it->second->ProcessMessage(event);
528 }
529 } else {
530 HILOGE("[PAN Service] invalid address[%{public}s]", GetEncryptAddr(event.dev_).c_str());
531 }
532 }
533 REGISTER_CLASS_CREATOR(PanService);
534 } // namespace bluetooth
535 } // namespace OHOS
536