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