att_server.c (5611a760af48d1ce1beea59c7908be73bd2393f1) att_server.c (f8fbdce0c5067e7e7edd3a29934b1f9b79c8ff2d)
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

--- 89 unchanged lines hidden (view full) ---

98
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;
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

--- 89 unchanged lines hidden (view full) ---

98
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 bt_store_16(event, pos, client_handle);
106 little_endian_store_16(event, pos, client_handle);
107 pos += 2;
107 pos += 2;
108 bt_store_16(event, pos, attribute_handle);
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
113static void att_emit_mtu_event(uint16_t handle, uint16_t mtu){
114
115 if (!att_client_packet_handler) return;
116
117 uint8_t event[6];
118 int pos = 0;
119 event[pos++] = ATT_EVENT_MTU_EXCHANGE_COMPLETE;
120 event[pos++] = sizeof(event) - 2;
109 pos += 2;
110 (*att_client_packet_handler)(HCI_EVENT_PACKET, 0, &event[0], sizeof(event));
111}
112
113static void att_emit_mtu_event(uint16_t handle, uint16_t mtu){
114
115 if (!att_client_packet_handler) return;
116
117 uint8_t event[6];
118 int pos = 0;
119 event[pos++] = ATT_EVENT_MTU_EXCHANGE_COMPLETE;
120 event[pos++] = sizeof(event) - 2;
121 bt_store_16(event, pos, handle);
121 little_endian_store_16(event, pos, handle);
122 pos += 2;
122 pos += 2;
123 bt_store_16(event, pos, mtu);
123 little_endian_store_16(event, pos, mtu);
124 pos += 2;
125 (*att_client_packet_handler)(HCI_EVENT_PACKET, 0, &event[0], sizeof(event));
126}
127
128static void att_handle_value_indication_timeout(btstack_timer_source_t *ts){
129 uint16_t att_handle = att_handle_value_indication_handle;
130 att_handle_value_indication_notify_client(ATT_HANDLE_VALUE_INDICATION_TIMEOUT, att_connection.con_handle, att_handle);
131}

--- 12 unchanged lines hidden (view full) ---

144
145 case HCI_EVENT_LE_META:
146 switch (packet[2]) {
147 case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
148 // store connection info
149 att_client_addr_type = packet[7];
150 bt_flip_addr(att_client_address, &packet[8]);
151 // reset connection properties
124 pos += 2;
125 (*att_client_packet_handler)(HCI_EVENT_PACKET, 0, &event[0], sizeof(event));
126}
127
128static void att_handle_value_indication_timeout(btstack_timer_source_t *ts){
129 uint16_t att_handle = att_handle_value_indication_handle;
130 att_handle_value_indication_notify_client(ATT_HANDLE_VALUE_INDICATION_TIMEOUT, att_connection.con_handle, att_handle);
131}

--- 12 unchanged lines hidden (view full) ---

