• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 HIMSA II K/S - www.himsa.com. Represented by EHIMA -
3  * www.ehima.com
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #pragma once
19 
20 #include <deque>
21 
22 #include "stack/gatt/gatt_int.h"
23 #include "types/raw_address.h"
24 
25 #define EATT_MIN_MTU_MPS (64)
26 #define EATT_DEFAULT_MTU (256)
27 #define EATT_ALL_CIDS (0xFFFF)
28 
29 namespace bluetooth {
30 namespace eatt {
31 
32 /* Enums */
33 enum class EattChannelState : uint8_t {
34   EATT_CHANNEL_PENDING = 0x00,
35   EATT_CHANNEL_OPENED,
36   EATT_CHANNEL_RECONFIGURING,
37 };
38 
39 class EattChannel {
40  public:
41   /* Pointer to EattDevice */
42   RawAddress bda_;
43   uint16_t cid_;
44   uint16_t tx_mtu_;
45   uint16_t rx_mtu_;
46   EattChannelState state_;
47 
48   /* Used to keep server commands */
49   tGATT_SR_CMD server_outstanding_cmd_;
50   /* Used to veryfy indication confirmation*/
51   uint16_t indicate_handle_;
52   /* local app confirm to indication timer */
53   alarm_t* ind_ack_timer_;
54   /* indication confirmation timer */
55   alarm_t* ind_confirmation_timer_;
56   /* GATT client command queue */
57   std::deque<tGATT_CMD_Q> cl_cmd_q_;
58 
EattChannel(RawAddress & bda,uint16_t cid,uint16_t tx_mtu,uint16_t rx_mtu)59   EattChannel(RawAddress& bda, uint16_t cid, uint16_t tx_mtu, uint16_t rx_mtu)
60       : bda_(bda),
61         cid_(cid),
62         tx_mtu_(tx_mtu),
63         rx_mtu_(rx_mtu),
64         state_(EattChannelState::EATT_CHANNEL_PENDING),
65         indicate_handle_(0),
66         ind_ack_timer_(NULL),
67         ind_confirmation_timer_(NULL) {
68     cl_cmd_q_ = std::deque<tGATT_CMD_Q>();
69   }
70 
~EattChannel()71   ~EattChannel() {
72     if (ind_ack_timer_ != NULL) {
73       alarm_free(ind_ack_timer_);
74     }
75 
76     if (ind_confirmation_timer_ != NULL) {
77       alarm_free(ind_confirmation_timer_);
78     }
79   }
80 
EattChannelSetState(EattChannelState state)81   void EattChannelSetState(EattChannelState state) {
82     if (state_ == EattChannelState::EATT_CHANNEL_PENDING) {
83       if (state == EattChannelState::EATT_CHANNEL_OPENED) {
84         memset(&server_outstanding_cmd_, 0, sizeof(tGATT_SR_CMD));
85         char name[64];
86         sprintf(name, "eatt_ind_ack_timer_%s_cid_0x%04x",
87                 bda_.ToString().c_str(), cid_);
88         ind_ack_timer_ = alarm_new(name);
89 
90         sprintf(name, "eatt_ind_conf_timer_%s_cid_0x%04x",
91                 bda_.ToString().c_str(), cid_);
92         ind_confirmation_timer_ = alarm_new(name);
93       }
94     }
95     state_ = state;
96   }
EattChannelSetTxMTU(uint16_t tx_mtu)97   void EattChannelSetTxMTU(uint16_t tx_mtu) { this->tx_mtu_ = tx_mtu; }
98 };
99 
100 /* Interface class */
101 class EattExtension {
102  public:
103   EattExtension();
104   EattExtension(const EattExtension&) = delete;
105   EattExtension& operator=(const EattExtension&) = delete;
106 
107   virtual ~EattExtension();
108 
GetInstance()109   static EattExtension* GetInstance() {
110     static EattExtension* instance = new EattExtension();
111     return instance;
112   }
113 
114   static void AddFromStorage(const RawAddress& bd_addr);
115 
116   /**
117    * Checks if EATT is supported on peer device.
118    *
119    * @param bd_addr peer device address
120    */
121   virtual bool IsEattSupportedByPeer(const RawAddress& bd_addr);
122 
123   /**
124    * Connect at maximum 5 EATT channels to peer device.
125    *
126    * @param bd_addr peer device address
127    */
128   virtual void Connect(const RawAddress& bd_addr);
129 
130   /**
131    * Disconnect all EATT channels to peer device.
132    *
133    * @param bd_addr peer device address
134    * @param cid remote channel id (EATT_ALL_CIDS for all)
135    */
136   virtual void Disconnect(const RawAddress& bd_addr,
137                           uint16_t cid = EATT_ALL_CIDS);
138 
139   /**
140    * Reconfigure EATT channel for give CID
141    *
142    * @param bd_addr peer device address
143    * @param cid channel id
144    * @param mtu new maximum transmit unit available of local device
145    */
146   virtual void Reconfigure(const RawAddress& bd_addr, uint16_t cid,
147                            uint16_t mtu);
148 
149   /**
150    * Reconfigure all EATT channels to peer device.
151    *
152    * @param bd_addr peer device address
153    * @param mtu new maximum transmit unit available of local device
154    */
155   virtual void ReconfigureAll(const RawAddress& bd_addr, uint16_t mtu);
156 
157   /* Below methods required by GATT implementation */
158 
159   /**
160    * Find EATT channel by cid.
161    *
162    * @param bd_addr peer device address
163    * @param cid channel id
164    *
165    * @return Eatt Channel instance.
166    */
167   virtual EattChannel* FindEattChannelByCid(const RawAddress& bd_addr,
168                                             uint16_t cid);
169 
170   /**
171    * Find EATT channel by transaction id.
172    *
173    * @param bd_addr peer device address
174    * @param trans_id transaction id
175    *
176    * @return pointer to EATT channel.
177    */
178   virtual EattChannel* FindEattChannelByTransId(const RawAddress& bd_addr,
179                                                 uint32_t trans_id);
180 
181   /**
182    * Check if EATT channel on given handle is waiting for a indication
183    * confirmation
184    *
185    * @param bd_addr peer device address
186    * @param indication_handle handle of the pending indication
187    *
188    * @return true if confirmation is pending false otherwise
189    */
190   virtual bool IsIndicationPending(const RawAddress& bd_addr,
191                                    uint16_t indication_handle);
192 
193   /**
194    * Get EATT channel available for indication.
195    *
196    * @param bd_addr peer device address
197    *
198    * @return pointer to EATT channel.
199    */
200   virtual EattChannel* GetChannelAvailableForIndication(
201       const RawAddress& bd_addr);
202 
203   /**
204    * Free Resources.
205    *
206    * (Maybe not needed)
207    * @param bd_addr peer device address
208    *
209    */
210   virtual void FreeGattResources(const RawAddress& bd_addr);
211 
212   /**
213    * Check if there is any EATT channels having some msg in its send queue
214    *
215    * @param bd_addr peer device address
216    *
217    * @return true when there is at least one EATT channel ready to send
218    */
219   virtual bool IsOutstandingMsgInSendQueue(const RawAddress& bd_addr);
220 
221   /**
222    * Get EATT channel ready to send.
223    *
224    * @param bd_addr peer device address
225    *
226    * @return pointer to EATT channel.
227    */
228   virtual EattChannel* GetChannelWithQueuedDataToSend(
229       const RawAddress& bd_addr);
230 
231   /**
232    * Get EATT channel available to send GATT request.
233    *
234    * @param bd_addr peer device address
235    *
236    * @return pointer to EATT channel.
237    */
238   virtual EattChannel* GetChannelAvailableForClientRequest(
239       const RawAddress& bd_addr);
240 
241   /**
242    * Start GATT indication timer per CID.
243    *
244    * @param bd_addr peer device address
245    * @param cid channel id
246    */
247   virtual void StartIndicationConfirmationTimer(const RawAddress& bd_addr,
248                                                 uint16_t cid);
249 
250   /**
251    * Stop GATT indication timer per CID.
252    *
253    * @param bd_addr peer device address
254    * @param cid channel id
255    */
256   virtual void StopIndicationConfirmationTimer(const RawAddress& bd_addr,
257                                                uint16_t cid);
258 
259   /**
260    *  Start application time for incoming indication on given CID
261    *
262    * @param bd_addr peer device address
263    * @param cid channel id
264    */
265   virtual void StartAppIndicationTimer(const RawAddress& bd_addr, uint16_t cid);
266 
267   /**
268    *  Stop application time for incoming indication on given CID
269    *
270    * @param bd_addr peer device address
271    * @param cid channel id
272    */
273   virtual void StopAppIndicationTimer(const RawAddress& bd_addr, uint16_t cid);
274 
275   /**
276    * Starts the EattExtension module
277    */
278   void Start();
279 
280   /**
281    * Stops the EattExtension module
282    */
283   void Stop();
284 
285  private:
286   struct impl;
287   std::unique_ptr<impl> pimpl_;
288 };
289 
290 }  // namespace eatt
291 }  // namespace bluetooth
292