• 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 "opp_statemachine.h"
17 
18 #include "log.h"
19 #include "opp_service.h"
20 
21 namespace OHOS {
22 namespace bluetooth {
OppStateMachine(const std::string & address)23 OppStateMachine::OppStateMachine(const std::string &address)
24     : address_(address)
25 {}
26 
Init()27 void OppStateMachine::Init()
28 {
29     connTimer_ = std::make_unique<utility::Timer>(
30         std::bind(&bluetooth::OppStateMachine::ConnectionTimeout, this));
31     disconnTimer_ = std::make_unique<utility::Timer>(
32         std::bind(&bluetooth::OppStateMachine::DisonnectionTimeout, this));
33 
34     std::unique_ptr<utility::StateMachine::State> disconnectedState =
35         std::make_unique<OppDisconnectedState>(DISCONNECTED, *this);
36     std::unique_ptr<utility::StateMachine::State> connectingState =
37         std::make_unique<OppConnectingState>(CONNECTING, *this);
38     std::unique_ptr<utility::StateMachine::State> disconnectingState =
39         std::make_unique<OppDisconnectingState>(DISCONNECTING, *this);
40     std::unique_ptr<utility::StateMachine::State> connectedState =
41         std::make_unique<OppConnectedState>(CONNECTED, *this);
42 
43     Move(disconnectedState);
44     Move(connectingState);
45     Move(disconnectingState);
46     Move(connectedState);
47 
48     InitState(DISCONNECTED);
49 }
50 
IsRemoving() const51 bool OppStateMachine::IsRemoving() const
52 {
53     return isRemoving_;
54 }
55 
SetRemoving(bool isRemoving)56 void OppStateMachine::SetRemoving(bool isRemoving)
57 {
58     isRemoving_ = isRemoving;
59 }
60 
GetDeviceAdress()61 std::string OppStateMachine::GetDeviceAdress()
62 {
63     return address_;
64 }
65 
Entry()66 void OppDisconnectedState::Entry()
67 {
68     if (isReentry_) {
69         stateMachine_.SetRemoving(true);
70         OppService *service = OppService::GetService();
71         if (service != nullptr) {
72             service->RemoveStateMachine(stateMachine_.GetDeviceAdress());
73         } else {
74             HILOGE("[OPP Machine]:OppService is nullptr!");
75         }
76         stateMachine_.NotifyStateTransitions();
77     }
78 }
79 
Exit()80 void OppDisconnectedState::Exit()
81 {
82     isReentry_ = true;
83 }
84 
Dispatch(const utility::Message & msg)85 bool OppDisconnectedState::Dispatch(const utility::Message &msg)
86 {
87     OppMessage &event = (OppMessage &)msg;
88     HILOGI("[OPP Machine]:[Disconnected][%{public}s]",
89         OppStateMachine::GetEventName(event.what_).c_str());
90     switch (event.what_) {
91         case OPP_CONNECT_REQ_EVT:
92             stateMachine_.ProcessConnectReqEvent(event);
93             Transition(OppStateMachine::CONNECTING);
94             break;
95         case OPP_CONNECTED_EVT:
96             stateMachine_.ProcessConnectedEvent(event);
97             Transition(OppStateMachine::CONNECTED);
98             break;
99         default:
100             break;
101     }
102     return true;
103 }
104 
Entry()105 void OppConnectingState::Entry()
106 {
107     stateMachine_.NotifyStateTransitions();
108     stateMachine_.StartConnectionTimer();
109 }
Exit()110 void OppConnectingState::Exit()
111 {
112     stateMachine_.StopConnectionTimer();
113 }
114 
Dispatch(const utility::Message & msg)115 bool OppConnectingState::Dispatch(const utility::Message &msg)
116 {
117     OppMessage &event = (OppMessage &)msg;
118     HILOGI("[OPP Machine]:[Connecting][%{public}s]",
119         OppStateMachine::GetEventName(event.what_).c_str());
120     switch (event.what_) {
121         case OPP_DISCONNECT_REQ_EVT:
122             stateMachine_.ProcessDisconnectReqEvent(event);
123             Transition(OppStateMachine::DISCONNECTING);
124             break;
125         case OPP_CONNECTED_EVT:
126             stateMachine_.ProcessConnectedEvent(event);
127             Transition(OppStateMachine::CONNECTED);
128             break;
129         case OPP_DISCONNECTED_EVT:
130             stateMachine_.ProcessDisconnectedEvent(event);
131             Transition(OppStateMachine::DISCONNECTED);
132             break;
133         case OPP_SDP_CMPL_EVT:
134             stateMachine_.ProcessSdpCompleteEvent(event);
135             break;
136         case OPP_GAP_CMPL_EVT:
137             stateMachine_.ProcessGapCompleteEvent(event);
138             break;
139         case OPP_CONNECTION_TIMEOUT_EVT:
140             stateMachine_.ProcessDisconnectedEvent(event);
141             Transition(OppStateMachine::DISCONNECTED);
142             break;
143         default:
144             break;
145     }
146     return true;
147 }
148 
Entry()149 void OppDisconnectingState::Entry()
150 {
151     stateMachine_.NotifyStateTransitions();
152     stateMachine_.StartDisconnectionTimer();
153 }
154 
Exit()155 void OppDisconnectingState::Exit()
156 {
157     stateMachine_.StopDisconnectionTimer();
158 }
159 
Dispatch(const utility::Message & msg)160 bool OppDisconnectingState::Dispatch(const utility::Message &msg)
161 {
162     OppMessage &event = (OppMessage &)msg;
163     HILOGI("[OPP Machine]:[Disconnecting][%{public}s]",
164         OppStateMachine::GetEventName(event.what_).c_str());
165     switch (event.what_) {
166         case OPP_CONNECTED_EVT:
167             stateMachine_.ProcessConnectedEvent(event);
168             Transition(OppStateMachine::CONNECTED);
169             break;
170         case OPP_DISCONNECTED_EVT:
171             stateMachine_.ProcessDisconnectedEvent(event);
172             Transition(OppStateMachine::DISCONNECTED);
173             break;
174         case OPP_DISCONNECTION_TIMEOUT_EVT:
175             stateMachine_.ProcessDisconnectedEvent(event);
176             Transition(OppStateMachine::DISCONNECTED);
177             break;
178         default:
179             break;
180     }
181     return true;
182 }
183 
Entry()184 void OppConnectedState::Entry()
185 {
186     stateMachine_.NotifyStateTransitions();
187 }
188 
Exit()189 void OppConnectedState::Exit()
190 {
191 }
192 
Dispatch(const utility::Message & msg)193 bool OppConnectedState::Dispatch(const utility::Message &msg)
194 {
195     OppMessage &event = (OppMessage &)msg;
196     HILOGI("[OPP Machine]:[Connected][%{public}s]",
197         OppStateMachine::GetEventName(event.what_).c_str());
198     switch (event.what_) {
199         case OPP_DISCONNECT_REQ_EVT:
200             stateMachine_.ProcessDisconnectReqEvent(event);
201             Transition(OppStateMachine::DISCONNECTING);
202             break;
203         case OPP_DISCONNECTED_EVT:
204             stateMachine_.ProcessDisconnectedEvent(event);
205             Transition(OppStateMachine::DISCONNECTED);
206             break;
207         default:
208             break;
209     }
210     return true;
211 }
212 
ProcessConnectReqEvent(const OppMessage & msg)213 void OppStateMachine::ProcessConnectReqEvent(const OppMessage &msg)
214 {
215     if (sdpClient_ == nullptr) {
216         sdpClient_ = std::make_unique<OppSdpClient>(address_);
217     }
218     sdpClient_->SdpSearch();
219 }
220 
ProcessDisconnectReqEvent(const OppMessage & msg)221 void OppStateMachine::ProcessDisconnectReqEvent(const OppMessage &msg)
222 {
223     OppService::GetService()->DisconnectObex(address_);
224 }
225 
ProcessSdpCompleteEvent(const OppMessage & msg)226 void OppStateMachine::ProcessSdpCompleteEvent(const OppMessage &msg)
227 {
228     if (msg.arg1_ == OPP_SDP_SUCCESS) {
229         GapSecChannel gapSecChannel;
230         RawAddress(address_).ConvertToUint8(obexConfig_.addr_.addr);
231         obexConfig_.addr_.type = BT_PUBLIC_DEVICE_ADDRESS;
232         obexConfig_.lpsm_ = OPP_GOEP_L2CAP_PSM;
233         obexConfig_.isSupportReliableSession_ = false;
234         if (msg.sdpInfo_.psm > 0) {
235             obexConfig_.isGoepL2capPSM_ = true;
236             obexConfig_.scn_ = msg.sdpInfo_.psm;
237             obexConfig_.isSupportSrm_ = true;
238             obexConfig_.mtu_ = OppService::GetService()->GetOppConfig().l2capMtu;
239             gapSecChannel.l2capPsm = obexConfig_.scn_;
240         } else {
241             obexConfig_.scn_ = msg.sdpInfo_.rfcommNo;
242             obexConfig_.mtu_ = OppService::GetService()->GetOppConfig().rfcommMtu;
243             gapSecChannel.rfcommChannel = obexConfig_.scn_;
244         }
245         gapClient_ = std::make_unique<OppGapClient>(address_, gapSecChannel, obexConfig_.isGoepL2capPSM_);
246         if ((gapClient_->Register() != BT_NO_ERROR) || (gapClient_->RequestSecurity() != BT_NO_ERROR)) {
247             OppMessage event(OPP_DISCONNECTED_EVT);
248             event.dev_ = address_;
249             OppService::GetService()->PostEvent(event);
250         }
251     } else {
252         OppMessage event(OPP_DISCONNECTED_EVT);
253         event.dev_ = address_;
254         OppService::GetService()->PostEvent(event);
255     }
256 }
257 
ProcessGapCompleteEvent(const OppMessage & msg)258 void OppStateMachine::ProcessGapCompleteEvent(const OppMessage &msg)
259 {
260     if (msg.arg1_ == OPP_GAP_SUCCESS) {
261         OppService::GetService()->ConnectObex(address_, obexConfig_);
262     } else {
263         OppMessage event(OPP_DISCONNECTED_EVT);
264         event.dev_ = address_;
265         OppService::GetService()->PostEvent(event);
266     }
267 }
268 
ProcessConnectedEvent(const OppMessage & msg)269 void OppStateMachine::ProcessConnectedEvent(const OppMessage &msg)
270 {
271     OppService::GetService()->OnObexConnected(address_);
272 }
273 
ProcessDisconnectedEvent(const OppMessage & msg)274 void OppStateMachine::ProcessDisconnectedEvent(const OppMessage &msg)
275 {
276     OppService::GetService()->OnObexDisconnected(address_);
277 }
278 
GetDeviceStateInt() const279 int OppStateMachine::GetDeviceStateInt() const
280 {
281     return static_cast<const OppState*>(GetState())->GetStateInt();
282 }
283 
StartConnectionTimer() const284 void OppStateMachine::StartConnectionTimer() const
285 {
286     connTimer_->Start(connectionTimeoutMs);
287     HILOGI("[OPP Machine]:Start connection timer!");
288 }
289 
StopConnectionTimer() const290 void OppStateMachine::StopConnectionTimer() const
291 {
292     connTimer_->Stop();
293     HILOGI("[OPP Machine]:Stop connection timer!");
294 }
295 
ConnectionTimeout() const296 void OppStateMachine::ConnectionTimeout() const
297 {
298     OppMessage event(OPP_CONNECTION_TIMEOUT_EVT);
299     event.dev_ = address_;
300     OppService::GetService()->PostEvent(event);
301 }
302 
StartDisconnectionTimer() const303 void OppStateMachine::StartDisconnectionTimer() const
304 {
305     disconnTimer_->Start(disconnectionTimeoutMs);
306     HILOGI("[OPP Machine]:Start disconnection timer!");
307 }
308 
StopDisconnectionTimer() const309 void OppStateMachine::StopDisconnectionTimer() const
310 {
311     disconnTimer_->Stop();
312     HILOGI("[OPP Machine]:Stop disconnection timer!");
313 }
314 
DisonnectionTimeout() const315 void OppStateMachine::DisonnectionTimeout() const
316 {
317     OppMessage event(OPP_DISCONNECTION_TIMEOUT_EVT);
318     event.dev_ = address_;
319     OppService::GetService()->PostEvent(event);
320 }
321 
GetEventName(int what)322 std::string OppStateMachine::GetEventName(int what)
323 {
324     switch (what) {
325         case OPP_CONNECT_REQ_EVT:
326             return "OPP_CONNECT_REQ_EVT";
327         case OPP_DISCONNECT_REQ_EVT:
328             return "OPP_DISCONNECT_REQ_EVT";
329         case OPP_CONNECTED_EVT:
330             return "OPP_CONNECTED_EVT";
331         case OPP_DISCONNECTED_EVT:
332             return "OPP_DISCONNECTED_EVT";
333         case OPP_SDP_CMPL_EVT:
334             return "OPP_SDP_CMPL_EVT";
335         case OPP_GAP_CMPL_EVT:
336             return "OPP_GAP_CMPL_EVT";
337         case OPP_CONNECTION_TIMEOUT_EVT:
338             return "OPP_CONNECTION_TIMEOUT_EVT";
339         case OPP_DISCONNECTION_TIMEOUT_EVT:
340             return "OPP_DISCONNECTION_TIMEOUT_EVT";
341         default:
342             return "Unknown";
343     }
344 }
345 
NotifyStateTransitions()346 void OppStateMachine::NotifyStateTransitions()
347 {
348     OppService *service = OppService::GetService();
349     int toState = GetDeviceStateInt();
350     if (service != nullptr) {
351         RawAddress device(address_);
352         if ((preState_ != toState) && (preState_ <= OPP_STATE_CONNECTED) &&
353             (toState <= OPP_STATE_CONNECTED)) {
354             service->NotifyStateChanged(device, toState);
355         }
356     }
357 
358     preState_ = toState;
359 }
360 }  // namespace bluetooth
361 }  // namespace OHOS
362