att_server.c (85878f9d1f78048061b66c447a981d399c90b557) att_server.c (c61037cc77c8186ed1a8cb389419343a0c648995)
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

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

72#ifdef ENABLE_TESTING_SUPPORT
73#include <stdio.h>
74#endif
75
76#ifndef NVN_NUM_GATT_SERVER_CCC
77#define NVN_NUM_GATT_SERVER_CCC 20
78#endif
79
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

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

72#ifdef ENABLE_TESTING_SUPPORT
73#include <stdio.h>
74#endif
75
76#ifndef NVN_NUM_GATT_SERVER_CCC
77#define NVN_NUM_GATT_SERVER_CCC 20
78#endif
79
80#define ATT_SERVICE_FLAGS_DELAYED_RESPONSE (1<<0u)
81
80static void att_run_for_context(att_server_t * att_server, att_connection_t * att_connection);
81static att_write_callback_t att_server_write_callback_for_handle(uint16_t handle);
82static btstack_packet_handler_t att_server_packet_handler_for_handle(uint16_t handle);
83static void att_server_handle_can_send_now(void);
84static void att_server_persistent_ccc_restore(att_server_t * att_server, att_connection_t * att_connection);
85static void att_server_persistent_ccc_clear(att_server_t * att_server);
86static void att_server_handle_att_pdu(att_server_t * att_server, att_connection_t * att_connection, uint8_t * packet, uint16_t size);
87

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

107static btstack_context_callback_registration_t att_client_waiting_for_can_send_registration;
108
109static att_read_callback_t att_server_client_read_callback;
110static att_write_callback_t att_server_client_write_callback;
111
112// round robin
113static hci_con_handle_t att_server_last_can_send_now = HCI_CON_HANDLE_INVALID;
114
82static void att_run_for_context(att_server_t * att_server, att_connection_t * att_connection);
83static att_write_callback_t att_server_write_callback_for_handle(uint16_t handle);
84static btstack_packet_handler_t att_server_packet_handler_for_handle(uint16_t handle);
85static void att_server_handle_can_send_now(void);
86static void att_server_persistent_ccc_restore(att_server_t * att_server, att_connection_t * att_connection);
87static void att_server_persistent_ccc_clear(att_server_t * att_server);
88static void att_server_handle_att_pdu(att_server_t * att_server, att_connection_t * att_connection, uint8_t * packet, uint16_t size);
89

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

109static btstack_context_callback_registration_t att_client_waiting_for_can_send_registration;
110
111static att_read_callback_t att_server_client_read_callback;
112static att_write_callback_t att_server_client_write_callback;
113
114// round robin
115static hci_con_handle_t att_server_last_can_send_now = HCI_CON_HANDLE_INVALID;
116
117static uint8_t att_server_flags;
118
115#ifdef ENABLE_GATT_OVER_EATT
116typedef struct {
117 btstack_linked_item_t item;
118 att_server_t att_server;
119 att_connection_t att_connection;
120 uint8_t * receive_buffer;
121 uint8_t * send_buffer;
122} att_server_eatt_bearer_t;

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

