diff --git a/example/le_counter.c b/example/le_counter.c index c7e8fb282..a72cd7336 100644 --- a/example/le_counter.c +++ b/example/le_counter.c @@ -69,6 +69,7 @@ static int le_notification_enabled; static btstack_timer_source_t heartbeat; 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 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){ if (le_notification_enabled) { 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_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; break; 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; @@ -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, copy data and return number bytes copied // @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 (buffer){ 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 */ -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; le_notification_enabled = little_endian_read_16(buffer, 0) == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION; + con_handle = connection_handle; return 0; } /* LISTING_END */ diff --git a/example/le_streamer.c b/example/le_streamer.c index 4ee1f49a7..aea72732a 100644 --- a/example/le_streamer.c +++ b/example/le_streamer.c @@ -209,13 +209,13 @@ static void streamer(void){ memset(test_data, counter, sizeof(test_data)); // 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 test_track_sent(test_data_len); // request next send event - att_server_request_can_send_now_event(); + att_server_request_can_send_now_event(connection_handle); } /* LISTING_END */ @@ -234,9 +234,9 @@ static int att_write_callback(hci_con_handle_t con_handle, uint16_t att_handle, switch(att_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; - printf("Notifications enabled %u\n", le_notification_enabled); + printf("Notifications enabled %u\n", 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(); break; diff --git a/example/spp_and_le_counter.c b/example/spp_and_le_counter.c index 00e11fc4f..1bdd6c8c6 100644 --- a/example/spp_and_le_counter.c +++ b/example/spp_and_le_counter.c @@ -61,6 +61,7 @@ static uint16_t rfcomm_channel_id; static uint8_t spp_service_buffer[150]; static int le_notification_enabled; +static hci_con_handle_t att_con_handle; // THE Couner 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; 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; 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){ 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; + att_con_handle = con_handle; return 0; case ATT_CHARACTERISTIC_0000FF11_0000_1000_8000_00805F9B34FB_01_VALUE_HANDLE: printf("Write on test characteristic: "); @@ -224,7 +226,7 @@ static void heartbeat_handler(struct btstack_timer_source *ts){ } 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_add_timer(ts); diff --git a/src/ble/att_server.c b/src/ble/att_server.c index 8a26b28e8..ceb074eb0 100644 --- a/src/ble/att_server.c +++ b/src/ble/att_server.c @@ -414,17 +414,20 @@ void att_server_register_packet_handler(btstack_packet_handler_t 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; 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_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; 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); } -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_dispatch_server_can_send_now(att_connection.con_handle)) return BTSTACK_ACL_BUFFERS_FULL; diff --git a/src/ble/att_server.h b/src/ble/att_server.h index fc81242d2..8f482a36b 100644 --- a/src/ble/att_server.h +++ b/src/ble/att_server.h @@ -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 + * @param con_handle * @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 * @note ATT_EVENT_CAN_SEND_NOW might be emitted during call to this function * 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 + * @param con_handle * @param attribute_handle * @param value * @param value_len * @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 + * @param con_handle * @param attribute_handle * @param value * @param value_len * @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 */