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