att_server.c (bce48a26559b983f222efb64ec1cede436ab446e) att_server.c (5d07396b2432226952ea1e16305d745278a64416)
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

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

70#endif
71
72#ifndef NVN_NUM_GATT_SERVER_CCC
73#define NVN_NUM_GATT_SERVER_CCC 20
74#endif
75
76static void att_run_for_context(att_server_t * att_server);
77static att_write_callback_t att_server_write_callback_for_handle(uint16_t handle);
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

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

70#endif
71
72#ifndef NVN_NUM_GATT_SERVER_CCC
73#define NVN_NUM_GATT_SERVER_CCC 20
74#endif
75
76static void att_run_for_context(att_server_t * att_server);
77static att_write_callback_t att_server_write_callback_for_handle(uint16_t handle);
78static btstack_packet_handler_t att_server_packet_handler_for_handle(uint16_t handle);
78static void att_server_persistent_ccc_restore(att_server_t * att_server);
79static void att_server_persistent_ccc_clear(att_server_t * att_server);
80
81typedef enum {
82 ATT_SERVER_RUN_PHASE_1_REQUESTS,
83 ATT_SERVER_RUN_PHASE_2_INDICATIONS,
84 ATT_SERVER_RUN_PHASE_3_NOTIFICATIONS,
85} att_server_run_phase_t;

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

120 att_server_t * att_server = &connection->att_server;
121 if (att_server->state == state) return att_server;
122 }
123 return NULL;
124}
125#endif
126
127static void att_handle_value_indication_notify_client(uint8_t status, uint16_t client_handle, uint16_t attribute_handle){
79static void att_server_persistent_ccc_restore(att_server_t * att_server);
80static void att_server_persistent_ccc_clear(att_server_t * att_server);
81
82typedef enum {
83 ATT_SERVER_RUN_PHASE_1_REQUESTS,
84 ATT_SERVER_RUN_PHASE_2_INDICATIONS,
85 ATT_SERVER_RUN_PHASE_3_NOTIFICATIONS,
86} att_server_run_phase_t;

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

121 att_server_t * att_server = &connection->att_server;
122 if (att_server->state == state) return att_server;
123 }
124 return NULL;
125}
126#endif
127
128static void att_handle_value_indication_notify_client(uint8_t status, uint16_t client_handle, uint16_t attribute_handle){
128 if (!att_client_packet_handler) return;
129 btstack_packet_handler_t packet_handler = att_server_packet_handler_for_handle(attribute_handle);
130 if (!packet_handler) return;
129
130 uint8_t event[7];
131 int pos = 0;
132 event[pos++] = ATT_EVENT_HANDLE_VALUE_INDICATION_COMPLETE;
133 event[pos++] = sizeof(event) - 2;
134 event[pos++] = status;
135 little_endian_store_16(event, pos, client_handle);
136 pos += 2;
137 little_endian_store_16(event, pos, attribute_handle);
138 (*att_client_packet_handler)(HCI_EVENT_PACKET, 0, &event[0], sizeof(event));
139}
140
131
132 uint8_t event[7];
133 int pos = 0;
134 event[pos++] = ATT_EVENT_HANDLE_VALUE_INDICATION_COMPLETE;
135 event[pos++] = sizeof(event) - 2;
136 event[pos++] = status;
137 little_endian_store_16(event, pos, client_handle);
138 pos += 2;
139 little_endian_store_16(event, pos, attribute_handle);
140 (*att_client_packet_handler)(HCI_EVENT_PACKET, 0, &event[0], sizeof(event));
141}
142
141static void att_emit_mtu_event(hci_con_handle_t con_handle, uint16_t mtu){
142 if (!att_client_packet_handler) return;
143static void att_emit_event_to_all(const uint8_t * event, uint16_t size){
144 // dispatch to app level handler
145 if (att_client_packet_handler){
146 (*att_client_packet_handler)(HCI_EVENT_PACKET, 0, (uint8_t*) event, size);
147 }
143
148
149 // dispatch to service handlers
150 btstack_linked_list_iterator_t it;
151 btstack_linked_list_iterator_init(&it, &service_handlers);
152 while (btstack_linked_list_iterator_has_next(&it)){
153 att_service_handler_t * handler = (att_service_handler_t*) btstack_linked_list_iterator_next(&it);
154 if (!handler->packet_handler) continue;
155 (*handler->packet_handler)(HCI_EVENT_PACKET, 0, (uint8_t*) event, size);
156 }
157}
158
159static void att_emit_mtu_event(hci_con_handle_t con_handle, uint16_t mtu){
144 uint8_t event[6];
145 int pos = 0;
146 event[pos++] = ATT_EVENT_MTU_EXCHANGE_COMPLETE;
147 event[pos++] = sizeof(event) - 2;
148 little_endian_store_16(event, pos, con_handle);
149 pos += 2;
150 little_endian_store_16(event, pos, mtu);
160 uint8_t event[6];
161 int pos = 0;
162 event[pos++] = ATT_EVENT_MTU_EXCHANGE_COMPLETE;
163 event[pos++] = sizeof(event) - 2;
164 little_endian_store_16(event, pos, con_handle);
165 pos += 2;
166 little_endian_store_16(event, pos, mtu);
167
168 // also dispatch to GATT Clients
151 att_dispatch_server_mtu_exchanged(con_handle, mtu);
169 att_dispatch_server_mtu_exchanged(con_handle, mtu);
152 (*att_client_packet_handler)(HCI_EVENT_PACKET, 0, &event[0], sizeof(event));
170
171 // dispatch to app level handler and service handlers
172 att_emit_event_to_all(&event[0], sizeof(event));
153}
154
155static void att_emit_can_send_now_event(void * context){
156 UNUSED(context);
157 if (!att_client_packet_handler) return;
158
159 uint8_t event[] = { ATT_EVENT_CAN_SEND_NOW, 0};
160 (*att_client_packet_handler)(HCI_EVENT_PACKET, 0, &event[0], sizeof(event));

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

202 att_server->connection.max_mtu = ATT_REQUEST_BUFFER_SIZE;
203 }
204 att_server->connection.encryption_key_size = 0;
205 att_server->connection.authenticated = 0;
206 att_server->connection.authorized = 0;
207 // workaround: identity resolving can already be complete, at least store result
208 att_server->ir_le_device_db_index = sm_le_device_index(con_handle);
209 att_server->pairing_active = 0;
173}
174
175static void att_emit_can_send_now_event(void * context){
176 UNUSED(context);
177 if (!att_client_packet_handler) return;
178
179 uint8_t event[] = { ATT_EVENT_CAN_SEND_NOW, 0};
180 (*att_client_packet_handler)(HCI_EVENT_PACKET, 0, &event[0], sizeof(event));

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

222 att_server->connection.max_mtu = ATT_REQUEST_BUFFER_SIZE;
223 }
224 att_server->connection.encryption_key_size = 0;
225 att_server->connection.authenticated = 0;
226 att_server->connection.authorized = 0;
227 // workaround: identity resolving can already be complete, at least store result
228 att_server->ir_le_device_db_index = sm_le_device_index(con_handle);
229 att_server->pairing_active = 0;
230 // notify all
231 att_emit_event_to_all(packet, size);
210 break;
211
212 default:
213 break;
214 }
215 break;
216
217 case HCI_EVENT_ENCRYPTION_CHANGE:

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

