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