xref: /btstack/src/ble/att_server.c (revision 423c667c13e0fb5d595b3640a5d1a44fbdf8d998)
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 MATTHIAS
24  * RINGWALD 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 
39 //
40 // ATT Server Globals
41 //
42 
43 #include <stdint.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <inttypes.h>
48 
49 #include "btstack_config.h"
50 
51 #include "att_dispatch.h"
52 #include "ble/att_db.h"
53 #include "ble/att_server.h"
54 #include "ble/core.h"
55 #include "ble/le_device_db.h"
56 #include "ble/sm.h"
57 #include "btstack_debug.h"
58 #include "btstack_event.h"
59 #include "btstack_memory.h"
60 #include "btstack_run_loop.h"
61 #include "gap.h"
62 #include "hci.h"
63 #include "hci_dump.h"
64 #include "l2cap.h"
65 
66 static void att_run(void);
67 
68 // max ATT request matches L2CAP PDU -- allow to use smaller buffer
69 #ifndef ATT_REQUEST_BUFFER_SIZE
70 #define ATT_REQUEST_BUFFER_SIZE HCI_ACL_PAYLOAD_SIZE
71 #endif
72 
73 typedef enum {
74     ATT_SERVER_IDLE,
75     ATT_SERVER_REQUEST_RECEIVED,
76     ATT_SERVER_W4_SIGNED_WRITE_VALIDATION,
77     ATT_SERVER_REQUEST_RECEIVED_AND_VALIDATED,
78 } att_server_state_t;
79 
80 static att_connection_t att_connection;
81 static att_server_state_t att_server_state;
82 
83 static uint8_t   att_client_addr_type;
84 static bd_addr_t att_client_address;
85 static uint8_t   att_client_waiting_for_can_send;
86 static uint16_t  att_request_size   = 0;
87 static uint8_t   att_request_buffer[ATT_REQUEST_BUFFER_SIZE];
88 
89 static int       att_ir_le_device_db_index = -1;
90 static int       att_ir_lookup_active = 0;
91 
92 static int       att_handle_value_indication_handle = 0;
93 static btstack_timer_source_t att_handle_value_indication_timer;
94 static btstack_packet_callback_registration_t hci_event_callback_registration;
95 static btstack_packet_callback_registration_t sm_event_callback_registration;
96 static btstack_packet_handler_t att_client_packet_handler = NULL;
97 
98 static void att_handle_value_indication_notify_client(uint8_t status, uint16_t client_handle, uint16_t attribute_handle){
99     if (!att_client_packet_handler) return;
100 
101     uint8_t event[7];
102     int pos = 0;
103     event[pos++] = ATT_EVENT_HANDLE_VALUE_INDICATION_COMPLETE;
104     event[pos++] = sizeof(event) - 2;
105     event[pos++] = status;
106     little_endian_store_16(event, pos, client_handle);
107     pos += 2;
108     little_endian_store_16(event, pos, attribute_handle);
109     pos += 2;
110     (*att_client_packet_handler)(HCI_EVENT_PACKET, 0, &event[0], sizeof(event));
111 }
112 
113 static void att_emit_mtu_event(hci_con_handle_t con_handle, uint16_t mtu){
114     if (!att_client_packet_handler) return;
115 
116     uint8_t event[6];
117     int pos = 0;
118     event[pos++] = ATT_EVENT_MTU_EXCHANGE_COMPLETE;
119     event[pos++] = sizeof(event) - 2;
120     little_endian_store_16(event, pos, con_handle);
121     pos += 2;
122     little_endian_store_16(event, pos, mtu);
123     pos += 2;
124     (*att_client_packet_handler)(HCI_EVENT_PACKET, 0, &event[0], sizeof(event));
125 }
126 
127 static void att_emit_can_send_now_event(void){
128     if (att_client_packet_handler) return;
129     uint8_t event[] = { ATT_EVENT_CAN_SEND_NOW, 0};
130     (*att_client_packet_handler)(HCI_EVENT_PACKET, 0, &event[0], sizeof(event));
131 }
132 
133 static void att_server_notify_can_send(void){
134     if (att_connection.con_handle == 0) return;
135     if (!att_client_waiting_for_can_send) return;
136     if (!att_dispatch_server_can_send_now(att_connection.con_handle)) return;
137 
138     att_client_waiting_for_can_send = 0;
139     att_emit_can_send_now_event();
140 }
141 
142 static void att_handle_value_indication_timeout(btstack_timer_source_t *ts){
143     uint16_t att_handle = att_handle_value_indication_handle;
144     att_handle_value_indication_notify_client(ATT_HANDLE_VALUE_INDICATION_TIMEOUT, att_connection.con_handle, att_handle);
145 }
146 
147 static void att_event_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
148 
149     bd_addr_t event_address;
150     switch (packet_type) {
151 
152         case HCI_EVENT_PACKET:
153             switch (hci_event_packet_get_type(packet)) {
154 
155                 case L2CAP_EVENT_CAN_SEND_NOW:
156                     att_run();
157                     // if we cannot send now, we'll get another l2cap can send now soon
158                     att_server_notify_can_send();
159                     break;
160 
161                 case HCI_EVENT_LE_META:
162                     switch (packet[2]) {
163                         case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
164                         	// store connection info
165                         	att_client_addr_type = packet[7];
166                             reverse_bd_addr(&packet[8], att_client_address);
167                             // reset connection properties
168                             att_connection.con_handle = little_endian_read_16(packet, 4);
169                             att_connection.mtu = ATT_DEFAULT_MTU;
170                             att_connection.max_mtu = l2cap_max_le_mtu();
171                             if (att_connection.max_mtu > ATT_REQUEST_BUFFER_SIZE){
172                                 att_connection.max_mtu = ATT_REQUEST_BUFFER_SIZE;
173                             }
174                             att_connection.encryption_key_size = 0;
175                             att_connection.authenticated = 0;
176 		                	att_connection.authorized = 0;
177                             break;
178 
179                         default:
180                             break;
181                     }
182                     break;
183 
184                 case HCI_EVENT_ENCRYPTION_CHANGE:
185                 case HCI_EVENT_ENCRYPTION_KEY_REFRESH_COMPLETE:
186                 	// check handle
187                 	if (att_connection.con_handle != little_endian_read_16(packet, 3)) break;
188                 	att_connection.encryption_key_size = sm_encryption_key_size(att_connection.con_handle);
189                 	att_connection.authenticated = sm_authenticated(att_connection.con_handle);
190                 	break;
191 
192                 case HCI_EVENT_DISCONNECTION_COMPLETE:
193                     att_clear_transaction_queue(&att_connection);
194                     att_connection.con_handle = 0;
195                     att_handle_value_indication_handle = 0; // reset error state
196                     // restart advertising if we have been connected before
197                     // -> avoid sending advertise enable a second time before command complete was received
198                     att_server_state = ATT_SERVER_IDLE;
199                     break;
200 
201                 case SM_EVENT_IDENTITY_RESOLVING_STARTED:
202                     log_info("SM_EVENT_IDENTITY_RESOLVING_STARTED");
203                     att_ir_lookup_active = 1;
204                     break;
205                 case SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED:
206                     att_ir_lookup_active = 0;
207                     att_ir_le_device_db_index = little_endian_read_16(packet, 11);
208                     log_info("SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED id %u", att_ir_le_device_db_index);
209                     att_run();
210                     break;
211                 case SM_EVENT_IDENTITY_RESOLVING_FAILED:
212                     log_info("SM_EVENT_IDENTITY_RESOLVING_FAILED");
213                     att_ir_lookup_active = 0;
214                     att_ir_le_device_db_index = -1;
215                     att_run();
216                     break;
217                 case SM_EVENT_AUTHORIZATION_RESULT: {
218                     if (packet[4] != att_client_addr_type) break;
219                     reverse_bd_addr(&packet[5], event_address);
220                     if (memcmp(event_address, att_client_address, 6) != 0) break;
221                     att_connection.authorized = packet[11];
222                     att_run();
223                 	break;
224                 }
225                 default:
226                     break;
227             }
228             break;
229         default:
230             break;
231     }
232 }
233 
234 static void att_signed_write_handle_cmac_result(uint8_t hash[8]){
235 
236     if (att_server_state != ATT_SERVER_W4_SIGNED_WRITE_VALIDATION) return;
237 
238     uint8_t hash_flipped[8];
239     reverse_64(hash, hash_flipped);
240     if (memcmp(hash_flipped, &att_request_buffer[att_request_size-8], 8)){
241         log_info("ATT Signed Write, invalid signature");
242         att_server_state = ATT_SERVER_IDLE;
243         return;
244     }
245     log_info("ATT Signed Write, valid signature");
246 
247     // update sequence number
248     uint32_t counter_packet = little_endian_read_32(att_request_buffer, att_request_size-12);
249     le_device_db_remote_counter_set(att_ir_le_device_db_index, counter_packet+1);
250     att_server_state = ATT_SERVER_REQUEST_RECEIVED_AND_VALIDATED;
251     att_run();
252 }
253 
254 static void att_run(void){
255     switch (att_server_state){
256         case ATT_SERVER_IDLE:
257         case ATT_SERVER_W4_SIGNED_WRITE_VALIDATION:
258             return;
259         case ATT_SERVER_REQUEST_RECEIVED:
260             if (att_request_buffer[0] == ATT_SIGNED_WRITE_COMMAND){
261                 log_info("ATT Signed Write!");
262                 if (!sm_cmac_ready()) {
263                     log_info("ATT Signed Write, sm_cmac engine not ready. Abort");
264                     att_server_state = ATT_SERVER_IDLE;
265                      return;
266                 }
267                 if (att_request_size < (3 + 12)) {
268                     log_info("ATT Signed Write, request to short. Abort.");
269                     att_server_state = ATT_SERVER_IDLE;
270                     return;
271                 }
272                 if (att_ir_lookup_active){
273                     return;
274                 }
275                 if (att_ir_le_device_db_index < 0){
276                     log_info("ATT Signed Write, CSRK not available");
277                     att_server_state = ATT_SERVER_IDLE;
278                     return;
279                 }
280 
281                 // check counter
282                 uint32_t counter_packet = little_endian_read_32(att_request_buffer, att_request_size-12);
283                 uint32_t counter_db     = le_device_db_remote_counter_get(att_ir_le_device_db_index);
284                 log_info("ATT Signed Write, DB counter %"PRIu32", packet counter %"PRIu32, counter_db, counter_packet);
285                 if (counter_packet < counter_db){
286                     log_info("ATT Signed Write, db reports higher counter, abort");
287                     att_server_state = ATT_SERVER_IDLE;
288                     return;
289                 }
290 
291                 // signature is { sequence counter, secure hash }
292                 sm_key_t csrk;
293                 le_device_db_remote_csrk_get(att_ir_le_device_db_index, csrk);
294                 att_server_state = ATT_SERVER_W4_SIGNED_WRITE_VALIDATION;
295                 log_info("Orig Signature: ");
296                 log_info_hexdump( &att_request_buffer[att_request_size-8], 8);
297                 uint16_t attribute_handle = little_endian_read_16(att_request_buffer, 1);
298                 sm_cmac_start(csrk, att_request_buffer[0], attribute_handle, att_request_size - 15, &att_request_buffer[3], counter_packet, att_signed_write_handle_cmac_result);
299                 return;
300             }
301             // NOTE: fall through for regular commands
302 
303         case ATT_SERVER_REQUEST_RECEIVED_AND_VALIDATED:
304             if (!att_dispatch_server_can_send_now(att_connection.con_handle)) return;
305 
306             l2cap_reserve_packet_buffer();
307             uint8_t * att_response_buffer = l2cap_get_outgoing_buffer();
308             uint16_t  att_response_size   = att_handle_request(&att_connection, att_request_buffer, att_request_size, att_response_buffer);
309 
310             // intercept "insufficient authorization" for authenticated connections to allow for user authorization
311             if ((att_response_size     >= 4)
312             && (att_response_buffer[0] == ATT_ERROR_RESPONSE)
313             && (att_response_buffer[4] == ATT_ERROR_INSUFFICIENT_AUTHORIZATION)
314             && (att_connection.authenticated)){
315 
316             	switch (sm_authorization_state(att_connection.con_handle)){
317             		case AUTHORIZATION_UNKNOWN:
318                         l2cap_release_packet_buffer();
319 		             	sm_request_pairing(att_connection.con_handle);
320 	    		        return;
321 	    		    case AUTHORIZATION_PENDING:
322                         l2cap_release_packet_buffer();
323 	    		    	return;
324 	    		    default:
325 	    		    	break;
326             	}
327             }
328 
329             att_server_state = ATT_SERVER_IDLE;
330             if (att_response_size == 0) {
331                 l2cap_release_packet_buffer();
332                 return;
333             }
334 
335             l2cap_send_prepared_connectionless(att_connection.con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, att_response_size);
336 
337             // notify client about MTU exchange result
338             if (att_response_buffer[0] == ATT_EXCHANGE_MTU_RESPONSE){
339                 att_emit_mtu_event(att_connection.con_handle, att_connection.mtu);
340             }
341 
342             break;
343     }
344 }
345 
346 static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){
347     switch (packet_type){
348         case HCI_EVENT_PACKET:
349             if (packet[0] != L2CAP_EVENT_CAN_SEND_NOW) break;
350             att_run();
351             break;
352 
353         case ATT_DATA_PACKET:
354             // handle value indication confirms
355             if (packet[0] == ATT_HANDLE_VALUE_CONFIRMATION && att_handle_value_indication_handle){
356                 btstack_run_loop_remove_timer(&att_handle_value_indication_timer);
357                 uint16_t att_handle = att_handle_value_indication_handle;
358                 att_handle_value_indication_handle = 0;
359                 att_handle_value_indication_notify_client(0, att_connection.con_handle, att_handle);
360                 return;
361             }
362 
363             // directly process command
364             // note: signed write cannot be handled directly as authentication needs to be verified
365             if (packet[0] == ATT_WRITE_COMMAND){
366                 att_handle_request(&att_connection, packet, size, 0);
367                 return;
368             }
369 
370             // check size
371             if (size > sizeof(att_request_buffer)) {
372                 log_info("att_packet_handler: dropping att pdu 0x%02x as size %u > att_request_buffer %u", packet[0], size, (int) sizeof(att_request_buffer));
373                 return;
374             }
375 
376             // last request still in processing?
377             if (att_server_state != ATT_SERVER_IDLE){
378                 log_info("att_packet_handler: skipping att pdu 0x%02x as server not idle (state %u)", packet[0], att_server_state);
379                 return;
380             }
381 
382             // store request
383             att_server_state = ATT_SERVER_REQUEST_RECEIVED;
384             att_request_size = size;
385             memcpy(att_request_buffer, packet, size);
386 
387             att_run();
388             break;
389     }
390 }
391 
392 void att_server_init(uint8_t const * db, att_read_callback_t read_callback, att_write_callback_t write_callback){
393 
394     // register for HCI Events
395     hci_event_callback_registration.callback = &att_event_packet_handler;
396     hci_add_event_handler(&hci_event_callback_registration);
397 
398     // register for SM events
399     sm_event_callback_registration.callback = &att_event_packet_handler;
400     sm_add_event_handler(&sm_event_callback_registration);
401 
402     // and L2CAP ATT Server PDUs
403     att_dispatch_register_server(att_packet_handler);
404 
405     att_server_state = ATT_SERVER_IDLE;
406     att_set_db(db);
407     att_set_read_callback(read_callback);
408     att_set_write_callback(write_callback);
409 
410 }
411 
412 void att_server_register_packet_handler(btstack_packet_handler_t handler){
413     att_client_packet_handler = handler;
414 }
415 
416 int  att_server_can_send_packet_now(void){
417 	if (att_connection.con_handle == 0) return 0;
418 	int can_send = att_dispatch_server_can_send_now(att_connection.con_handle);
419     if (!can_send){
420         att_client_waiting_for_can_send = 1;
421     }
422     return can_send;
423 }
424 
425 void att_server_request_can_send_now_event(){
426     att_client_waiting_for_can_send = 1;
427     att_server_notify_can_send();
428 }
429 
430 int att_server_notify(uint16_t attribute_handle, uint8_t *value, uint16_t value_len){
431     if (!att_dispatch_server_can_send_now(att_connection.con_handle)) return BTSTACK_ACL_BUFFERS_FULL;
432 
433     l2cap_reserve_packet_buffer();
434     uint8_t * packet_buffer = l2cap_get_outgoing_buffer();
435     uint16_t size = att_prepare_handle_value_notification(&att_connection, attribute_handle, value, value_len, packet_buffer);
436 	return l2cap_send_prepared_connectionless(att_connection.con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, size);
437 }
438 
439 int att_server_indicate(uint16_t attribute_handle, uint8_t *value, uint16_t value_len){
440     if (att_handle_value_indication_handle) return ATT_HANDLE_VALUE_INDICATION_IN_PORGRESS;
441     if (!att_dispatch_server_can_send_now(att_connection.con_handle)) return BTSTACK_ACL_BUFFERS_FULL;
442 
443     // track indication
444     att_handle_value_indication_handle = attribute_handle;
445     btstack_run_loop_set_timer_handler(&att_handle_value_indication_timer, att_handle_value_indication_timeout);
446     btstack_run_loop_set_timer(&att_handle_value_indication_timer, ATT_TRANSACTION_TIMEOUT_MS);
447     btstack_run_loop_add_timer(&att_handle_value_indication_timer);
448 
449     l2cap_reserve_packet_buffer();
450     uint8_t * packet_buffer = l2cap_get_outgoing_buffer();
451     uint16_t size = att_prepare_handle_value_indication(&att_connection, attribute_handle, value, value_len, packet_buffer);
452 	l2cap_send_prepared_connectionless(att_connection.con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, size);
453     return 0;
454 }
455