diff --git a/ble/att_server.c b/ble/att_server.c index 51446d90c..9203a9a88 100644 --- a/ble/att_server.c +++ b/ble/att_server.c @@ -285,3 +285,20 @@ void att_server_init(uint8_t const * db, att_read_callback_t read_callback, att_ void att_server_register_packet_handler(btstack_packet_handler_t handler){ att_client_packet_handler = handler; } + +int att_server_can_send(){ + if (att_request_handle == 0) return 0; + return hci_can_send_packet_now(HCI_ACL_DATA_PACKET); +} + +void att_server_notify(uint16_t handle, uint8_t *value, uint16_t value_len){ + uint8_t packet_buffer[att_connection.mtu]; + uint16_t size = att_prepare_handle_value_notification(&att_connection, handle, value, value_len, packet_buffer); + l2cap_send_connectionless(att_request_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, packet_buffer, size); +} + +void att_server_indicate(uint16_t handle, uint8_t *value, uint16_t value_len){ + uint8_t packet_buffer[att_connection.mtu]; + uint16_t size = att_prepare_handle_value_indication(&att_connection, handle, value, value_len, packet_buffer); + l2cap_send_connectionless(att_request_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, packet_buffer, size); +} diff --git a/ble/att_server.h b/ble/att_server.h index fdb5a9e9b..061310a14 100644 --- a/ble/att_server.h +++ b/ble/att_server.h @@ -38,6 +38,9 @@ #include #include #include "att.h" - + void att_server_init(uint8_t const * db, att_read_callback_t read_callback, att_write_callback_t write_callback); void att_server_register_packet_handler(btstack_packet_handler_t handler); +int att_server_can_send(); +void att_server_notify(uint16_t handle, uint8_t *value, uint16_t value_len); +void att_server_indicate(uint16_t handle, uint8_t *value, uint16_t value_len); diff --git a/example/libusb/ble_peripheral.c b/example/libusb/ble_peripheral.c index c5006ce09..422603b05 100644 --- a/example/libusb/ble_peripheral.c +++ b/example/libusb/ble_peripheral.c @@ -33,15 +33,10 @@ //***************************************************************************** // -// att device demo +// BLE Peripheral Demo // //***************************************************************************** -// TODO: seperate BR/EDR from LE ACL buffers -// .. - -// NOTE: Supports only a single connection - #include #include #include @@ -63,24 +58,52 @@ #include "gap_le.h" #include "central_device_db.h" -///------ -static int advertisements_enabled = 0; +#define HEARTBEAT_PERIOD_MS 1000 // test profile #include "profile.h" +///------ +static int advertisements_enabled = 0; +static timer_source_t heartbeat; +static uint8_t counter = 0; +static int update_client = 0; +static int client_configuration = 0; + +static void app_run(); + +static void heartbeat_handler(struct timer *ts){ + // restart timer + run_loop_set_timer(ts, HEARTBEAT_PERIOD_MS); + run_loop_add_timer(ts); + + counter++; + update_client = 1; + app_run(); +} + +static void app_run(){ + if (!client_configuration || !update_client) return; + if (!att_server_can_send()) return; + printf("Notify value %u\n", counter); + update_client = 0; + att_server_notify(0x0f, &counter, 1); +} + // write requests -static void att_write_callback(uint16_t handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size, signature_t * signature){ +static int att_write_callback(uint16_t handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size, signature_t * signature){ printf("WRITE Callback, handle %04x\n", handle); switch(handle){ - case 0x000b: - buffer[buffer_size]=0; - printf("New text: %s\n", buffer); + case 0x0010: + client_configuration = buffer[0]; + printf("Client Configuration set to %u\n", client_configuration); break; - case 0x000d: - printf("New value: %u\n", buffer[0]); + default: + printf("Value: "); + hexdump(buffer, buffer_size); break; } + return 1; } static void app_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ @@ -180,9 +203,15 @@ void setup(void){ int main(void) { setup(); - // gap_random_address_set_update_period(5000); + gap_random_address_set_update_period(60000); gap_random_address_set_mode(GAP_RANDOM_ADDRESS_RESOLVABLE); + // set one-shot timer + heartbeat.process = &heartbeat_handler; + run_loop_set_timer(&heartbeat, HEARTBEAT_PERIOD_MS); + run_loop_add_timer(&heartbeat); + + // turn on! hci_power_control(HCI_POWER_ON);