1 /*
2  * Copyright (C) 2021-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 #ifndef GATT_CONNECTION_MANAGER_H
17 #define GATT_CONNECTION_MANAGER_H
18 
19 #include <cstdint>
20 #include <list>
21 #include <memory>
22 #include <mutex>
23 #include <string>
24 #include <tuple>
25 #include <vector>
26 #include "base_def.h"
27 #include "dispatcher.h"
28 #include "gatt_connection_observer.h"
29 #include "gatt_data.h"
30 #include "raw_address.h"
31 #include "state_machine.h"
32 #include "timer.h"
33 
34 namespace OHOS {
35 namespace bluetooth {
36 class GattConnectionManager {
37 public:
38     class Device {
39     public:
40         struct ConnectionPriorityResult {
41             uint16_t interval_;
42             uint16_t latency_;
43             uint16_t timeout_;
44             int status;
45         };
46         static const std::string STATE_IDLE;
47         static const std::string STATE_CONNECTING;
48         static const std::string STATE_CONNECTED;
49         static const std::string STATE_DISCONNECTING;
50         static const std::string STATE_DISCONNECTED;
51 
52         class StateMachine : public utility::StateMachine {
53         public:
54             enum StateMessage {
55                 MSG_CONNECT,
56                 MSG_CONNECT_COMPLETE,
57                 MSG_DISCONNECT,
58                 MSG_DISCONNECT_COMPLETE,
59                 MSG_REQUEST_CONNECTION_PRIORITY,
60                 MSG_RESPONSE_CONNECTION_PRIORITY,
61                 MSG_DIRECT_CONNECT_TIMEOUT,
62                 MSG_RECONNECT_CAUSE_0X3E
63             };
64             explicit StateMachine(GattConnectionManager::Device &device);
65             ~StateMachine();
66 
67         private:
68             class StateBase : public utility::StateMachine::State {
69             public:
70                 StateBase(const std::string &name,
71                     utility::StateMachine &stateMachine, GattConnectionManager::Device &device);
~StateBase()72                 virtual ~StateBase()
73                 {}
74 
75             protected:
76                 GattConnectionManager::Device &device_;
77             };
78             struct Idle : public StateBase {
79                 Idle(utility::StateMachine &stateMachine, GattConnectionManager::Device &device);
~IdleIdle80                 ~Idle() override{};
81                 void Entry() override;
ExitIdle82                 void Exit() override{};
83                 bool Dispatch(const utility::Message &msg) override;
84             };
85             struct Connecting : public StateBase {
86                 Connecting(utility::StateMachine &stateMachine, GattConnectionManager::Device &device);
~ConnectingConnecting87                 ~Connecting() override{};
88                 void Entry() override;
ExitConnecting89                 void Exit() override{};
90                 bool Dispatch(const utility::Message &msg) override;
91             };
92             struct Connected : public StateBase {
93                 Connected(utility::StateMachine &stateMachine, GattConnectionManager::Device &device);
~ConnectedConnected94                 ~Connected() override{};
95                 void Entry() override;
ExitConnected96                 void Exit() override{};
97                 bool Dispatch(const utility::Message &msg) override;
98             };
99             struct Disconnecting : public StateBase {
100                 Disconnecting(utility::StateMachine &stateMachine, GattConnectionManager::Device &device);
~DisconnectingDisconnecting101                 ~Disconnecting() override{};
102                 void Entry() override;
ExitDisconnecting103                 void Exit() override{};
104                 bool Dispatch(const utility::Message &msg) override;
105             };
106             struct Disconnected : public StateBase {
107                 Disconnected(utility::StateMachine &stateMachine, GattConnectionManager::Device &device);
~DisconnectedDisconnected108                 ~Disconnected() override{};
109                 void Entry() override;
ExitDisconnected110                 void Exit() override{};
111                 bool Dispatch(const utility::Message &msg) override;
112             };
113         };
114 
115         Device(const uint8_t *addr, uint8_t transport, uint8_t type, bool autoConnect = false);
116         explicit Device(const GattDevice &device, bool autoConnect = false);
117         ~Device();
118         bool ProcessMessage(int messageId, int arg1 = 0, void *arg2 = nullptr);
119         void CheckEncryption();
120         bool &AutoConnect();
121         uint8_t *Addr();
122         GattDevice &Info();
123         StateMachine &SM();
124         uint16_t &MTU();
125         uint16_t &Handle();
126         uint8_t &Role();
127         uint8_t &RetryTimes();
128         std::mutex &DeviceRWMutex();
129         utility::Timer &DirectConnect();
130 
131     private:
132         bool autoConnect_;
133         uint16_t mtu_;
134         uint16_t handle_;
135         uint8_t role_;
136         uint8_t retry_;
137         uint8_t addr_[RawAddress::BT_ADDRESS_BYTE_LEN] = {0};
138         GattDevice info_;
139         std::mutex deviceRWMutex_;
140         StateMachine sm_;
141         utility::Timer directConnect_;
142         void CopyAddress(const uint8_t *addr, size_t length);
143         Device() = delete;
144         BT_DISALLOW_COPY_AND_ASSIGN(Device);
145         BT_DISALLOW_MOVE_AND_ASSIGN(Device);
146     };
147 
GetInstance()148     static GattConnectionManager &GetInstance()
149     {
150         static GattConnectionManager instance;
151         return instance;
152     }
153     ~GattConnectionManager();
154 
155     int Connect(const GattDevice &device, bool autoConnect = false) const;
156     int Disconnect(const GattDevice &device) const;
157     int RegisterObserver(GattConnectionObserver &observer) const;
158     void DeregisterObserver(int registerId) const;
159     const std::string &GetDeviceState(const GattDevice &device) const;
160     void GetDevices(std::vector<GattDevice> &devices) const;
161     std::pair<uint16_t, uint16_t> GetMaximumNumberOfConnections() const;
162     std::tuple<std::string, uint16_t, uint16_t> GetDeviceInformation(const GattDevice &device) const;
163     uint8_t GetDeviceTransport(uint16_t handle) const;
164     int RequestConnectionPriority(uint16_t handle, int connPriority) const;
165     bool GetEncryptionInfo(uint16_t connectHandle) const;
166     bool GetEncryptionInfo(const GattDevice &device) const;
167     int SetConnectionType(const GattDevice &device, bool autoConnect) const;
168 
169     int StartUp(utility::Dispatcher &dispatcher);
170     int ShutDown() const;
171 
172 private:
173     static const uint8_t MAX_OBSERVER_NUM = 4;
174     static const uint16_t BT_PSM_GATT = 0x001F;
175     static const int DIRECT_CONNECT_TIMEOUT = 30000;
176     GattConnectionManager();
177     DECLARE_IMPL();
178 
179     BT_DISALLOW_COPY_AND_ASSIGN(GattConnectionManager);
180 };
181 }  // namespace bluetooth
182 }  // namespace OHOS
183 
184 #endif  // GATT_CONNECTION_MANAGER_H
185