att_server: add con handle to send related functions

This commit is contained in:
Matthias Ringwald 2016-04-07 14:52:50 +02:00
parent 0d78ab98bf
commit c141988c58
5 changed files with 29 additions and 19 deletions

View File

@ -69,6 +69,7 @@
static int le_notification_enabled; static int le_notification_enabled;
static btstack_timer_source_t heartbeat; static btstack_timer_source_t heartbeat;
static btstack_packet_callback_registration_t hci_event_callback_registration; static btstack_packet_callback_registration_t hci_event_callback_registration;
static hci_con_handle_t con_handle;
static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
static uint16_t att_read_callback(hci_con_handle_t con_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size); static uint16_t att_read_callback(hci_con_handle_t con_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size);
@ -140,7 +141,7 @@ static void beat(void){
static void heartbeat_handler(struct btstack_timer_source *ts){ static void heartbeat_handler(struct btstack_timer_source *ts){
if (le_notification_enabled) { if (le_notification_enabled) {
beat(); beat();
att_server_request_can_send_now_event(); att_server_request_can_send_now_event(con_handle);
} }
btstack_run_loop_set_timer(ts, HEARTBEAT_PERIOD_MS); btstack_run_loop_set_timer(ts, HEARTBEAT_PERIOD_MS);
btstack_run_loop_add_timer(ts); btstack_run_loop_add_timer(ts);
@ -170,7 +171,7 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
le_notification_enabled = 0; le_notification_enabled = 0;
break; break;
case ATT_EVENT_CAN_SEND_NOW: case ATT_EVENT_CAN_SEND_NOW:
att_server_notify(ATT_CHARACTERISTIC_0000FF11_0000_1000_8000_00805F9B34FB_01_VALUE_HANDLE, (uint8_t*) counter_string, counter_string_len); att_server_notify(con_handle, ATT_CHARACTERISTIC_0000FF11_0000_1000_8000_00805F9B34FB_01_VALUE_HANDLE, (uint8_t*) counter_string, counter_string_len);
break; break;
} }
break; break;
@ -193,7 +194,7 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
// - if buffer == NULL, don't copy data, just return size of value // - if buffer == NULL, don't copy data, just return size of value
// - if buffer != NULL, copy data and return number bytes copied // - if buffer != NULL, copy data and return number bytes copied
// @param offset defines start of attribute value // @param offset defines start of attribute value
static uint16_t att_read_callback(hci_con_handle_t con_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){ static uint16_t att_read_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){
if (att_handle == ATT_CHARACTERISTIC_0000FF11_0000_1000_8000_00805F9B34FB_01_VALUE_HANDLE){ if (att_handle == ATT_CHARACTERISTIC_0000FF11_0000_1000_8000_00805F9B34FB_01_VALUE_HANDLE){
if (buffer){ if (buffer){
memcpy(buffer, &counter_string[offset], counter_string_len - offset); memcpy(buffer, &counter_string[offset], counter_string_len - offset);
@ -214,9 +215,10 @@ static uint16_t att_read_callback(hci_con_handle_t con_handle, uint16_t att_hand
*/ */
/* LISTING_START(attWrite): ATT Write */ /* LISTING_START(attWrite): ATT Write */
static int att_write_callback(hci_con_handle_t con_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size){ static int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size){
if (att_handle != ATT_CHARACTERISTIC_0000FF11_0000_1000_8000_00805F9B34FB_01_CLIENT_CONFIGURATION_HANDLE) return 0; if (att_handle != ATT_CHARACTERISTIC_0000FF11_0000_1000_8000_00805F9B34FB_01_CLIENT_CONFIGURATION_HANDLE) return 0;
le_notification_enabled = little_endian_read_16(buffer, 0) == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION; le_notification_enabled = little_endian_read_16(buffer, 0) == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION;
con_handle = connection_handle;
return 0; return 0;
} }
/* LISTING_END */ /* LISTING_END */

View File

@ -209,13 +209,13 @@ static void streamer(void){
memset(test_data, counter, sizeof(test_data)); memset(test_data, counter, sizeof(test_data));
// send // send
att_server_notify(ATT_CHARACTERISTIC_0000FF11_0000_1000_8000_00805F9B34FB_01_VALUE_HANDLE, (uint8_t*) test_data, test_data_len); att_server_notify(connection_handle, ATT_CHARACTERISTIC_0000FF11_0000_1000_8000_00805F9B34FB_01_VALUE_HANDLE, (uint8_t*) test_data, test_data_len);
// track // track
test_track_sent(test_data_len); test_track_sent(test_data_len);
// request next send event // request next send event
att_server_request_can_send_now_event(); att_server_request_can_send_now_event(connection_handle);
} }
/* LISTING_END */ /* LISTING_END */
@ -236,7 +236,7 @@ static int att_write_callback(hci_con_handle_t con_handle, uint16_t att_handle,
le_notification_enabled = little_endian_read_16(buffer, 0) == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION; le_notification_enabled = little_endian_read_16(buffer, 0) == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION;
printf("Notifications enabled %u\n", le_notification_enabled); printf("Notifications enabled %u\n", le_notification_enabled);
if (le_notification_enabled){ if (le_notification_enabled){
att_server_request_can_send_now_event(); att_server_request_can_send_now_event(connection_handle);
} }
test_reset(); test_reset();
break; break;

View File

@ -61,6 +61,7 @@
static uint16_t rfcomm_channel_id; static uint16_t rfcomm_channel_id;
static uint8_t spp_service_buffer[150]; static uint8_t spp_service_buffer[150];
static int le_notification_enabled; static int le_notification_enabled;
static hci_con_handle_t att_con_handle;
// THE Couner // THE Couner
static btstack_timer_source_t heartbeat; static btstack_timer_source_t heartbeat;
@ -120,7 +121,7 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
break; break;
case ATT_EVENT_CAN_SEND_NOW: case ATT_EVENT_CAN_SEND_NOW:
att_server_notify(ATT_CHARACTERISTIC_0000FF11_0000_1000_8000_00805F9B34FB_01_VALUE_HANDLE, (uint8_t*) counter_string, counter_string_len); att_server_notify(att_con_handle, ATT_CHARACTERISTIC_0000FF11_0000_1000_8000_00805F9B34FB_01_VALUE_HANDLE, (uint8_t*) counter_string, counter_string_len);
break; break;
case RFCOMM_EVENT_INCOMING_CONNECTION: case RFCOMM_EVENT_INCOMING_CONNECTION:
@ -193,6 +194,7 @@ static int att_write_callback(hci_con_handle_t con_handle, uint16_t att_handle,
switch (att_handle){ switch (att_handle){
case ATT_CHARACTERISTIC_0000FF11_0000_1000_8000_00805F9B34FB_01_CLIENT_CONFIGURATION_HANDLE: case ATT_CHARACTERISTIC_0000FF11_0000_1000_8000_00805F9B34FB_01_CLIENT_CONFIGURATION_HANDLE:
le_notification_enabled = little_endian_read_16(buffer, 0) == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION; le_notification_enabled = little_endian_read_16(buffer, 0) == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION;
att_con_handle = con_handle;
return 0; return 0;
case ATT_CHARACTERISTIC_0000FF11_0000_1000_8000_00805F9B34FB_01_VALUE_HANDLE: case ATT_CHARACTERISTIC_0000FF11_0000_1000_8000_00805F9B34FB_01_VALUE_HANDLE:
printf("Write on test characteristic: "); printf("Write on test characteristic: ");
@ -224,7 +226,7 @@ static void heartbeat_handler(struct btstack_timer_source *ts){
} }
if (le_notification_enabled) { if (le_notification_enabled) {
att_server_request_can_send_now_event(); att_server_request_can_send_now_event(att_con_handle);
} }
btstack_run_loop_set_timer(ts, HEARTBEAT_PERIOD_MS); btstack_run_loop_set_timer(ts, HEARTBEAT_PERIOD_MS);
btstack_run_loop_add_timer(ts); btstack_run_loop_add_timer(ts);

View File

@ -414,17 +414,20 @@ void att_server_register_packet_handler(btstack_packet_handler_t handler){
att_client_packet_handler = handler; att_client_packet_handler = handler;
} }
int att_server_can_send_packet_now(void){ // NOTE: con_handle is ignored for now as only a single connection is supported
// TODO: support multiple connections
int att_server_can_send_packet_now(hci_con_handle_t con_handle){
if (att_connection.con_handle == 0) return 0; if (att_connection.con_handle == 0) return 0;
return att_dispatch_server_can_send_now(att_connection.con_handle); return att_dispatch_server_can_send_now(att_connection.con_handle);
} }
void att_server_request_can_send_now_event(){ void att_server_request_can_send_now_event(hci_con_handle_t con_handle){
att_client_waiting_for_can_send = 1; att_client_waiting_for_can_send = 1;
att_dispatch_server_request_can_send_now_event(att_connection.con_handle); att_dispatch_server_request_can_send_now_event(att_connection.con_handle);
} }
int att_server_notify(uint16_t attribute_handle, uint8_t *value, uint16_t value_len){ int att_server_notify(hci_con_handle_t con_handle, uint16_t attribute_handle, uint8_t *value, uint16_t value_len){
if (!att_dispatch_server_can_send_now(att_connection.con_handle)) return BTSTACK_ACL_BUFFERS_FULL; if (!att_dispatch_server_can_send_now(att_connection.con_handle)) return BTSTACK_ACL_BUFFERS_FULL;
l2cap_reserve_packet_buffer(); l2cap_reserve_packet_buffer();
@ -433,7 +436,7 @@ int att_server_notify(uint16_t attribute_handle, uint8_t *value, uint16_t value_
return l2cap_send_prepared_connectionless(att_connection.con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, size); return l2cap_send_prepared_connectionless(att_connection.con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, size);
} }
int att_server_indicate(uint16_t attribute_handle, uint8_t *value, uint16_t value_len){ int att_server_indicate(hci_con_handle_t con_handle, uint16_t attribute_handle, uint8_t *value, uint16_t value_len){
if (att_handle_value_indication_handle) return ATT_HANDLE_VALUE_INDICATION_IN_PORGRESS; if (att_handle_value_indication_handle) return ATT_HANDLE_VALUE_INDICATION_IN_PORGRESS;
if (!att_dispatch_server_can_send_now(att_connection.con_handle)) return BTSTACK_ACL_BUFFERS_FULL; if (!att_dispatch_server_can_send_now(att_connection.con_handle)) return BTSTACK_ACL_BUFFERS_FULL;

View File

@ -64,35 +64,38 @@ void att_server_register_packet_handler(btstack_packet_handler_t handler);
/* /*
* @brief tests if a notification or indication can be send right now * @brief tests if a notification or indication can be send right now
* @param con_handle
* @return 1, if packet can be sent * @return 1, if packet can be sent
*/ */
int att_server_can_send_packet_now(void); int att_server_can_send_packet_now(hci_con_handle_t con_handle);
/** /**
* @brief Request emission of ATT_EVENT_CAN_SEND_NOW as soon as possible * @brief Request emission of ATT_EVENT_CAN_SEND_NOW as soon as possible
* @note ATT_EVENT_CAN_SEND_NOW might be emitted during call to this function * @note ATT_EVENT_CAN_SEND_NOW might be emitted during call to this function
* so packet handler should be ready to handle it * so packet handler should be ready to handle it
* @param local_cid * @param con_handle
*/ */
void att_server_request_can_send_now_event(void); void att_server_request_can_send_now_event(hci_con_handle_t con_handle);
/* /*
* @brief notify client about attribute value change * @brief notify client about attribute value change
* @param con_handle
* @param attribute_handle * @param attribute_handle
* @param value * @param value
* @param value_len * @param value_len
* @return 0 if ok, error otherwise * @return 0 if ok, error otherwise
*/ */
int att_server_notify(uint16_t attribute_handle, uint8_t *value, uint16_t value_len); int att_server_notify(hci_con_handle_t con_handle, uint16_t attribute_handle, uint8_t *value, uint16_t value_len);
/* /*
* @brief indicate value change to client. client is supposed to reply with an indication_response * @brief indicate value change to client. client is supposed to reply with an indication_response
* @param con_handle
* @param attribute_handle * @param attribute_handle
* @param value * @param value
* @param value_len * @param value_len
* @return 0 if ok, error otherwise * @return 0 if ok, error otherwise
*/ */
int att_server_indicate(uint16_t attribute_handle, uint8_t *value, uint16_t value_len); int att_server_indicate(hci_con_handle_t con_handle, uint16_t attribute_handle, uint8_t *value, uint16_t value_len);
/* API_END */ /* API_END */