• Home
  • History
  • Annotate
  • 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  
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  
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  
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    }
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  
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