• 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 #include <bluetooth/log.h>
19 
20 #include "eatt_impl.h"
21 #include "stack/include/bt_hdr.h"
22 #include "stack/include/bt_psm_types.h"
23 #include "types/raw_address.h"
24 
25 using bluetooth::eatt::eatt_impl;
26 
27 namespace bluetooth {
28 namespace eatt {
29 
30 struct EattExtension::impl {
31   impl() = default;
32   ~impl() = default;
33 
Startbluetooth::eatt::EattExtension::impl34   void Start() {
35     if (eatt_impl_) {
36       log::error("Eatt already started");
37       return;
38     };
39 
40     /* Register server for Eatt */
41     memset(&reg_info_, 0, sizeof(reg_info_));
42     reg_info_.pL2CA_CreditBasedConnectInd_Cb = eatt_connect_ind;
43     reg_info_.pL2CA_CreditBasedConnectCfm_Cb = eatt_connect_cfm;
44     reg_info_.pL2CA_CreditBasedReconfigCompleted_Cb = eatt_reconfig_completed;
45     reg_info_.pL2CA_DisconnectInd_Cb = eatt_disconnect_ind;
46     reg_info_.pL2CA_Error_Cb = eatt_error_cb;
47     reg_info_.pL2CA_DataInd_Cb = eatt_data_ind;
48     reg_info_.pL2CA_CreditBasedCollisionInd_Cb = eatt_collision_ind;
49 
50     if (L2CA_RegisterLECoc(BT_PSM_EATT, reg_info_, BTM_SEC_NONE, {}) == 0) {
51       log::error("cannot register EATT");
52     } else {
53       eatt_impl_ = std::make_unique<eatt_impl>();
54     }
55   }
56 
Stopbluetooth::eatt::EattExtension::impl57   void Stop() {
58     if (!eatt_impl_) {
59       log::error("Eatt not started");
60       return;
61     }
62     eatt_impl_.reset(nullptr);
63     L2CA_DeregisterLECoc(BT_PSM_EATT);
64   }
65 
IsRunningbluetooth::eatt::EattExtension::impl66   bool IsRunning() { return eatt_impl_ ? true : false; }
67 
GetImplInstancebluetooth::eatt::EattExtension::impl68   static eatt_impl* GetImplInstance(void) {
69     auto* instance = EattExtension::GetInstance();
70     return instance->pimpl_->eatt_impl_.get();
71   }
72 
eatt_connect_indbluetooth::eatt::EattExtension::impl73   static void eatt_connect_ind(const RawAddress& bda,
74                                std::vector<uint16_t>& lcids, uint16_t psm,
75                                uint16_t peer_mtu, uint8_t identifier) {
76     auto p_eatt_impl = GetImplInstance();
77     if (p_eatt_impl)
78       p_eatt_impl->eatt_l2cap_connect_ind(bda, lcids, psm, peer_mtu,
79                                           identifier);
80   }
81 
eatt_connect_cfmbluetooth::eatt::EattExtension::impl82   static void eatt_connect_cfm(const RawAddress& bda, uint16_t lcid,
83                                uint16_t peer_mtu, uint16_t result) {
84     auto p_eatt_impl = GetImplInstance();
85     if (p_eatt_impl)
86       p_eatt_impl->eatt_l2cap_connect_cfm(bda, lcid, peer_mtu, result);
87   }
88 
eatt_reconfig_completedbluetooth::eatt::EattExtension::impl89   static void eatt_reconfig_completed(const RawAddress& bda, uint16_t lcid,
90                                       bool is_local_cfg,
91                                       tL2CAP_LE_CFG_INFO* p_cfg) {
92     auto p_eatt_impl = GetImplInstance();
93     if (p_eatt_impl)
94       p_eatt_impl->eatt_l2cap_reconfig_completed(bda, lcid, is_local_cfg,
95                                                  p_cfg);
96   }
97 
eatt_collision_indbluetooth::eatt::EattExtension::impl98   static void eatt_collision_ind(const RawAddress& bd_addr) {
99     auto p_eatt_impl = GetImplInstance();
100     if (p_eatt_impl) p_eatt_impl->eatt_l2cap_collision_ind(bd_addr);
101   }
102 
eatt_error_cbbluetooth::eatt::EattExtension::impl103   static void eatt_error_cb(uint16_t lcid, uint16_t reason) {
104     auto p_eatt_impl = GetImplInstance();
105     if (p_eatt_impl) p_eatt_impl->eatt_l2cap_error_cb(lcid, reason);
106   }
107 
eatt_disconnect_indbluetooth::eatt::EattExtension::impl108   static void eatt_disconnect_ind(uint16_t lcid, bool please_confirm) {
109     auto p_eatt_impl = GetImplInstance();
110     if (p_eatt_impl)
111       p_eatt_impl->eatt_l2cap_disconnect_ind(lcid, please_confirm);
112   }
113 
eatt_data_indbluetooth::eatt::EattExtension::impl114   static void eatt_data_ind(uint16_t lcid, BT_HDR* data_p) {
115     auto p_eatt_impl = GetImplInstance();
116     if (p_eatt_impl) p_eatt_impl->eatt_l2cap_data_ind(lcid, data_p);
117   }
118 
119   std::unique_ptr<eatt_impl> eatt_impl_;
120   tL2CAP_APPL_INFO reg_info_;
121 };
122 
AddFromStorage(const RawAddress & bd_addr)123 void EattExtension::AddFromStorage(const RawAddress& bd_addr) {
124   eatt_impl* p_eatt_impl = EattExtension::impl::GetImplInstance();
125   if (p_eatt_impl) p_eatt_impl->add_from_storage(bd_addr);
126 }
127 
EattExtension()128 EattExtension::EattExtension() : pimpl_(std::make_unique<impl>()) {}
129 
IsEattSupportedByPeer(const RawAddress & bd_addr)130 bool EattExtension::IsEattSupportedByPeer(const RawAddress& bd_addr) {
131   return pimpl_->eatt_impl_->is_eatt_supported_by_peer(bd_addr);
132 }
133 
Connect(const RawAddress & bd_addr)134 void EattExtension::Connect(const RawAddress& bd_addr) {
135   pimpl_->eatt_impl_->connect(bd_addr);
136 }
137 
Disconnect(const RawAddress & bd_addr,uint16_t cid)138 void EattExtension::Disconnect(const RawAddress& bd_addr, uint16_t cid) {
139   pimpl_->eatt_impl_->disconnect(bd_addr, cid);
140 }
141 
Reconfigure(const RawAddress & bd_addr,uint16_t cid,uint16_t mtu)142 void EattExtension::Reconfigure(const RawAddress& bd_addr, uint16_t cid,
143                                 uint16_t mtu) {
144   pimpl_->eatt_impl_->reconfigure(bd_addr, cid, mtu);
145 }
ReconfigureAll(const RawAddress & bd_addr,uint16_t mtu)146 void EattExtension::ReconfigureAll(const RawAddress& bd_addr, uint16_t mtu) {
147   pimpl_->eatt_impl_->reconfigure_all(bd_addr, mtu);
148 }
149 
FindEattChannelByCid(const RawAddress & bd_addr,uint16_t cid)150 EattChannel* EattExtension::FindEattChannelByCid(const RawAddress& bd_addr,
151                                                  uint16_t cid) {
152   return pimpl_->eatt_impl_->find_eatt_channel_by_cid(bd_addr, cid);
153 }
154 
FindEattChannelByTransId(const RawAddress & bd_addr,uint32_t trans_id)155 EattChannel* EattExtension::FindEattChannelByTransId(const RawAddress& bd_addr,
156                                                      uint32_t trans_id) {
157   return pimpl_->eatt_impl_->find_eatt_channel_by_transid(bd_addr, trans_id);
158 }
159 
IsIndicationPending(const RawAddress & bd_addr,uint16_t indication_handle)160 bool EattExtension::IsIndicationPending(const RawAddress& bd_addr,
161                                         uint16_t indication_handle) {
162   return pimpl_->eatt_impl_->is_indication_pending(bd_addr, indication_handle);
163 }
164 
GetChannelAvailableForIndication(const RawAddress & bd_addr)165 EattChannel* EattExtension::GetChannelAvailableForIndication(
166     const RawAddress& bd_addr) {
167   return pimpl_->eatt_impl_->get_channel_available_for_indication(bd_addr);
168 }
169 
FreeGattResources(const RawAddress & bd_addr)170 void EattExtension::FreeGattResources(const RawAddress& bd_addr) {
171   pimpl_->eatt_impl_->free_gatt_resources(bd_addr);
172 }
173 
IsOutstandingMsgInSendQueue(const RawAddress & bd_addr)174 bool EattExtension::IsOutstandingMsgInSendQueue(const RawAddress& bd_addr) {
175   return pimpl_->eatt_impl_->is_outstanding_msg_in_send_queue(bd_addr);
176 }
177 
GetChannelWithQueuedDataToSend(const RawAddress & bd_addr)178 EattChannel* EattExtension::GetChannelWithQueuedDataToSend(
179     const RawAddress& bd_addr) {
180   return pimpl_->eatt_impl_->get_channel_with_queued_data(bd_addr);
181 }
182 
GetChannelAvailableForClientRequest(const RawAddress & bd_addr)183 EattChannel* EattExtension::GetChannelAvailableForClientRequest(
184     const RawAddress& bd_addr) {
185   return pimpl_->eatt_impl_->get_channel_available_for_client_request(bd_addr);
186 }
187 
188 /* Start stop GATT indication timer per CID */
StartIndicationConfirmationTimer(const RawAddress & bd_addr,uint16_t cid)189 void EattExtension::StartIndicationConfirmationTimer(const RawAddress& bd_addr,
190                                                      uint16_t cid) {
191   pimpl_->eatt_impl_->start_indication_confirm_timer(bd_addr, cid);
192 }
193 
StopIndicationConfirmationTimer(const RawAddress & bd_addr,uint16_t cid)194 void EattExtension::StopIndicationConfirmationTimer(const RawAddress& bd_addr,
195                                                     uint16_t cid) {
196   pimpl_->eatt_impl_->stop_indication_confirm_timer(bd_addr, cid);
197 }
198 
199 /* Start stop application indication timeout */
StartAppIndicationTimer(const RawAddress & bd_addr,uint16_t cid)200 void EattExtension::StartAppIndicationTimer(const RawAddress& bd_addr,
201                                             uint16_t cid) {
202   pimpl_->eatt_impl_->start_app_indication_timer(bd_addr, cid);
203 }
204 
StopAppIndicationTimer(const RawAddress & bd_addr,uint16_t cid)205 void EattExtension::StopAppIndicationTimer(const RawAddress& bd_addr,
206                                            uint16_t cid) {
207   pimpl_->eatt_impl_->stop_app_indication_timer(bd_addr, cid);
208 }
209 
Start()210 void EattExtension::Start() { pimpl_->Start(); }
211 
Stop()212 void EattExtension::Stop() { pimpl_->Stop(); }
213 
214 EattExtension::~EattExtension() = default;
215 
216 }  // namespace eatt
217 }  // namespace bluetooth
218