582
583#ifdef ENABLE_ATT_DELAYED_RESPONSE
584 if ((att_response_size == ATT_READ_RESPONSE_PENDING) || (att_response_size == ATT_INTERNAL_WRITE_RESPONSE_PENDING)){
585 // update state
586 att_server->state = ATT_SERVER_RESPONSE_PENDING;
587
588 // callback with handle ATT_READ_RESPONSE_PENDING for reads
589 if (att_response_size == ATT_READ_RESPONSE_PENDING){
119#ifdef ENABLE_GATT_OVER_EATT
120typedef struct {
121 btstack_linked_item_t item;
122 att_server_t att_server;
123 att_connection_t att_connection;
124 uint8_t * receive_buffer;
125 uint8_t * send_buffer;
126} att_server_eatt_bearer_t;

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

586
587#ifdef ENABLE_ATT_DELAYED_RESPONSE
588 if ((att_response_size == ATT_READ_RESPONSE_PENDING) || (att_response_size == ATT_INTERNAL_WRITE_RESPONSE_PENDING)){
589 // update state
590 att_server->state = ATT_SERVER_RESPONSE_PENDING;
591
592 // callback with handle ATT_READ_RESPONSE_PENDING for reads
593 if (att_response_size == ATT_READ_RESPONSE_PENDING){
590 att_server_client_read_callback(att_connection->con_handle, ATT_READ_RESPONSE_PENDING, 0, NULL, 0);
594 // notify services that returned response pending
595 btstack_linked_list_iterator_t it;
596 btstack_linked_list_iterator_init(&it, &service_handlers);
597 while (btstack_linked_list_iterator_has_next(&it)) {
598 att_service_handler_t *handler = (att_service_handler_t *) btstack_linked_list_iterator_next(&it);
599 if ((handler->flags & ATT_SERVICE_FLAGS_DELAYED_RESPONSE) != 0){
600 handler->flags &= ~ATT_SERVICE_FLAGS_DELAYED_RESPONSE;
601 handler->read_callback(att_connection->con_handle, ATT_READ_RESPONSE_PENDING, 0, NULL, 0);
602 }
603 }
604 // notify main read callback if it returned response pending
605 if ((att_server_flags & ATT_SERVICE_FLAGS_DELAYED_RESPONSE) != 0){
606 // flag was set by read callback
607 btstack_assert(att_server_client_read_callback != NULL);
608 (*att_server_client_read_callback)(att_connection->con_handle, ATT_READ_RESPONSE_PENDING, 0, NULL, 0);
609 }
591 }
592
593 // free reserved buffer
594 if (eatt_buffer == NULL){
595 l2cap_release_packet_buffer();
596 }
597 return 0;
598 }

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

1167 while (btstack_linked_list_iterator_has_next(&it)){
1168 att_service_handler_t * handler = (att_service_handler_t*) btstack_linked_list_iterator_next(&it);
1169 if (handler->start_handle > handle) continue;
1170 if (handler->end_handle < handle) continue;
1171 return handler;
1172 }
1173 return NULL;
1174}
610 }
611
612 // free reserved buffer
613 if (eatt_buffer == NULL){
614 l2cap_release_packet_buffer();
615 }
616 return 0;
617 }

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

