• 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 "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_NO_ERROR;
94     int resultBnep = BT_NO_ERROR;
95     panSdp_ = std::make_unique<PanSdp>();
96     resultSdp = panSdp_->Register();
97     resultBnep = PanBnep::Startup();
98     if (resultSdp == BT_NO_ERROR && resultBnep == BT_NO_ERROR) {
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         LOG_ERROR("[PAN Service]%{public}s():Invalid Device address:%{public}s", __FUNCTION__, 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     LOG_DEBUG("[PAN Service]%{public}s():address[%{public}s] event_no[%{public}d]",
446         __FUNCTION__, address.c_str(), event.what_);
447     switch (event.what_) {
448         case PAN_SERVICE_STARTUP_EVT:
449             StartUp();
450             break;
451         case PAN_SERVICE_SHUTDOWN_EVT:
452             ShutDown();
453             break;
454         case PAN_INT_OPEN_EVT:
455         case BNEP_L2CAP_CONNECT_REQ_EVT:
456             ProcessConnectEvent(event);
457             break;
458         case PAN_REMOVE_STATE_MACHINE_EVT:
459             ProcessRemoveStateMachine(event.dev_);
460             break;
461         default:
462             ProcessDefaultEvent(event);
463             break;
464     }
465 }
466 
ProcessConnectEvent(const PanMessage & event)467 void PanService::ProcessConnectEvent(const PanMessage &event)
468 {
469     if (GetConnectionsDeviceNum() < maxConnectionsNum_) {
470         auto it = stateMachines_.find(event.dev_);
471         if (it != stateMachines_.end() && it->second != nullptr && it->second->IsRemoving()) {
472             // peer device may send connect request before we remove statemachine for last connection.
473             // so post this connect request, process it after we remove statemachine completely.
474             PostEvent(event);
475         } else if (it == stateMachines_.end() || it->second == nullptr) {
476             stateMachines_[event.dev_] = std::make_unique<PanStateMachine>(event.dev_);
477             stateMachines_[event.dev_]->Init();
478             stateMachines_[event.dev_]->ProcessMessage(event);
479             if (event.what_ == BNEP_L2CAP_CONNECT_REQ_EVT) {
480                 stateMachines_[event.dev_]->ProcessL2capConnectionEvent(event);
481             }
482         } else {
483             it->second->ProcessMessage(event);
484             if (event.what_ == BNEP_L2CAP_CONNECT_REQ_EVT) {
485                 it->second->ProcessL2capConnectionEvent(event);
486             }
487         }
488     }
489 }
490 
PanFindDeviceByLcid(uint16_t lcid)491 std::string PanService::PanFindDeviceByLcid(uint16_t lcid)
492 {
493     std::string ret;
494 
495     std::lock_guard<std::recursive_mutex> lk(mutex_);
496     for (auto it = stateMachines_.begin(); it != stateMachines_.end(); ++it) {
497         if ((it->second != nullptr) && ((it->second->GetDeviceLcid() == lcid))) {
498             return it->first;
499         }
500     }
501     return ret;
502 }
503 
GetLocalAddress()504 std::string PanService::GetLocalAddress()
505 {
506     IAdapterClassic *adapterClassic = (IAdapterClassic *)(IAdapterManager::GetInstance()->
507         GetAdapter(ADAPTER_BREDR));
508     if (adapterClassic != nullptr) {
509         return adapterClassic->GetLocalAddress();
510     }
511     return std::string();
512 }
513 
ProcessRemoveStateMachine(const std::string & address)514 void PanService::ProcessRemoveStateMachine(const std::string &address)
515 {
516     stateMachines_.insert_or_assign(address, nullptr);
517     if (isShuttingDown_) {
518         ShutDownDone(false);
519     }
520 }
521 
ProcessDefaultEvent(const PanMessage & event) const522 void PanService::ProcessDefaultEvent(const PanMessage &event) const
523 {
524     auto it = stateMachines_.find(event.dev_);
525     if ((it != stateMachines_.end()) && (it->second != nullptr)) {
526         if ((event.what_ > BNEP_L2CAP_START_EVT) && (event.what_ < BNEP_L2CAP_END_EVT)) {
527             it->second->ProcessL2capConnectionEvent(event);
528         } else {
529             it->second->ProcessMessage(event);
530         }
531     } else {
532         LOG_ERROR("[PAN Service]%{public}s():invalid address[%{public}s]", __FUNCTION__, event.dev_.c_str());
533     }
534 }
535 REGISTER_CLASS_CREATOR(PanService);
536 }  // namespace bluetooth
537 }  // namespace OHOS
538