1 /*
2 * Copyright (C) 2014 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holders nor the names of
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * 4. Any redistribution, use, or modification is done solely for
17 * personal benefit and not for any commercial purpose or for
18 * monetary gain.
19 *
20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24 * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * Please inquire about commercial licensing options at
34 * [email protected]
35 *
36 */
37
38 #define BTSTACK_FILE__ "att_dispatch.c"
39
40
41 /**
42 * Dispatcher for independent implementation of ATT client and server
43 */
44
45 #include "ble/att_dispatch.h"
46 #include "ble/core.h"
47 #include "btstack_debug.h"
48 #include "l2cap.h"
49 #include "btstack_event.h"
50
51 #define ATT_SERVER 0u
52 #define ATT_CLIENT 1u
53 #define ATT_MAX 2u
54
55 struct {
56 btstack_packet_handler_t packet_handler;
57 bool waiting_for_can_send;
58 } subscriptions[ATT_MAX];
59
60 // index of subscription that will get can send now first if waiting for it
61 static uint8_t att_round_robin;
62
63 // track can send now requests
64 static bool can_send_now_pending;
65
66 #ifdef ENABLE_GATT_OVER_CLASSIC
att_dispatch_att_server_for_l2cap_cid(uint16_t l2cap_cid)67 static att_server_t * att_dispatch_att_server_for_l2cap_cid(uint16_t l2cap_cid){
68 btstack_linked_list_iterator_t it;
69 hci_connections_get_iterator(&it);
70 while(btstack_linked_list_iterator_has_next(&it)) {
71 hci_connection_t *hci_connection = (hci_connection_t *) btstack_linked_list_iterator_next(&it);
72 att_server_t *att_server = &hci_connection->att_server;
73 if (att_server->l2cap_cid == l2cap_cid){
74 return att_server;
75 }
76 }
77 return NULL;
78 }
79 #endif
80
att_dispatch_handle_can_send_now(uint8_t * packet,uint16_t size)81 static void att_dispatch_handle_can_send_now(uint8_t *packet, uint16_t size){
82 uint8_t i;
83 uint8_t index;
84 uint16_t l2cap_cid = l2cap_event_can_send_now_get_local_cid(packet);
85 #ifdef ENABLE_GATT_OVER_CLASSIC
86 if (l2cap_cid != L2CAP_CID_ATTRIBUTE_PROTOCOL){
87 att_server_t * att_server = att_dispatch_att_server_for_l2cap_cid(l2cap_cid);
88 if (att_server != NULL){
89 for (i = 0u; i < ATT_MAX; i++) {
90 index = (att_round_robin + i) & 1u;
91 if (att_server->send_requests[index]) {
92 att_server->send_requests[index] = false;
93 // registered packet handlers from Unenhanced LE
94 subscriptions[index].packet_handler(HCI_EVENT_PACKET, l2cap_cid, packet, size);
95 // fairness: prioritize next service
96 att_round_robin = (index + 1u) % ATT_MAX;
97 // stop if client cannot send anymore
98 if (!l2cap_can_send_packet_now(l2cap_cid)) break;
99 }
100 }
101 // check if more can send now events are needed
102 bool send_request_pending = att_server->send_requests[ATT_CLIENT]
103 || att_server->send_requests[ATT_SERVER];
104 if (send_request_pending){
105 l2cap_request_can_send_now_event(att_server->l2cap_cid);
106 }
107 return;
108 }
109 }
110 #endif
111 can_send_now_pending = false;
112 for (i = 0u; i < ATT_MAX; i++){
113 index = (att_round_robin + i) & 1u;
114 if ( (subscriptions[index].packet_handler != NULL) && subscriptions[index].waiting_for_can_send){
115 subscriptions[index].waiting_for_can_send = false;
116 subscriptions[index].packet_handler(HCI_EVENT_PACKET, l2cap_cid, packet, size);
117 // fairness: prioritize next service
118 att_round_robin = (index + 1u) % ATT_MAX;
119 // stop if client cannot send anymore
120 if (!hci_can_send_acl_le_packet_now()) break;
121 }
122 }
123 // check if more can send now events are needed
124 if (!can_send_now_pending){
125 for (i = 0u; i < ATT_MAX; i++){
126 if ((subscriptions[i].packet_handler != NULL) && subscriptions[i].waiting_for_can_send){
127 can_send_now_pending = true;
128 // note: con_handle is not used, so we can pass in anything
129 l2cap_request_can_send_fix_channel_now_event(0, L2CAP_CID_ATTRIBUTE_PROTOCOL);
130 break;
131 }
132 }
133 }
134 }
135
att_dispatch_handle_att_pdu(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)136 static void att_dispatch_handle_att_pdu(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
137 uint8_t index;
138 uint8_t opcode;
139 uint8_t method;
140 bool for_server;
141 bool invalid;
142
143 // parse opcode
144 opcode = packet[0u];
145 method = opcode & 0x03fu;
146 invalid = method > ATT_MULTIPLE_HANDLE_VALUE_NTF;
147 // odd PDUs are sent from server to client - even PDUs are sent from client to server, also let server handle invalid ones
148 for_server = ((method & 1u) == 0u) || invalid;
149 index = for_server ? ATT_SERVER : ATT_CLIENT;
150 if (!subscriptions[index].packet_handler) return;
151 subscriptions[index].packet_handler(packet_type, channel, packet, size);
152 }
153
att_packet_handler(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)154 static void att_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
155 #ifdef ENABLE_GATT_OVER_CLASSIC
156 hci_connection_t * hci_connection;
157 att_server_t * att_server;
158 hci_con_handle_t con_handle;
159 bool outgoing_active;
160 uint8_t index;
161 bd_addr_t address;
162 uint16_t l2cap_cid;
163 uint8_t status;
164 #endif
165 switch (packet_type){
166 case ATT_DATA_PACKET:
167 att_dispatch_handle_att_pdu(packet_type, channel, packet, size);
168 break;
169 #ifdef ENABLE_GATT_OVER_CLASSIC
170 case L2CAP_DATA_PACKET:
171 att_dispatch_handle_att_pdu(packet_type, channel, packet, size);
172 break;
173 #endif
174 case HCI_EVENT_PACKET:
175 switch (hci_event_packet_get_type(packet)) {
176 case L2CAP_EVENT_CAN_SEND_NOW:
177 att_dispatch_handle_can_send_now(packet, size);
178 break;
179 #ifdef ENABLE_GATT_OVER_CLASSIC
180 case L2CAP_EVENT_INCOMING_CONNECTION:
181 l2cap_event_incoming_connection_get_address(packet, address);
182 l2cap_cid = l2cap_event_incoming_connection_get_local_cid(packet);
183 // reject if outgoing l2cap connection active, L2CAP/TIM/BV-01-C
184 con_handle = l2cap_event_incoming_connection_get_handle(packet);
185 hci_connection = hci_connection_for_handle(con_handle);
186 btstack_assert(hci_connection != NULL);
187 outgoing_active = hci_connection->att_server.l2cap_cid != 0;
188 if (outgoing_active) {
189 hci_connection->att_server.incoming_connection_request = true;
190 l2cap_decline_connection(l2cap_cid);
191 log_info("Decline incoming connection from %s", bd_addr_to_str(address));
192 } else {
193 l2cap_accept_connection(l2cap_cid);
194 log_info("Accept incoming connection from %s", bd_addr_to_str(address));
195 }
196 break;
197 case L2CAP_EVENT_CHANNEL_OPENED:
198 // store l2cap_cid in att_server
199 status = l2cap_event_channel_opened_get_status(packet);
200 con_handle = l2cap_event_channel_opened_get_handle(packet);
201 hci_connection = hci_connection_for_handle(con_handle);
202 if (status == ERROR_CODE_SUCCESS){
203 btstack_assert(hci_connection != NULL);
204 hci_connection->att_server.l2cap_cid = l2cap_event_channel_opened_get_local_cid(packet);
205 } else {
206 if (hci_connection != NULL){
207 hci_connection->att_server.l2cap_cid = 0;
208 }
209 }
210 // dispatch to all roles
211 for (index = 0; index < ATT_MAX; index++){
212 if (subscriptions[index].packet_handler != NULL){
213 subscriptions[index].packet_handler(packet_type, channel, packet, size);
214 }
215 }
216 break;
217 case L2CAP_EVENT_CHANNEL_CLOSED:
218 // clear l2cap_cid in att_server
219 l2cap_cid = l2cap_event_channel_closed_get_local_cid(packet);
220 att_server = att_dispatch_att_server_for_l2cap_cid(l2cap_cid);
221 att_server->l2cap_cid = 0;
222 // dispatch to all roles
223 for (index = 0; index < ATT_MAX; index++){
224 if (subscriptions[index].packet_handler != NULL){
225 subscriptions[index].packet_handler(packet_type, channel, packet, size);
226 }
227 }
228 break;
229 #endif
230 default:
231 break;
232 }
233 break;
234 default:
235 break;
236 }
237 }
238
att_dispatch_register_client(btstack_packet_handler_t packet_handler)239 void att_dispatch_register_client(btstack_packet_handler_t packet_handler){
240 subscriptions[ATT_CLIENT].packet_handler = packet_handler;
241 l2cap_register_fixed_channel(att_packet_handler, L2CAP_CID_ATTRIBUTE_PROTOCOL);
242 }
243
att_dispatch_register_server(btstack_packet_handler_t packet_handler)244 void att_dispatch_register_server(btstack_packet_handler_t packet_handler){
245 subscriptions[ATT_SERVER].packet_handler = packet_handler;
246 l2cap_register_fixed_channel(att_packet_handler, L2CAP_CID_ATTRIBUTE_PROTOCOL);
247 }
248
249 #ifdef ENABLE_GATT_OVER_CLASSIC
att_dispatch_classic_get_l2cap_cid(hci_con_handle_t con_handle)250 static uint16_t att_dispatch_classic_get_l2cap_cid(hci_con_handle_t con_handle){
251 // get l2cap_cid from att_server in hci_connection
252 hci_connection_t * hci_connection = hci_connection_for_handle(con_handle);
253 if (hci_connection != NULL) {
254 return hci_connection->att_server.l2cap_cid;
255 } else {
256 return 0;
257 }
258 }
259 #endif
260
261
att_dispatch_can_send_now(hci_con_handle_t con_handle)262 static bool att_dispatch_can_send_now(hci_con_handle_t con_handle) {
263 #ifdef ENABLE_GATT_OVER_CLASSIC
264 uint16_t l2cap_cid = att_dispatch_classic_get_l2cap_cid(con_handle);
265 if (l2cap_cid != 0){
266 return l2cap_can_send_packet_now(l2cap_cid);
267 }
268 #endif
269 return l2cap_can_send_fixed_channel_packet_now(con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL);
270 }
271
att_dispatch_client_can_send_now(hci_con_handle_t con_handle)272 bool att_dispatch_client_can_send_now(hci_con_handle_t con_handle){
273 return att_dispatch_can_send_now(con_handle);
274 }
275
att_dispatch_server_can_send_now(hci_con_handle_t con_handle)276 bool att_dispatch_server_can_send_now(hci_con_handle_t con_handle){
277 return att_dispatch_can_send_now(con_handle);
278 }
279
att_dispatch_request_can_send_now_event(hci_con_handle_t con_handle,uint8_t type)280 static void att_dispatch_request_can_send_now_event(hci_con_handle_t con_handle, uint8_t type) {
281 #ifdef ENABLE_GATT_OVER_CLASSIC
282 hci_connection_t * hci_connection = hci_connection_for_handle(con_handle);
283 if (hci_connection != NULL) {
284 att_server_t * att_server = &hci_connection->att_server;
285 if (att_server->l2cap_cid != 0){
286 bool send_request_pending = att_server->send_requests[ATT_CLIENT]
287 || att_server->send_requests[ATT_SERVER];
288 att_server->send_requests[type] = true;
289 if (send_request_pending == false){
290 l2cap_request_can_send_now_event(att_server->l2cap_cid);
291 }
292 return;
293 }
294 }
295 #endif
296 subscriptions[type].waiting_for_can_send = true;
297 if (can_send_now_pending == false) {
298 can_send_now_pending = true;
299 l2cap_request_can_send_fix_channel_now_event(con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL);
300 }
301 }
302
att_dispatch_client_request_can_send_now_event(hci_con_handle_t con_handle)303 void att_dispatch_client_request_can_send_now_event(hci_con_handle_t con_handle){
304 att_dispatch_request_can_send_now_event(con_handle, ATT_CLIENT);
305 }
306
att_dispatch_server_request_can_send_now_event(hci_con_handle_t con_handle)307 void att_dispatch_server_request_can_send_now_event(hci_con_handle_t con_handle){
308 att_dispatch_request_can_send_now_event(con_handle, ATT_SERVER);
309 }
310
emit_mtu_exchange_complete(btstack_packet_handler_t packet_handler,hci_con_handle_t con_handle,uint16_t new_mtu)311 static void emit_mtu_exchange_complete(btstack_packet_handler_t packet_handler, hci_con_handle_t con_handle, uint16_t new_mtu){
312 if (!packet_handler) return;
313 uint8_t packet[6];
314 packet[0] = ATT_EVENT_MTU_EXCHANGE_COMPLETE;
315 packet[1] = sizeof(packet) - 2u;
316 little_endian_store_16(packet, 2, con_handle);
317 little_endian_store_16(packet, 4, new_mtu);
318 packet_handler(HCI_EVENT_PACKET, con_handle, packet, 6);
319 }
320
att_dispatch_server_mtu_exchanged(hci_con_handle_t con_handle,uint16_t new_mtu)321 void att_dispatch_server_mtu_exchanged(hci_con_handle_t con_handle, uint16_t new_mtu){
322 emit_mtu_exchange_complete(subscriptions[ATT_CLIENT].packet_handler, con_handle, new_mtu);
323 }
324
att_dispatch_client_mtu_exchanged(hci_con_handle_t con_handle,uint16_t new_mtu)325 void att_dispatch_client_mtu_exchanged(hci_con_handle_t con_handle, uint16_t new_mtu){
326 emit_mtu_exchange_complete(subscriptions[ATT_SERVER].packet_handler, con_handle, new_mtu);
327 }
328
329 #ifdef ENABLE_GATT_OVER_CLASSIC
att_dispatch_classic_register_service(void)330 void att_dispatch_classic_register_service(void){
331 l2cap_register_service(&att_packet_handler, PSM_ATT, 0xffff, gap_get_security_level());
332 }
att_dispatch_classic_connect(bd_addr_t address,uint16_t l2cap_psm,uint16_t * out_cid)333 uint8_t att_dispatch_classic_connect(bd_addr_t address, uint16_t l2cap_psm, uint16_t *out_cid) {
334 uint16_t l2cap_cid;
335 uint8_t status = l2cap_create_channel(&att_packet_handler, address, l2cap_psm, 0xffff, &l2cap_cid);
336 // store l2cap_cid in hci_connection
337 if (status == ERROR_CODE_SUCCESS){
338 hci_connection_t * hci_connection = hci_connection_for_bd_addr_and_type(address, BD_ADDR_TYPE_ACL);
339 if (hci_connection != NULL) {
340 hci_connection->att_server.l2cap_cid = l2cap_cid;
341 hci_connection->att_server.incoming_connection_request = false;
342 }
343 }
344 *out_cid = l2cap_cid;
345 return status;
346 }
347
348 #endif
349