144
145 case HCI_EVENT_LE_META:
146 switch (packet[2]) {
147 case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
148 // store connection info
149 att_client_addr_type = packet[7];
150 bt_flip_addr(att_client_address, &packet[8]);
151 // reset connection properties
152 att_connection.con_handle = READ_BT_16(packet, 4);
152 att_connection.con_handle = little_endian_read_16(packet, 4);
153 att_connection.mtu = ATT_DEFAULT_MTU;
154 att_connection.max_mtu = l2cap_max_le_mtu();
155 if (att_connection.max_mtu > ATT_REQUEST_BUFFER_SIZE){
156 att_connection.max_mtu = ATT_REQUEST_BUFFER_SIZE;
157 }
158 att_connection.encryption_key_size = 0;
159 att_connection.authenticated = 0;
160 att_connection.authorized = 0;
161 break;
162
163 default:
164 break;
165 }
166 break;
167
168 case HCI_EVENT_ENCRYPTION_CHANGE:
169 case HCI_EVENT_ENCRYPTION_KEY_REFRESH_COMPLETE:
170 // check handle
153 att_connection.mtu = ATT_DEFAULT_MTU;
154 att_connection.max_mtu = l2cap_max_le_mtu();
155 if (att_connection.max_mtu > ATT_REQUEST_BUFFER_SIZE){
156 att_connection.max_mtu = ATT_REQUEST_BUFFER_SIZE;
157 }
158 att_connection.encryption_key_size = 0;
159 att_connection.authenticated = 0;
160 att_connection.authorized = 0;
161 break;
162
163 default:
164 break;
165 }
166 break;
167
168 case HCI_EVENT_ENCRYPTION_CHANGE:
169 case HCI_EVENT_ENCRYPTION_KEY_REFRESH_COMPLETE:
170 // check handle
171 if (att_connection.con_handle != READ_BT_16(packet, 3)) break;
171 if (att_connection.con_handle != little_endian_read_16(packet, 3)) break;
172 att_connection.encryption_key_size = sm_encryption_key_size(att_connection.con_handle);
173 att_connection.authenticated = sm_authenticated(att_connection.con_handle);
174 break;
175
176 case HCI_EVENT_DISCONNECTION_COMPLETE:
177 att_clear_transaction_queue(&att_connection);
178 att_connection.con_handle = 0;
179 att_handle_value_indication_handle = 0; // reset error state
180 // restart advertising if we have been connected before
181 // -> avoid sending advertise enable a second time before command complete was received
182 att_server_state = ATT_SERVER_IDLE;
183 break;
184
185 case SM_EVENT_IDENTITY_RESOLVING_STARTED:
186 log_info("SM_EVENT_IDENTITY_RESOLVING_STARTED");
187 att_ir_lookup_active = 1;
188 break;
189 case SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED:
190 att_ir_lookup_active = 0;
172 att_connection.encryption_key_size = sm_encryption_key_size(att_connection.con_handle);
173 att_connection.authenticated = sm_authenticated(att_connection.con_handle);
174 break;
175
176 case HCI_EVENT_DISCONNECTION_COMPLETE:
177 att_clear_transaction_queue(&att_connection);
178 att_connection.con_handle = 0;
179 att_handle_value_indication_handle = 0; // reset error state
180 // restart advertising if we have been connected before
181 // -> avoid sending advertise enable a second time before command complete was received
182 att_server_state = ATT_SERVER_IDLE;
183 break;
184
185 case SM_EVENT_IDENTITY_RESOLVING_STARTED:
186 log_info("SM_EVENT_IDENTITY_RESOLVING_STARTED");
187 att_ir_lookup_active = 1;
188 break;
189 case SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED:
190 att_ir_lookup_active = 0;
191 att_ir_le_device_db_index = READ_BT_16(packet, 11);
191 att_ir_le_device_db_index = little_endian_read_16(packet, 11);
192 log_info("SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED id %u", att_ir_le_device_db_index);
193 att_run();
194 break;
195 case SM_EVENT_IDENTITY_RESOLVING_FAILED:
196 log_info("SM_EVENT_IDENTITY_RESOLVING_FAILED");
197 att_ir_lookup_active = 0;
198 att_ir_le_device_db_index = -1;
199 att_run();

--- 26 unchanged lines hidden (view full) ---

226 if (memcmp(hash_flipped, &att_request_buffer[att_request_size-8], 8)){
227 log_info("ATT Signed Write, invalid signature");
228 att_server_state = ATT_SERVER_IDLE;
229 return;
230 }
231 log_info("ATT Signed Write, valid signature");
232
233 // update sequence number
192 log_info("SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED id %u", att_ir_le_device_db_index);
193 att_run();
194 break;
195 case SM_EVENT_IDENTITY_RESOLVING_FAILED:
196 log_info("SM_EVENT_IDENTITY_RESOLVING_FAILED");
197 att_ir_lookup_active = 0;
198 att_ir_le_device_db_index = -1;
199 att_run();

--- 26 unchanged lines hidden (view full) ---