240 att_server->connection.con_handle = 0;
241 att_server->pairing_active = 0;
242 att_server->state = ATT_SERVER_IDLE;
243 if (att_server->value_indication_handle){
244 uint16_t att_handle = att_server->value_indication_handle;
245 att_server->value_indication_handle = 0; // reset error state
246 att_handle_value_indication_notify_client(ATT_HANDLE_VALUE_INDICATION_DISCONNECT, att_server->connection.con_handle, att_handle);
247 }
232 break;
233
234 default:
235 break;
236 }
237 break;
238
239 case HCI_EVENT_ENCRYPTION_CHANGE:

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

262 att_server->connection.con_handle = 0;
263 att_server->pairing_active = 0;
264 att_server->state = ATT_SERVER_IDLE;
265 if (att_server->value_indication_handle){
266 uint16_t att_handle = att_server->value_indication_handle;
267 att_server->value_indication_handle = 0; // reset error state
268 att_handle_value_indication_notify_client(ATT_HANDLE_VALUE_INDICATION_DISCONNECT, att_server->connection.con_handle, att_handle);
269 }
270 // notify all
271 att_emit_event_to_all(packet, size);
248 break;
249
250 // Identity Resolving
251 case SM_EVENT_IDENTITY_RESOLVING_STARTED:
252 con_handle = sm_event_identity_resolving_started_get_handle(packet);
253 att_server = att_server_for_handle(con_handle);
254 if (!att_server) break;
255 log_info("SM_EVENT_IDENTITY_RESOLVING_STARTED");

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

822}
823
824static att_write_callback_t att_server_write_callback_for_handle(uint16_t handle){
825 att_service_handler_t * handler = att_service_handler_for_handle(handle);
826 if (handler) return handler->write_callback;
827 return att_server_client_write_callback;
828}
829
272 break;
273
274 // Identity Resolving
275 case SM_EVENT_IDENTITY_RESOLVING_STARTED:
276 con_handle = sm_event_identity_resolving_started_get_handle(packet);
277 att_server = att_server_for_handle(con_handle);
278 if (!att_server) break;
279 log_info("SM_EVENT_IDENTITY_RESOLVING_STARTED");

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

846}
847
848static att_write_callback_t att_server_write_callback_for_handle(uint16_t handle){
849 att_service_handler_t * handler = att_service_handler_for_handle(handle);
850 if (handler) return handler->write_callback;
851 return att_server_client_write_callback;
852}
853
854static btstack_packet_handler_t att_server_packet_handler_for_handle(uint16_t handle){
855 att_service_handler_t * handler = att_service_handler_for_handle(handle);
856 if (handler) return handler->packet_handler;
857 return att_client_packet_handler;
858}
859
830static void att_notify_write_callbacks(hci_con_handle_t con_handle, uint16_t transaction_mode){
831 // notify all callbacks
832 btstack_linked_list_iterator_t it;
833 btstack_linked_list_iterator_init(&it, &service_handlers);
834 while (btstack_linked_list_iterator_has_next(&it)){
835 att_service_handler_t * handler = (att_service_handler_t*) btstack_linked_list_iterator_next(&it);
836 if (!handler->write_callback) continue;
837 (*handler->write_callback)(con_handle, 0, transaction_mode, 0, NULL, 0);

--- 150 unchanged lines hidden ---
860static void att_notify_write_callbacks(hci_con_handle_t con_handle, uint16_t transaction_mode){
861 // notify all callbacks
862 btstack_linked_list_iterator_t it;
863 btstack_linked_list_iterator_init(&it, &service_handlers);
864 while (btstack_linked_list_iterator_has_next(&it)){
865 att_service_handler_t * handler = (att_service_handler_t*) btstack_linked_list_iterator_next(&it);
866 if (!handler->write_callback) continue;
867 (*handler->write_callback)(con_handle, 0, transaction_mode, 0, NULL, 0);

--- 150 unchanged lines hidden ---