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_statemachine.h"
17 #include "pan_service.h"
18 
19 namespace OHOS {
20 namespace bluetooth {
PanStateMachine(const std::string & address)21 PanStateMachine::PanStateMachine(const std::string &address)
22     : address_(address), panBnep_(address)
23 {}
24 
Init()25 void PanStateMachine::Init()
26 {
27     connTimer_ = std::make_unique<utility::Timer>(
28         std::bind(&bluetooth::PanStateMachine::ConnectionTimeout, this));
29     disconnTimer_ = std::make_unique<utility::Timer>(
30         std::bind(&bluetooth::PanStateMachine::DisonnectionTimeout, this));
31 
32     std::unique_ptr<utility::StateMachine::State> disconnectedState =
33         std::make_unique<PanDisconnectedState>(DISCONNECTED, *this);
34     std::unique_ptr<utility::StateMachine::State> connectingState =
35         std::make_unique<PanConnectingState>(CONNECTING, *this);
36     std::unique_ptr<utility::StateMachine::State> disconnectingState =
37         std::make_unique<PanDisconnectingState>(DISCONNECTING, *this);
38     std::unique_ptr<utility::StateMachine::State> connectedState =
39         std::make_unique<PanConnectedState>(CONNECTED, *this);
40 
41     Move(disconnectedState);
42     Move(connectingState);
43     Move(disconnectingState);
44     Move(connectedState);
45 
46     InitState(DISCONNECTED);
47 }
48 
IsRemoving() const49 bool PanStateMachine::IsRemoving() const
50 {
51     return isRemoving_;
52 }
53 
SetRemoving(bool isRemoving)54 void PanStateMachine::SetRemoving(bool isRemoving)
55 {
56     isRemoving_ = isRemoving;
57 }
58 
GetDeviceLcid()59 uint16_t PanStateMachine::GetDeviceLcid()
60 {
61     return panBnep_.GetLcid();
62 }
63 
ProcessL2capConnectionEvent(const PanMessage & event)64 void PanStateMachine::ProcessL2capConnectionEvent(
65     const PanMessage &event)
66 {
67     LOG_DEBUG("[PAN Machine]%{public}s():event[%{public}s]", __FUNCTION__,
68         PanStateMachine::GetEventName(event.what_).c_str());
69     panBnep_.ProcessEvent(event);
70 }
71 
GetDeviceAdress()72 std::string PanStateMachine::GetDeviceAdress()
73 {
74     return address_;
75 }
76 
Entry()77 void PanDisconnectedState::Entry()
78 {
79     stateMachine_.ProcessDeferredMessage();
80 
81     if (isReentry_) {
82         stateMachine_.SetRemoving(true);
83         PanService *service = PanService::GetService();
84         if (service != nullptr) {
85             service->RemoveStateMachine(stateMachine_.GetDeviceAdress());
86         } else {
87             LOG_ERROR("[PAN Machine]%{public}s():PanService is nullptr!", __FUNCTION__);
88         }
89         stateMachine_.NotifyStateTransitions();
90     }
91 }
92 
Exit()93 void PanDisconnectedState::Exit()
94 {
95     isReentry_ = true;
96 }
97 
Dispatch(const utility::Message & msg)98 bool PanDisconnectedState::Dispatch(const utility::Message &msg)
99 {
100     PanMessage &event = (PanMessage &)msg;
101     LOG_DEBUG("[PAN Machine]%{public}s():[Disconnected][%{public}s]",
102         __FUNCTION__, PanStateMachine::GetEventName(event.what_).c_str());
103     switch (event.what_) {
104         case PAN_INT_OPEN_EVT:
105             stateMachine_.ProcessOpenEvent(event);
106             Transition(PanStateMachine::CONNECTING);
107             break;
108         case PAN_OPEN_CMPL_EVT:
109             Transition(PanStateMachine::CONNECTED);
110             break;
111         default:
112             break;
113     }
114     return true;
115 }
116 
117 
Entry()118 void PanConnectingState::Entry()
119 {
120     stateMachine_.NotifyStateTransitions();
121     stateMachine_.StartConnectionTimer();
122 }
Exit()123 void PanConnectingState::Exit()
124 {
125     stateMachine_.StopConnectionTimer();
126 }
127 
Dispatch(const utility::Message & msg)128 bool PanConnectingState::Dispatch(const utility::Message &msg)
129 {
130     PanMessage &event = (PanMessage &)msg;
131     LOG_DEBUG("[PAN Machine]%{public}s():[Connecting][%{public}s]", __FUNCTION__,
132         PanStateMachine::GetEventName(event.what_).c_str());
133     switch (event.what_) {
134         case PAN_API_CLOSE_EVT:
135             stateMachine_.AddDeferredMessage(event);
136             break;
137         case PAN_INT_OPEN_EVT:
138             stateMachine_.ProcessOpenEvent(event);
139             Transition(PanStateMachine::CONNECTING);
140             break;
141         case PAN_INT_CLOSE_EVT:
142             stateMachine_.ProcessCloseEvent(event);
143             Transition(PanStateMachine::DISCONNECTED);
144             break;
145         case PAN_OPEN_CMPL_EVT:
146             stateMachine_.ProcessOpenComplete(event);
147             Transition(PanStateMachine::CONNECTED);
148             break;
149         default:
150             break;
151     }
152     return true;
153 }
154 
Entry()155 void PanDisconnectingState::Entry()
156 {
157     stateMachine_.NotifyStateTransitions();
158     stateMachine_.StartDisconnectionTimer();
159 }
160 
Exit()161 void PanDisconnectingState::Exit()
162 {
163     stateMachine_.StopDisconnectionTimer();
164 }
165 
Dispatch(const utility::Message & msg)166 bool PanDisconnectingState::Dispatch(const utility::Message &msg)
167 {
168     PanMessage &event = (PanMessage &)msg;
169     LOG_DEBUG("[PAN Machine]%{public}s():[Disconnecting][%{public}s]", __FUNCTION__,
170         PanStateMachine::GetEventName(event.what_).c_str());
171     switch (event.what_) {
172         case PAN_INT_OPEN_EVT:
173             stateMachine_.ProcessOpenEvent(event);
174             Transition(PanStateMachine::CONNECTING);
175             break;
176         case PAN_INT_CLOSE_EVT:
177             stateMachine_.ProcessCloseEvent(event);
178             Transition(PanStateMachine::DISCONNECTED);
179             break;
180         case PAN_OPEN_CMPL_EVT:
181             Transition(PanStateMachine::CONNECTED);
182             break;
183         case PAN_DISCONNECTION_TIMEOUT_EVT:
184             Transition(PanStateMachine::CONNECTED);
185             break;
186         default:
187             break;
188     }
189     return true;
190 }
191 
Entry()192 void PanConnectedState::Entry()
193 {
194     stateMachine_.ProcessDeferredMessage();
195     stateMachine_.NotifyStateTransitions();
196 }
197 
Exit()198 void PanConnectedState::Exit()
199 {
200 }
201 
Dispatch(const utility::Message & msg)202 bool PanConnectedState::Dispatch(const utility::Message &msg)
203 {
204     PanMessage &event = (PanMessage &)msg;
205     LOG_DEBUG("[PAN Machine]%{public}s():[Connected][%{public}s]", __FUNCTION__,
206         PanStateMachine::GetEventName(event.what_).c_str());
207     switch (event.what_) {
208         case PAN_API_CLOSE_EVT:
209             stateMachine_.ProcessCloseReqEvent(event);
210             Transition(PanStateMachine::DISCONNECTING);
211             break;
212         case PAN_INT_CLOSE_EVT:
213             stateMachine_.ProcessCloseEvent(event);
214             Transition(PanStateMachine::DISCONNECTED);
215             break;
216         case PAN_API_WRITE_DATA_EVT:
217             stateMachine_.ProcessSendData(event);
218             break;
219         case PAN_INT_DATA_EVT:
220             stateMachine_.ProcessReciveData(event);
221             break;
222         default:
223             break;
224     }
225     return true;
226 }
227 
ProcessOpenEvent(const PanMessage & msg)228 void PanStateMachine::ProcessOpenEvent(const PanMessage &msg)
229 {
230     PanMessage event(PAN_OPEN_CMPL_EVT);
231     event.dev_ = address_;
232     PanService::GetService()->PostEvent(event);
233 }
234 
ProcessCloseReqEvent(const PanMessage & msg)235 void PanStateMachine::ProcessCloseReqEvent(const PanMessage &msg)
236 {
237     panBnep_.Disconnect();
238 }
239 
ProcessCloseEvent(const PanMessage & msg)240 void PanStateMachine::ProcessCloseEvent(const PanMessage &msg)
241 {
242     PanService::GetService()->CloseNetwork(address_);
243 }
244 
ProcessReciveData(const PanMessage & msg)245 void PanStateMachine::ProcessReciveData(const PanMessage &msg)
246 {
247     uint8_t* data = nullptr;
248     int dataLength = 0;
249     if (msg.data_ != nullptr) {
250         data = msg.data_->get();
251         dataLength = msg.dataLength_;
252     }
253     PanService::GetService()->WriteNetworkData(address_, msg.ethernetHeader_, data, dataLength);
254 }
255 
ProcessSendData(const PanMessage & msg)256 void PanStateMachine::ProcessSendData(const PanMessage &msg)
257 {
258     uint8_t* data = nullptr;
259     int dataLength = 0;
260     if (msg.data_ != nullptr) {
261         data = msg.data_->get();
262         dataLength = msg.dataLength_;
263     }
264     panBnep_.SendData(msg.ethernetHeader_, data, dataLength);
265 }
266 
ProcessOpenComplete(const PanMessage & msg)267 void PanStateMachine::ProcessOpenComplete(const PanMessage &msg)
268 {
269     if (!PanService::GetService()->IsTetheringOn()) {
270         PanMessage event(PAN_API_CLOSE_EVT);
271         event.dev_ = address_;
272         PanService::GetService()->PostEvent(event);
273         return;
274     }
275     PanService::GetService()->OpenNetwork();
276 }
277 
GetDeviceStateInt() const278 int PanStateMachine::GetDeviceStateInt() const
279 {
280     return static_cast<const PanState*>(GetState())->GetStateInt();
281 }
282 
StartConnectionTimer() const283 void PanStateMachine::StartConnectionTimer() const
284 {
285     connTimer_->Start(CONNECTION_TIMEOUT_MS);
286     LOG_INFO("[PAN Machine]%{public}s():Start connection timer!", __FUNCTION__);
287 }
288 
StopConnectionTimer() const289 void PanStateMachine::StopConnectionTimer() const
290 {
291     connTimer_->Stop();
292     LOG_INFO("[PAN Machine]%{public}s():Stop connection timer!", __FUNCTION__);
293 }
294 
ConnectionTimeout() const295 void PanStateMachine::ConnectionTimeout() const
296 {
297     PanMessage event(PAN_CONNECTION_TIMEOUT_EVT);
298     event.dev_ = address_;
299     PanService::GetService()->PostEvent(event);
300 }
301 
StartDisconnectionTimer() const302 void PanStateMachine::StartDisconnectionTimer() const
303 {
304     disconnTimer_->Start(DISCONNECTION_TIMEOUT_MS);
305     LOG_INFO("[PAN Machine]%{public}s():Start disconnection timer!", __FUNCTION__);
306 }
307 
StopDisconnectionTimer() const308 void PanStateMachine::StopDisconnectionTimer() const
309 {
310     disconnTimer_->Stop();
311     LOG_INFO("[PAN Machine]%{public}s():Stop disconnection timer!", __FUNCTION__);
312 }
313 
DisonnectionTimeout() const314 void PanStateMachine::DisonnectionTimeout() const
315 {
316     PanMessage event(PAN_DISCONNECTION_TIMEOUT_EVT);
317     event.dev_ = address_;
318     PanService::GetService()->PostEvent(event);
319 }
320 
GetEventName(int what)321 std::string PanStateMachine::GetEventName(int what)
322 {
323     switch (what) {
324         case PAN_API_CLOSE_EVT:
325             return "PAN_API_CLOSE_EVENT";
326         case PAN_INT_OPEN_EVT:
327             return "PAN_INT_OPEN_EVENT";
328         case PAN_INT_CLOSE_EVT:
329             return "PAN_INT_CLOSE_EVENT";
330         case PAN_OPEN_CMPL_EVT:
331             return "PAN_OPEN_CMPL_EVENT";
332         case PAN_API_WRITE_DATA_EVT:
333             return "PAN_API_WRITE_DATA_EVENT";
334         case PAN_INT_DATA_EVT:
335             return "PAN_INT_DATA_EVENT";
336         case PAN_DISCONNECTION_TIMEOUT_EVT:
337             return "PAN_DISCONNECTION_TIMEOUT_EVT";
338         default:
339             return "Unknown";
340     }
341 }
342 
NotifyStateTransitions()343 void PanStateMachine::NotifyStateTransitions()
344 {
345     PanService *service = PanService::GetService();
346     int toState = GetDeviceStateInt();
347     if (service != nullptr) {
348         RawAddress device(address_);
349         if ((preState_ != toState) && (preState_ <= PAN_STATE_CONNECTED)
350             && (toState <= PAN_STATE_CONNECTED)) {
351             service->NotifyStateChanged(device, toState);
352         }
353     }
354 
355     preState_ = toState;
356 }
357 
AddDeferredMessage(const PanMessage & msg)358 void PanStateMachine::AddDeferredMessage(const PanMessage &msg)
359 {
360     deferMsgs_.push_back(msg);
361 }
362 
ProcessDeferredMessage()363 void PanStateMachine::ProcessDeferredMessage()
364 {
365     auto size = deferMsgs_.size();
366     while (size-- > 0 && !deferMsgs_.empty()) {
367         PanMessage event = deferMsgs_.front();
368         deferMsgs_.pop_front();
369         PanService::GetService()->PostEvent(event);
370     }
371 }
372 }  // namespace bluetooth
373 }  // namespace OHOS
374