226 if (memcmp(hash_flipped, &att_request_buffer[att_request_size-8], 8)){
227 log_info("ATT Signed Write, invalid signature");
228 att_server_state = ATT_SERVER_IDLE;
229 return;
230 }
231 log_info("ATT Signed Write, valid signature");
232
233 // update sequence number
234 uint32_t counter_packet = READ_BT_32(att_request_buffer, att_request_size-12);
234 uint32_t counter_packet = little_endian_read_32(att_request_buffer, att_request_size-12);
235 le_device_db_remote_counter_set(att_ir_le_device_db_index, counter_packet+1);
236 att_server_state = ATT_SERVER_REQUEST_RECEIVED_AND_VALIDATED;
237 att_run();
238}
239
240static void att_run(void){
241 switch (att_server_state){
242 case ATT_SERVER_IDLE:

--- 17 unchanged lines hidden (view full) ---

260 }
261 if (att_ir_le_device_db_index < 0){
262 log_info("ATT Signed Write, CSRK not available");
263 att_server_state = ATT_SERVER_IDLE;
264 return;
265 }
266
267 // check counter
235 le_device_db_remote_counter_set(att_ir_le_device_db_index, counter_packet+1);
236 att_server_state = ATT_SERVER_REQUEST_RECEIVED_AND_VALIDATED;
237 att_run();
238}
239
240static void att_run(void){
241 switch (att_server_state){
242 case ATT_SERVER_IDLE:

--- 17 unchanged lines hidden (view full) ---

260 }
261 if (att_ir_le_device_db_index < 0){
262 log_info("ATT Signed Write, CSRK not available");
263 att_server_state = ATT_SERVER_IDLE;
264 return;
265 }
266
267 // check counter
268 uint32_t counter_packet = READ_BT_32(att_request_buffer, att_request_size-12);
268 uint32_t counter_packet = little_endian_read_32(att_request_buffer, att_request_size-12);
269 uint32_t counter_db = le_device_db_remote_counter_get(att_ir_le_device_db_index);
270 log_info("ATT Signed Write, DB counter %"PRIu32", packet counter %"PRIu32, counter_db, counter_packet);
271 if (counter_packet < counter_db){
272 log_info("ATT Signed Write, db reports higher counter, abort");
273 att_server_state = ATT_SERVER_IDLE;
274 return;
275 }
276
277 // signature is { sequence counter, secure hash }
278 sm_key_t csrk;
279 le_device_db_remote_csrk_get(att_ir_le_device_db_index, csrk);
280 att_server_state = ATT_SERVER_W4_SIGNED_WRITE_VALIDATION;
281 log_info("Orig Signature: ");
282 hexdump( &att_request_buffer[att_request_size-8], 8);
269 uint32_t counter_db = le_device_db_remote_counter_get(att_ir_le_device_db_index);
270 log_info("ATT Signed Write, DB counter %"PRIu32", packet counter %"PRIu32, counter_db, counter_packet);
271 if (counter_packet < counter_db){
272 log_info("ATT Signed Write, db reports higher counter, abort");
273 att_server_state = ATT_SERVER_IDLE;
274 return;
275 }
276
277 // signature is { sequence counter, secure hash }
278 sm_key_t csrk;
279 le_device_db_remote_csrk_get(att_ir_le_device_db_index, csrk);
280 att_server_state = ATT_SERVER_W4_SIGNED_WRITE_VALIDATION;
281 log_info("Orig Signature: ");
282 hexdump( &att_request_buffer[att_request_size-8], 8);
283 uint16_t attribute_handle = READ_BT_16(att_request_buffer, 1);
283 uint16_t attribute_handle = little_endian_read_16(att_request_buffer, 1);
284 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);
285 return;
286 }
287 // NOTE: fall through for regular commands
288
289 case ATT_SERVER_REQUEST_RECEIVED_AND_VALIDATED:
290 if (!l2cap_can_send_fixed_channel_packet_now(att_connection.con_handle)) return;
291

--- 113 unchanged lines hidden ---
284 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);
285 return;
286 }
287 // NOTE: fall through for regular commands
288
289 case ATT_SERVER_REQUEST_RECEIVED_AND_VALIDATED:
290 if (!l2cap_can_send_fixed_channel_packet_now(att_connection.con_handle)) return;
291

--- 113 unchanged lines hidden ---