diff --git a/README.md b/README.md index ed6bed539..69ae62e39 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ No build server | [posix-h4-da14585](https://github.com/bluekitchen/btstack/tree No build server | [posix-h5](https://github.com/bluekitchen/btstack/tree/develop/port/posix-h5) | Unix-based system connected to Bluetooth module via H5 over serial port No build server | [posix-h5-bcm](https://github.com/bluekitchen/btstack/tree/develop/port/posix-h5) | Unix-based system connected to Broadcom/Cypress Bluetooth module via H5 over serial port [](https://buildbot.bluekitchen-gmbh.com/btstack/#/builders/port-libusb-develop) | [libusb](https://github.com/bluekitchen/btstack/tree/develop/port/libusb) | Unix-based system with dedicated USB Bluetooth dongle +No build server | [libusb-intel](https://github.com/bluekitchen/btstack/tree/develop/port/libusb-inttel) | Unix-based system with Intel Wireless 8260/8265 Controller No build server | [windows-h4](https://github.com/bluekitchen/btstack/tree/develop/port/windows-h4) | Win32-based system connected to Bluetooth module via serial port No build server | [windows-winusb](https://github.com/bluekitchen/btstack/tree/develop/port/windows-winusb) | Win32-based system with dedicated USB Bluetooth dongle No build server | [raspi](https://github.com/bluekitchen/btstack/tree/develop/port/raspi) | Raspberry Pi 3 or Raspberry Pi Zero W with built-in BCM4343 Bluetooth/Wifi Controller diff --git a/port/libusb-intel/.gitignore b/port/libusb-intel/.gitignore new file mode 100644 index 000000000..6a6d034f2 --- /dev/null +++ b/port/libusb-intel/.gitignore @@ -0,0 +1,72 @@ +a2dp_sink_demo +a2dp_source_demo +ancs_client_demo +ancs_client_demo.h +avdtp_sink.sbc +avdtp_sink.wav +avdtp_sink_demo +avdtp_source_demo +avrcp_browsing_client +ble_central_test +ble_peripheral_test +bnep_test +classic_test +dut_mode_classic +gap_dedicated_bonding +gap_inquiry +gap_inquiry_and_bond +gap_le_advertisements +gatt_battery_query +gatt_battery_query.h +gatt_browser +gatt_browser.h +hfp_ag_demo +hfp_hf_demo +hid_host_demo +hid_keyboard_demo +hid_mouse_demo +hog_keyboard_demo +hog_keyboard_demo.h +hog_mouse_demo +hog_mouse_demo.h +hsp_ag_demo +hsp_hs_demo +l2cap_test +le_counter +le_counter.h +le_counter_work +le_data_channel_client +le_data_channel_server +le_data_channel_server.h +le_streamer +le_streamer.h +le_streamer_client +led_counter +panu_demo +pbap_client_demo +profile.h +sco_input* +sco_output* +sdp_bnep_query +sdp_general_query +sdp_rfcomm_query +sm_pairing_central +sm_pairing_central.h +sm_pairing_peripheral +sm_pairing_peripheral.h +spp_and_le_counter +spp_and_le_counter.h +spp_and_le_streamer +spp_and_le_streamer.h +spp_counter +spp_streamer +spp_streamer_client +att_delayed_response +att_delayed_response.h + +*.ddc +*.sfi + +gap_link_keys +mod_player +gatt_heart_rate_client diff --git a/port/libusb-intel/Makefile b/port/libusb-intel/Makefile new file mode 100644 index 000000000..f331f44aa --- /dev/null +++ b/port/libusb-intel/Makefile @@ -0,0 +1,53 @@ +# Makefile for libusb based examples +BTSTACK_ROOT = ../.. + +CORE += main.c btstack_stdin_posix.c btstack_tlv_posix.c + +COMMON += hci_transport_h2_libusb.c btstack_run_loop_posix.c le_device_db_fs.c btstack_link_key_db_fs.c wav_util.c btstack_network_posix.c +COMMON += btstack_audio_portaudio.c btstack_chipset_intel_firmware.c + +include ${BTSTACK_ROOT}/example/Makefile.inc +include ${BTSTACK_ROOT}/chipset/intel/Makefile.inc + +CFLAGS += -g -std=c99 -Wall -Wmissing-prototypes -Wstrict-prototypes -Wshadow -Wunused-parameter -Wredundant-decls -Wsign-compare +# CFLAGS += -Werror +# CFLAGS += -pedantic + +# only LLVM +# CFLAGS += -Wnewline-eof +# CFLAGS += -Wc11-extensions +# CFLAGS += -Wgnu-empty-initializer + +CFLAGS += -I${BTSTACK_ROOT}/platform/posix \ + -I${BTSTACK_ROOT}/platform/embedded \ + -I${BTSTACK_ROOT}/3rd-party/tinydir \ + -I${BTSTACK_ROOT}/chipset/intel + +VPATH += ${BTSTACK_ROOT}/platform/embedded +VPATH += ${BTSTACK_ROOT}/platform/posix +VPATH += ${BTSTACK_ROOT}/platform/libusb +VPATH += ${BTSTACK_ROOT}/chipset/csr +VPATH += ${BTSTACK_ROOT}/chipset/intel + +# use pkg-config +CFLAGS += $(shell pkg-config libusb-1.0 --cflags) +LDFLAGS += $(shell pkg-config libusb-1.0 --libs) + +# use pkg-config for portaudio +# CFLAGS += $(shell pkg-config portaudio-2.0 --cflags) -DHAVE_PORTAUDIO +# LDFLAGS += $(shell pkg-config portaudio-2.0 --libs) + +# hard coded flags for portaudio in /usr/local/lib +# CFLAGS += -I/usr/local/include -DHAVE_PORTAUDIO +# LDFLAGS += -L/sw/lib -lportaudio -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit -Wl,-framework,Carbon + +clean: clean-intel + +clean_src: + rm -rf * ${BTSTACK_ROOT}/src/*.o + rm -rf * ${BTSTACK_ROOT}/src/classic/*.o + rm -rf * ${BTSTACK_ROOT}/src/ble/*.o + rm -rf * ${BTSTACK_ROOT}/platform/embedded/*.o + +all: all-intel ${EXAMPLES} + diff --git a/port/libusb-intel/README.md b/port/libusb-intel/README.md new file mode 100644 index 000000000..0236720a7 --- /dev/null +++ b/port/libusb-intel/README.md @@ -0,0 +1,86 @@ +# BTstack Port for POSIX Systems with Intel Wireless 8260/8265 Controllers + +Same as port/libusb, but customized for Intel Wireless 8260 and 8265 Controllers. +These controller require firmware upload and configuration to work. Firmware and config is downloaded from the Linux firmware repository. + +## Compilation + +Requirements: +- [pkg-config](http://www.freedesktop.org/wiki/Software/pkg-config/) +- [libusb-1.0](http://libusb.info) + +On a recent Debian-based system, all you need is: + + apt-get install gcc git libusb-1.0 pkg-config + + +When everything is ready, you compile all examples with: + + make + +## Environment + +On Linux, the USB Bluetooth dongle is usually not accessible to a regular user. You can either: +- run the examples as root +- add a udev rule for your dongle to extend access rights to user processes + +To add an udev rule, please create `/etc/udev/rules.d/btstack.rules` and add this + + # Match all devices from CSR + SUBSYSTEM=="usb", ATTRS{idVendor}=="0a12", MODE="0666" + + # Match DeLOCK Bluetooth 4.0 dongle + SUBSYSTEM=="usb", ATTRS{idVendor}=="0a5c", ATTRS{device}=="21e8", MODE="0666" + + # Match Asus BT400 + SUBSYSTEM=="usb", ATTRS{idVendor}=="0b05", ATTRS{device}=="17cb", MODE="0666" + + # Match Laird BT860 / Cypress Semiconductor CYW20704A2 + SUBSYSTEM=="usb", ATTRS{idVendor}=="04b4", ATTRS{device}=="f901", MODE="0666" + + # Match Intel Wireless 8260 8265 + SUBSYSTEM=="usb", ATTRS{idVendor}=="8027", ATTRS{device}=="0a2b, MODE="0666" + +On macOS, the OS will try to use a plugged-in Bluetooth Controller if one is available. +It's best to to tell the OS to always use the internal Bluetooth Contoller. + +For this, execute: + + sudo nvram bluetoothHostControllerSwitchBehavior=never + +and then reboot to activate the change. + +## Running the examples + +BTstack's HCI USB transport will try to find a suitable Bluetooth module and use it. + +On start, BTstack will try to find a suitable Bluetooth module. It will also print the path to the packet log as well as the USB path. + + $ ./le_counter + Packet Log: /tmp/hci_dump.pklg + USB Path: 03-01-04-03 + Firwmare ./ibt-12-16.sfi + Firmware upload complete + Firmware operational + Done 1 + BTstack counter 0001 + USB Path: 03-01-04-03 +BTstack up and running on F8:34:41:D5:BE:6F. + +If you want to run multiple examples at the same time, it helps to fix the path to the used Bluetooth module by passing -u usb-path to the executable. + +Example running le_streamer and le_streamer_client in two processes, using Bluetooth dongles at USB path 6 and 4: + + ./le_streamer -u 6 + Specified USB Path: 06 + Packet Log: /tmp/hci_dump_6.pklg + USB Path: 06 + BTstack up and running on 00:1A:7D:DA:71:13. + To start the streaming, please run the le_streamer_client example on other device, or use some GATT Explorer, e.g. LightBlue, BLExplr. + + $ ./le_streamer_client -u 4 + Specified USB Path: 04 + Packet Log: /tmp/hci_dump_4.pklg + USB Path: 04 + BTstack up and running on 00:1A:7D:DA:71:13. + Start scanning! diff --git a/port/libusb-intel/btstack_config.h b/port/libusb-intel/btstack_config.h new file mode 100644 index 000000000..66d77ad64 --- /dev/null +++ b/port/libusb-intel/btstack_config.h @@ -0,0 +1,36 @@ +// +// btstack_config.h for libusb port +// + +#ifndef __BTSTACK_CONFIG +#define __BTSTACK_CONFIG + +// Port related features +#define HAVE_MALLOC +#define HAVE_POSIX_FILE_IO +#define HAVE_BTSTACK_STDIN +#define HAVE_POSIX_TIME + +// BTstack features that can be enabled +#define ENABLE_BLE +#define ENABLE_CLASSIC +#define ENABLE_HFP_WIDE_BAND_SPEECH +#define ENABLE_LE_CENTRAL +#define ENABLE_LE_PERIPHERAL +#define ENABLE_LE_SECURE_CONNECTIONS +#define ENABLE_LE_DATA_CHANNELS +#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS +#define ENABLE_LE_DATA_LENGTH_EXTENSION +#define ENABLE_ATT_DELAYED_RESPONSE +#define ENABLE_LOG_ERROR +#define ENABLE_LOG_INFO +#define ENABLE_SCO_OVER_HCI +#define ENABLE_SDP_DES_DUMP + +#define ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE + +// BTstack configuration. buffers, sizes, ... +#define HCI_ACL_PAYLOAD_SIZE (1691 + 4) +#define HCI_INCOMING_PRE_BUFFER_SIZE 14 // sizeof BNEP header, avoid memcpy + +#endif diff --git a/port/libusb-intel/main.c b/port/libusb-intel/main.c new file mode 100644 index 000000000..68d032e72 --- /dev/null +++ b/port/libusb-intel/main.c @@ -0,0 +1,207 @@ +/* + * 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 + * + */ + +#define __BTSTACK_FILE__ "main.c" + +// ***************************************************************************** +// +// minimal setup for HCI code +// +// ***************************************************************************** + +#include +#include +#include +#include +#include + +#include "btstack_config.h" + +#include "btstack_debug.h" +#include "btstack_event.h" +#include "btstack_link_key_db_fs.h" +#include "btstack_memory.h" +#include "btstack_run_loop.h" +#include "btstack_run_loop_posix.h" +#include "hal_led.h" +#include "hci.h" +#include "hci_dump.h" +#include "btstack_stdin.h" +#include "btstack_audio.h" +#include "btstack_tlv_posix.h" +#include "btstack_chipset_intel_firmware.h" + +#define TLV_DB_PATH_PREFIX "/tmp/btstack_" +#define TLV_DB_PATH_POSTFIX ".tlv" +static char tlv_db_path[100]; +static const btstack_tlv_t * tlv_impl; +static btstack_tlv_posix_t tlv_context; +static bd_addr_t local_addr; + +static int main_argc; +static const char ** main_argv; +static const hci_transport_t * transport; + +int btstack_main(int argc, const char * argv[]); + +static btstack_packet_callback_registration_t hci_event_callback_registration; + +static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ + UNUSED(channel); + UNUSED(size); + if (packet_type != HCI_EVENT_PACKET) return; + switch (hci_event_packet_get_type(packet)){ + case BTSTACK_EVENT_STATE: + if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return; + gap_local_bd_addr(local_addr); + printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); + strcpy(tlv_db_path, TLV_DB_PATH_PREFIX); + strcat(tlv_db_path, bd_addr_to_str(local_addr)); + strcat(tlv_db_path, TLV_DB_PATH_POSTFIX); + tlv_impl = btstack_tlv_posix_init_instance(&tlv_context, tlv_db_path); + btstack_tlv_set_instance(tlv_impl, &tlv_context); + break; + default: + break; + } +} + +static void sigint_handler(int param){ + UNUSED(param); + + printf("CTRL-C - SIGINT received, shutting down..\n"); + log_info("sigint_handler: shutting down"); + + // reset anyway + btstack_stdin_reset(); + + // power down + hci_power_control(HCI_POWER_OFF); + hci_close(); + log_info("Good bye, see you.\n"); + exit(0); +} + +static int led_state = 0; +void hal_led_toggle(void){ + led_state = 1 - led_state; + printf("LED State %u\n", led_state); +} + +static void intel_firmware_done(int result){ + + printf("Done %x\n", result); + + // close + transport->close(); + + // init HCI + hci_init(transport, NULL); + +#ifdef ENABLE_CLASSIC + hci_set_link_key_db(btstack_link_key_db_fs_instance()); +#endif + +#ifdef HAVE_PORTAUDIO + btstack_audio_set_instance(btstack_audio_portaudio_get_instance()); +#endif + + // inform about BTstack state + hci_event_callback_registration.callback = &packet_handler; + hci_add_event_handler(&hci_event_callback_registration); + + // setup app + btstack_main(main_argc, main_argv); +} + +#define USB_MAX_PATH_LEN 7 +int main(int argc, const char * argv[]){ + + uint8_t usb_path[USB_MAX_PATH_LEN]; + int usb_path_len = 0; + const char * usb_path_string = NULL; + if (argc >= 3 && strcmp(argv[1], "-u") == 0){ + // parse command line options for "-u 11:22:33" + usb_path_string = argv[2]; + printf("Specified USB Path: "); + while (1){ + char * delimiter; + int port = strtol(usb_path_string, &delimiter, 16); + usb_path[usb_path_len] = port; + usb_path_len++; + printf("%02x ", port); + if (!delimiter) break; + if (*delimiter != ':' && *delimiter != '-') break; + usb_path_string = delimiter+1; + } + printf("\n"); + argc -= 2; + memmove(&argv[1], &argv[3], (argc-1) * sizeof(char *)); + } + + /// GET STARTED with BTstack /// + btstack_memory_init(); + btstack_run_loop_init(btstack_run_loop_posix_get_instance()); + + if (usb_path_len){ + hci_transport_usb_set_path(usb_path_len, usb_path); + } + + // use logger: format HCI_DUMP_PACKETLOGGER, HCI_DUMP_BLUEZ or HCI_DUMP_STDOUT + + char pklg_path[100]; + strcpy(pklg_path, "/tmp/hci_dump"); + if (usb_path_len){ + strcat(pklg_path, "_"); + strcat(pklg_path, usb_path_string); + } + strcat(pklg_path, ".pklg"); + printf("Packet Log: %s\n", pklg_path); + hci_dump_open(pklg_path, HCI_DUMP_PACKETLOGGER); + + // setup USB Transport + transport = hci_transport_usb_instance(); + btstack_chipset_intel_download_firmware(transport, &intel_firmware_done); + + // handle CTRL-c + signal(SIGINT, sigint_handler); + + // go + btstack_run_loop_execute(); + + return 0; +}