1186 while (btstack_linked_list_iterator_has_next(&it)){
1187 att_service_handler_t * handler = (att_service_handler_t*) btstack_linked_list_iterator_next(&it);
1188 if (handler->start_handle > handle) continue;
1189 if (handler->end_handle < handle) continue;
1190 return handler;
1191 }
1192 return NULL;
1193}
1175static att_read_callback_t att_server_read_callback_for_handle(uint16_t handle){
1176 att_service_handler_t * handler = att_service_handler_for_handle(handle);
1177 if (handler != NULL) return handler->read_callback;
1178 return att_server_client_read_callback;
1179}
1180
1181static att_write_callback_t att_server_write_callback_for_handle(uint16_t handle){
1182 att_service_handler_t * handler = att_service_handler_for_handle(handle);
1183 if (handler != NULL) return handler->write_callback;
1184 return att_server_client_write_callback;
1185}
1186
1187static btstack_packet_handler_t att_server_packet_handler_for_handle(uint16_t handle){

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

1213 uint8_t error_code = (*handler->write_callback)(con_handle, 0, ATT_TRANSACTION_MODE_VALIDATE, 0, NULL, 0);
1214 if (error_code != 0u) return error_code;
1215 }
1216 if (!att_server_client_write_callback) return 0;
1217 return (*att_server_client_write_callback)(con_handle, 0, ATT_TRANSACTION_MODE_VALIDATE, 0, NULL, 0);
1218}
1219
1220static uint16_t att_server_read_callback(hci_con_handle_t con_handle, uint16_t attribute_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){
1194
1195static att_write_callback_t att_server_write_callback_for_handle(uint16_t handle){
1196 att_service_handler_t * handler = att_service_handler_for_handle(handle);
1197 if (handler != NULL) return handler->write_callback;
1198 return att_server_client_write_callback;
1199}
1200
1201static btstack_packet_handler_t att_server_packet_handler_for_handle(uint16_t handle){

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

1227 uint8_t error_code = (*handler->write_callback)(con_handle, 0, ATT_TRANSACTION_MODE_VALIDATE, 0, NULL, 0);
1228 if (error_code != 0u) return error_code;
1229 }
1230 if (!att_server_client_write_callback) return 0;
1231 return (*att_server_client_write_callback)(con_handle, 0, ATT_TRANSACTION_MODE_VALIDATE, 0, NULL, 0);
1232}
1233
1234static uint16_t att_server_read_callback(hci_con_handle_t con_handle, uint16_t attribute_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){
1221 att_read_callback_t callback = att_server_read_callback_for_handle(attribute_handle);
1222 if (!callback) return 0;
1223 return (*callback)(con_handle, attribute_handle, offset, buffer, buffer_size);
1235 att_service_handler_t * service = att_service_handler_for_handle(attribute_handle);
1236 att_read_callback_t read_callback = (service != NULL) ? service->read_callback : att_server_client_read_callback;
1237 uint16_t result = 0;
1238 if (read_callback != NULL){
1239 result = (*read_callback)(con_handle, attribute_handle, offset, buffer, buffer_size);
1240#ifdef ENABLE_ATT_DELAYED_RESPONSE
1241 if (result == ATT_READ_RESPONSE_PENDING){
1242 if (service == NULL){
1243 att_server_flags |= ATT_SERVICE_FLAGS_DELAYED_RESPONSE;
1244 } else {
1245 service->flags |= ATT_SERVICE_FLAGS_DELAYED_RESPONSE;
1246 }
1247 }
1248#endif
1249 }
1250 return result;
1224}
1225
1226static int att_server_write_callback(hci_con_handle_t con_handle, uint16_t attribute_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size){
1227 switch (transaction_mode){
1228 case ATT_TRANSACTION_MODE_VALIDATE:
1229 return att_validate_prepared_write(con_handle);
1230 case ATT_TRANSACTION_MODE_EXECUTE:
1231 case ATT_TRANSACTION_MODE_CANCEL:

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

1462 return att_connection->mtu;
1463}
1464
1465void att_server_deinit(void){
1466 att_server_client_read_callback = NULL;
1467 att_server_client_write_callback = NULL;
1468 att_client_packet_handler = NULL;
1469 service_handlers = NULL;
1251}
1252
1253static int att_server_write_callback(hci_con_handle_t con_handle, uint16_t attribute_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size){
1254 switch (transaction_mode){
1255 case ATT_TRANSACTION_MODE_VALIDATE:
1256 return att_validate_prepared_write(con_handle);
1257 case ATT_TRANSACTION_MODE_EXECUTE:
1258 case ATT_TRANSACTION_MODE_CANCEL:

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

1489 return att_connection->mtu;
1490}
1491
1492void att_server_deinit(void){
1493 att_server_client_read_callback = NULL;
1494 att_server_client_write_callback = NULL;
1495 att_client_packet_handler = NULL;
1496 service_handlers = NULL;
1497 att_server_flags = 0;
1470}
1471
1472#ifdef ENABLE_GATT_OVER_EATT
1473
1474#define MAX_NR_EATT_CHANNELS 5
1475
1476static uint16_t att_server_eatt_receive_buffer_size;
1477static uint16_t att_server_eatt_send_buffer_size;

--- 177 unchanged lines hidden ---
1498}
1499
1500#ifdef ENABLE_GATT_OVER_EATT
1501
1502#define MAX_NR_EATT_CHANNELS 5
1503
1504static uint16_t att_server_eatt_receive_buffer_size;
1505static uint16_t att_server_eatt_send_buffer_size;

--- 177 unchanged lines hidden ---