From c8f97be681f13af34ae26e193207bad1ae738268 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Thu, 2 Feb 2017 14:40:41 +0100 Subject: [PATCH 1/4] example: add le_streamer_client that connects to le_streamer --- example/Makefile.inc | 5 + example/le_streamer_client.c | 283 +++++++++++++++++++++++++++++++++++ 2 files changed, 288 insertions(+) create mode 100644 example/le_streamer_client.c diff --git a/example/Makefile.inc b/example/Makefile.inc index c55cfb2d1..8c6e6f386 100644 --- a/example/Makefile.inc +++ b/example/Makefile.inc @@ -96,6 +96,7 @@ EXAMPLES = \ gatt_browser \ le_counter \ le_streamer \ + le_streamer_client \ led_counter \ sdp_bnep_query \ sdp_general_query \ @@ -117,6 +118,7 @@ EXAMPLES_USING_LE = \ gatt_browser \ le_counter \ le_streamer \ + le_streamer_client \ spp_and_le_counter \ gap_le_advertisements \ sm_pairing_peripheral \ @@ -176,6 +178,9 @@ sm_pairing_central: ${CORE_OBJ} ${COMMON_OBJ} ${SM_OBJ} ad_parser.o sm_pairing_c le_streamer: le_streamer.h ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${GATT_SERVER_OBJ} ${SM_OBJ} le_streamer.c ${CC} $(filter-out le_streamer.h,$^) ${CFLAGS} ${LDFLAGS} -o $@ +le_streamer_client: ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${GATT_CLIENT_OBJ} ${SM_OBJ} le_streamer_client.c + ${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@ + spp_and_le_counter: spp_and_le_counter.h ${CORE_OBJ} ${COMMON_OBJ} ${CLASSIC_OBJ} ${ATT_OBJ} ${GATT_SERVER_OBJ} ${SM_OBJ} spp_and_le_counter.c ${CC} $(filter-out spp_and_le_counter.h,$^) ${CFLAGS} ${LDFLAGS} -o $@ diff --git a/example/le_streamer_client.c b/example/le_streamer_client.c new file mode 100644 index 000000000..598fa9917 --- /dev/null +++ b/example/le_streamer_client.c @@ -0,0 +1,283 @@ +/* + * Copyright (C) 2014 BlueKitchen GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * 4. Any redistribution, use, or modification is done solely for + * personal benefit and not for any commercial purpose or for + * monetary gain. + * + * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Please inquire about commercial licensing options at + * contact@bluekitchen-gmbh.com + * + */ + +// ***************************************************************************** +// +// LE Streamer Client - connects to 'LE Streamer' and subscribes to test characteristic +// +// ***************************************************************************** + +#include +#include +#include +#include + +#include "btstack.h" + +typedef enum { + TC_IDLE, + TC_W4_SCAN_RESULT, + TC_W4_CONNECT, + TC_W4_SERVICE_RESULT, + TC_W4_CHARACTERISTIC_RESULT, + TC_W4_TEST_DATA +} gc_state_t; + +static bd_addr_t cmdline_addr = { }; +static int cmdline_addr_found = 0; + +// addr and type of device with correct name +static bd_addr_t le_streamer_addr; +static bd_addr_type_t le_streamer_addr_type; + +static hci_con_handle_t connection_handle; +static uint8_t le_streamer_service_uuid[16] = { 0x00, 0x00, 0xFF, 0x10, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; +static uint8_t le_streamer_characteristic_uuid[16] = { 0x00, 0x00, 0xFF, 0x11, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; + +static gatt_client_service_t le_streamer_service; +static gatt_client_characteristic_t le_streamer_characteristic; + +static gatt_client_notification_t notification_registration; + +static gc_state_t state = TC_IDLE; +static btstack_packet_callback_registration_t hci_event_callback_registration; + +// returns 1 if name is found in advertisement +static int advertisement_report_contains_name(const char * name, uint8_t * advertisement_report){ + // get advertisement from report event + const uint8_t * adv_data = gap_event_advertising_report_get_data(advertisement_report); + uint16_t adv_len = gap_event_advertising_report_get_data_length(advertisement_report); + int name_len = strlen(name); + + // iterate over advertisement data + ad_context_t context; + for (ad_iterator_init(&context, adv_len, adv_data) ; ad_iterator_has_more(&context) ; ad_iterator_next(&context)){ + uint8_t data_type = ad_iterator_get_data_type(&context); + uint8_t data_size = ad_iterator_get_data_len(&context); + const uint8_t * data = ad_iterator_get_data(&context); + int i; + switch (data_type){ + case BLUETOOTH_DATA_TYPE_SHORTENED_LOCAL_NAME: + case BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME: + // compare common prefix + for (i=0; i Date: Thu, 2 Feb 2017 14:50:30 +0100 Subject: [PATCH 2/4] wiced: add gatt_client to default makefile --- port/wiced/wiced.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/port/wiced/wiced.mk b/port/wiced/wiced.mk index 90c48581c..2b7247307 100644 --- a/port/wiced/wiced.mk +++ b/port/wiced/wiced.mk @@ -16,6 +16,7 @@ $(NAME)_SOURCES += \ ../../src/ble/att_db.c \ ../../src/ble/att_dispatch.c \ ../../src/ble/att_server.c \ + ../../src/ble/gatt_client.c \ ../../src/ble/le_device_db_memory.c \ ../../src/ble/gatt-service/battery_service_server.c \ ../../src/ble/sm.c \ From 3b1c4bce5257d383a8bc3295d210cf91e1bcedc1 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Thu, 2 Feb 2017 14:53:53 +0100 Subject: [PATCH 3/4] ports: remove obsolete MAX_NR_GATT_SUBCLIENTS, MAX_NR_GATT_CLIENTS = 1 --- port/arduino/btstack_config.h | 1 - port/ez430-rf2560/btstack_config.h | 3 +-- port/msp-exp430f5438-cc2564b/btstack_config.h | 3 +-- port/msp430f5229lp-cc2564b/btstack_config.h | 3 +-- port/nrf5-zephyr/btstack_config.h | 1 - port/nrf5x/btstack_config.h | 3 +-- port/pic32-harmony/src/btstack_config.h | 3 +-- port/stm32-f103rb-nucleo/btstack_config.h | 3 +-- port/wiced/btstack_config.h | 3 +-- 9 files changed, 7 insertions(+), 16 deletions(-) diff --git a/port/arduino/btstack_config.h b/port/arduino/btstack_config.h index 47ce386fd..98d9e284e 100644 --- a/port/arduino/btstack_config.h +++ b/port/arduino/btstack_config.h @@ -19,7 +19,6 @@ #define HCI_ACL_PAYLOAD_SIZE 200 #define MAX_NR_BNEP_SERVICES 0 #define MAX_NR_BNEP_CHANNELS 0 -#define MAX_NR_GATT_SUBCLIENTS 2 #define MAX_NR_HCI_CONNECTIONS 1 #define MAX_NR_L2CAP_SERVICES 0 #define MAX_NR_L2CAP_CHANNELS 0 diff --git a/port/ez430-rf2560/btstack_config.h b/port/ez430-rf2560/btstack_config.h index 369a312c1..57228be76 100644 --- a/port/ez430-rf2560/btstack_config.h +++ b/port/ez430-rf2560/btstack_config.h @@ -21,8 +21,7 @@ #define HCI_ACL_PAYLOAD_SIZE 52 #define MAX_SPP_CONNECTIONS 1 #define MAX_NR_HCI_CONNECTIONS MAX_SPP_CONNECTIONS -#define MAX_NR_GATT_CLIENTS 0 -#define MAX_NR_GATT_SUBCLIENTS 0 +#define MAX_NR_GATT_CLIENTS 1 #define MAX_NR_L2CAP_SERVICES 2 #define MAX_NR_L2CAP_CHANNELS (1+MAX_SPP_CONNECTIONS) #define MAX_NR_RFCOMM_MULTIPLEXERS MAX_SPP_CONNECTIONS diff --git a/port/msp-exp430f5438-cc2564b/btstack_config.h b/port/msp-exp430f5438-cc2564b/btstack_config.h index 14f171290..43db9cc9a 100644 --- a/port/msp-exp430f5438-cc2564b/btstack_config.h +++ b/port/msp-exp430f5438-cc2564b/btstack_config.h @@ -22,8 +22,7 @@ #define MAX_NR_BNEP_CHANNELS MAX_SPP_CONNECTIONS #define MAX_NR_BNEP_SERVICES 1 #define MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES 2 -#define MAX_NR_GATT_CLIENTS 0 -#define MAX_NR_GATT_SUBCLIENTS 0 +#define MAX_NR_GATT_CLIENTS 1 #define MAX_NR_HCI_CONNECTIONS MAX_SPP_CONNECTIONS #define MAX_NR_HFP_CONNECTIONS 0 #define MAX_NR_L2CAP_CHANNELS (1+MAX_SPP_CONNECTIONS) diff --git a/port/msp430f5229lp-cc2564b/btstack_config.h b/port/msp430f5229lp-cc2564b/btstack_config.h index 3bb3ed302..a22a382cd 100644 --- a/port/msp430f5229lp-cc2564b/btstack_config.h +++ b/port/msp430f5229lp-cc2564b/btstack_config.h @@ -21,8 +21,7 @@ #define HCI_ACL_PAYLOAD_SIZE 52 #define MAX_SPP_CONNECTIONS 1 #define MAX_NR_HCI_CONNECTIONS MAX_SPP_CONNECTIONS -#define MAX_NR_GATT_CLIENTS 0 -#define MAX_NR_GATT_SUBCLIENTS 0 +#define MAX_NR_GATT_CLIENTS 1 #define MAX_NR_HFP_CONNECTIONS 0 #define MAX_NR_L2CAP_SERVICES 2 #define MAX_NR_L2CAP_CHANNELS (1+MAX_SPP_CONNECTIONS) diff --git a/port/nrf5-zephyr/btstack_config.h b/port/nrf5-zephyr/btstack_config.h index 7e9cda771..dcc9f0e5c 100644 --- a/port/nrf5-zephyr/btstack_config.h +++ b/port/nrf5-zephyr/btstack_config.h @@ -22,7 +22,6 @@ #define MAX_NR_L2CAP_SERVICES 1 #define MAX_NR_L2CAP_CHANNELS 1 #define MAX_NR_GATT_CLIENTS 1 -#define MAX_NR_GATT_SUBCLIENTS 1 #define MAX_NR_RFCOMM_MULTIPLEXERS 0 #define MAX_NR_RFCOMM_SERVICES 0 diff --git a/port/nrf5x/btstack_config.h b/port/nrf5x/btstack_config.h index 68570ee64..8db79f1c9 100644 --- a/port/nrf5x/btstack_config.h +++ b/port/nrf5x/btstack_config.h @@ -19,8 +19,7 @@ // BTstack configuration. buffers, sizes, ... #define HCI_ACL_PAYLOAD_SIZE 52 #define MAX_SPP_CONNECTIONS 1 -#define MAX_NR_GATT_CLIENTS 0 -#define MAX_NR_GATT_SUBCLIENTS 0 +#define MAX_NR_GATT_CLIENTS 1 #define MAX_NR_HCI_CONNECTIONS MAX_SPP_CONNECTIONS #define MAX_NR_L2CAP_SERVICES 2 #define MAX_NR_L2CAP_CHANNELS (1+MAX_SPP_CONNECTIONS) diff --git a/port/pic32-harmony/src/btstack_config.h b/port/pic32-harmony/src/btstack_config.h index afdb69c93..0afde1156 100644 --- a/port/pic32-harmony/src/btstack_config.h +++ b/port/pic32-harmony/src/btstack_config.h @@ -20,8 +20,7 @@ // BTstack configuration. buffers, sizes, ... #define HCI_ACL_PAYLOAD_SIZE 52 #define MAX_SPP_CONNECTIONS 1 -#define MAX_NR_GATT_CLIENTS 0 -#define MAX_NR_GATT_SUBCLIENTS 0 +#define MAX_NR_GATT_CLIENTS 1 #define MAX_NR_HCI_CONNECTIONS MAX_SPP_CONNECTIONS #define MAX_NR_L2CAP_SERVICES 2 #define MAX_NR_L2CAP_CHANNELS (1+MAX_SPP_CONNECTIONS) diff --git a/port/stm32-f103rb-nucleo/btstack_config.h b/port/stm32-f103rb-nucleo/btstack_config.h index 10cf285b3..d3a8e7b0e 100644 --- a/port/stm32-f103rb-nucleo/btstack_config.h +++ b/port/stm32-f103rb-nucleo/btstack_config.h @@ -20,8 +20,7 @@ // BTstack configuration. buffers, sizes, ... #define HCI_ACL_PAYLOAD_SIZE 52 #define MAX_SPP_CONNECTIONS 1 -#define MAX_NR_GATT_CLIENTS 0 -#define MAX_NR_GATT_SUBCLIENTS 0 +#define MAX_NR_GATT_CLIENTS 1 #define MAX_NR_HCI_CONNECTIONS MAX_SPP_CONNECTIONS #define MAX_NR_L2CAP_SERVICES 2 #define MAX_NR_L2CAP_CHANNELS (1+MAX_SPP_CONNECTIONS) diff --git a/port/wiced/btstack_config.h b/port/wiced/btstack_config.h index 78681dffa..9ccfdef59 100644 --- a/port/wiced/btstack_config.h +++ b/port/wiced/btstack_config.h @@ -21,8 +21,7 @@ // BTstack configuration. buffers, sizes, ... #define HCI_ACL_PAYLOAD_SIZE 52 #define MAX_SPP_CONNECTIONS 1 -#define MAX_NR_GATT_CLIENTS 0 -#define MAX_NR_GATT_SUBCLIENTS 0 +#define MAX_NR_GATT_CLIENTS 1 #define MAX_NR_HCI_CONNECTIONS MAX_SPP_CONNECTIONS #define MAX_NR_L2CAP_SERVICES 2 #define MAX_NR_L2CAP_CHANNELS (1+MAX_SPP_CONNECTIONS) From 9d6ba381e711c693f2bff44214e38fb30f54aab2 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Thu, 2 Feb 2017 15:55:38 +0100 Subject: [PATCH 4/4] doc: add info on Windows run loop --- doc/manual/docs/how_to.md | 14 +++++++++++--- doc/manual/docs/integration.md | 14 +++++++++----- doc/manual/docs/quick_start.md | 11 +++++------ 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/doc/manual/docs/how_to.md b/doc/manual/docs/how_to.md index 2439ddeaa..b4c5e7c2e 100644 --- a/doc/manual/docs/how_to.md +++ b/doc/manual/docs/how_to.md @@ -73,6 +73,8 @@ ENABLE_LOG_DEBUG | Enable log_debug messages ENABLE_LOG_ERROR | Enable log_error messages ENABLE_LOG_INFO | Enable log_info messages ENABLE_SCO_OVER_HCI | Enable SCO over HCI for chipsets (only CC256x/WL18xx and USB CSR controllers) +ENBALE_LE_PERIPHERAL | Enable support for LE Peripheral Role in HCI and Security Manager +ENBALE_LE_CENTRAL | Enable support for LE Central Role in HCI and Security Manager ENABLE_LE_SECURE_CONNECTIONS | Enable LE Secure Connections using [mbed TLS library](https://tls.mbed.org) ENABLE_LE_DATA_CHANNELS | Enable LE Data Channels in credit-based flow control mode ENABLE_LE_SIGNED_WRITE | Enable LE Signed Writes in ATT/GATT @@ -193,10 +195,11 @@ BTstack provides different run loop implementations that implement the *btstack_ - Embedded: the main implementation for embedded systems, especially without an RTOS. - POSIX: implementation for POSIX systems based on the select() call. - CoreFoundation: implementation for iOS and OS X applications -- WICED: implementation for the Broadcom WICED SDK RTOS abstraction that warps FreeRTOS or ThreadX. +- WICED: implementation for the Broadcom WICED SDK RTOS abstraction that wraps FreeRTOS or ThreadX. +- Windows: implementation for Windows based on Event objects and WaitForMultipleObjects() call. Depending on the platform, data sources are either polled (embedded), or the platform provides a way -to wait for a data source to become ready for read or write (POSIX, CoreFoundation), or, +to wait for a data source to become ready for read or write (POSIX, CoreFoundation, Windows), or, are not used as the HCI transport driver and the run loop is implemented in a different way (WICED). In any case, the callbacks must be to explicitly enabled with the *btstack_run_loop_enable_data_source_callbacks(..)* function. @@ -254,8 +257,13 @@ It supports ready to read and write similar to the POSIX implementation. The cal To enable the use of timers, make sure that you defined HAVE_POSIX_TIME in the config file. -### Run loop WICED +### Run loop Windows +The data sources are Event objects. In the run loop implementation WaitForMultipleObjects() call +is all is used to wait for the Event object to become ready while waiting for the next timeout. + + +### Run loop WICED WICED SDK API does not provide asynchronous read and write to the UART and no direct way to wait for one or more peripherals to become ready. Therefore, BTstack does not provide direct support for data sources. diff --git a/doc/manual/docs/integration.md b/doc/manual/docs/integration.md index 019d377cb..71c44f939 100644 --- a/doc/manual/docs/integration.md +++ b/doc/manual/docs/integration.md @@ -30,16 +30,20 @@ system. Currently, we have two examples for this: +- *btstack_run_loop_posix.c* is an implementation for POSIX compliant + systems. The data sources are modeled as file descriptors and + managed in a linked list. Then, the *select* function is used to wait + for the next file descriptor to become ready or timer to expire. + - *btstack_run_loop_cocoa.c* is an implementation for the CoreFoundation Framework used in OS X and iOS. All run loop functions are implemented in terms of CoreFoundation calls, data sources and timers are modeled as CFSockets and CFRunLoopTimer respectively. -- *btstack_run_loop_posix.c* is an implementation for POSIX compliant - systems. The data sources are modeled as file descriptors and - managed in a linked list. Then, the*select* function is used to wait - for the next file descriptor to become ready or timer to expire. - +- *btstack_run_loop_windows* is an implementation for Windows environment. + The data sources are modeled with Event objects and managed in a linked list. + Then, the *WaitForMultipleObjects* is used to wait for the next Event to + becomre ready or timer to expire. ## Adapting BTstack for Multi-Threaded Environments {#sec:multithreadingIntegration} diff --git a/doc/manual/docs/quick_start.md b/doc/manual/docs/quick_start.md index b73d1fb95..52125b2df 100644 --- a/doc/manual/docs/quick_start.md +++ b/doc/manual/docs/quick_start.md @@ -10,9 +10,9 @@ On Windows, there is no packet manager, but it's easy to download and install al - [Python](http://www.python.org/getit/) for Windows. When using the official installer, please confirm adding Python to the Windows Path. - [MSYS2](https://msys2.github.io) is used to provide the bash shell and most standard POSIX command line tools. -- [MinGW64](https://mingw-w64.org/doku.php) GCC for Windows 64 & 32 bits incl. make. To install with MYS2: pacman -S mingw-w64-x86_64-gcc -- [git](https://git-scm.com) is used to download BTstack source code. To install with MYS2: pacman -S git -- [winpty](https://github.com/rprichard/winpty) a wrapper to allow for console input when running in msys2: To install with MYS2: pacman -S winpty +- [MinGW64](https://mingw-w64.org/doku.php) GCC for Windows 64 & 32 bits incl. make. To install with MSYS2: pacman -S mingw-w64-x86_64-gcc +- [git](https://git-scm.com) is used to download BTstack source code. To install with MSYS2: pacman -S git +- [winpty](https://github.com/rprichard/winpty) a wrapper to allow for console input when running in MSYS2: To install with MSYS2: pacman -S winpty ## Getting BTstack from GitHub @@ -68,7 +68,7 @@ Bluetooth. For this, execute: ## Windows-WinUSB -While libusb basically also works on Windows, we recommend to use the Windows-WinUSB port that uses a native run loop and the native WinUSB API to access the USB Bluetooth dongle. +Although libusb basically works with the POSIX Run Loop on Windows, we recommend to use the Windows-WinUSB port that uses a native run loop and the native WinUSB API to access a USB Bluetooth dongle. For libusb or WinUSB, you need to install a special device driver to make the USB dongle accessible to user space. It works like this: @@ -78,8 +78,7 @@ For libusb or WinUSB, you need to install a special device driver to make the US - Select WinUSB (libusb) in the right pull pull down list - Select “Replace Driver” -When running the examples in the MSYS2, the console input (via btstack_stdin_support) doesn't work. It works in the older MSYS and also the regular -CMD.exe environment. Another option is to install WinPTY and then start the example via WinPTY like this: +When running the examples in the MSYS2 shell, the console input (via btstack_stdin_support) doesn't work. It works in the older MSYS and also the regular CMD.exe environment. Another option is to install WinPTY and then start the example via WinPTY like this: $ winpty ./hfp_hf_demo.exe