Merge branch 'develop' into a2dp

This commit is contained in:
Milanka Ringwald 2017-01-17 13:49:59 +01:00
commit cab4a0b539
26 changed files with 2812 additions and 111 deletions

View File

@ -61,7 +61,9 @@ Status | Platform
-------------- | ------
[<img src="http://buildbot.bluekitchen-gmbh.com/btstack/badge.png?builder=port-posix-h4-develop">](https://buildbot.bluekitchen-gmbh.com/btstack/builders/port-posix-h4-develop) | posix: Unix-based system connected to Bluetooth module via serial port
[<img src="http://buildbot.bluekitchen-gmbh.com/btstack/badge.png?builder=port-libusb-develop">](https://buildbot.bluekitchen-gmbh.com/btstack/builders/port-libusb-develop) | libusb: Unix-based system with dedicated USB Bluetooth dongle
[<img src="http://buildbot.bluekitchen-gmbh.com/btstack/badge.png?builder=port-daemon-develop">](https://buildbot.bluekitchen-gmbh.com/btstack/builders/port-daemon-develop) | daemon: TCP and Unix domain named socket client-server architecture supporting multiple clients
[<img src="http://buildbot.bluekitchen-gmbh.com/btstack/badge.png?builder=port-daemon-develop">](https://buildbot.bluekitchen-gmbh.com/btstack/builders/.. | windows-h4: Win32-based system connected to Bluetooth module via serial port
.. | windwos-winusb: Win32-based system with dedicated USB Bluetooth dongle
port-daemon-develop) | daemon: TCP and Unix domain named socket client-server architecture supporting multiple clients
[<img src="http://buildbot.bluekitchen-gmbh.com/btstack/badge.png?builder=java-develop">](https://buildbot.bluekitchen-gmbh.com/btstack/builders/java-develop) | java: Java wrapper for daemon
[<img src="http://buildbot.bluekitchen-gmbh.com/btstack/badge.png?builder=port-ios-develop">](https://buildbot.bluekitchen-gmbh.com/btstack/builders/port-ios-develop) | iOS: daemon for iOS jailbreak devices, C client-server API
[<img src="http://buildbot.bluekitchen-gmbh.com/btstack/badge.png?builder=port-mtk-develop">](https://buildbot.bluekitchen-gmbh.com/btstack/builders/port-mtk-develop) | mtk: daemon for rooted Android devices, based on Mediatek MT65xx processor, Java and C client-server API

View File

@ -58,6 +58,10 @@
#include <unistd.h>
#endif
#ifdef _WIN32
#include <Windows.h>
#endif
static int send_download_command;
static uint32_t init_script_offset;
@ -134,8 +138,11 @@ static btstack_chipset_result_t chipset_next_command(uint8_t * hci_cmd_buffer){
close(hcd_fd);
// wait for firmware patch to be applied - shorter delay possible
#ifdef _WIN32
Sleep(1000);
#else
sleep(1);
#endif
return BTSTACK_CHIPSET_DONE;
}
if (res < 0){

View File

@ -1,33 +1,18 @@
## General Tools
Most ports use a regular Makefile to build the examples.
On Unix-based systems, git, make, and Python are usually installed. If
not, use the systems packet manager to install them.
On Windows, you need to manually install and configure GNU Make, Python,
and optionally git :
On Windows, there is no packet manager, but it's easy to download and install all requires development packets quickly by hand. You'll need:
- [GNU Make](http://gnuwin32.sourceforge.net/packages/make.htm)
for Windows: Add its bin folder to the Windows Path in Environment
Variables. The bin folder is where make.exe resides, and its
usually located in [C:\Program Files\GnuWin32\bin]().
- [Python](http://www.python.org/getit/) for
Windows: Add Python installation folder to the Windows Path in
Environment Variables.
### Adding paths to the Windows Path variable {#sec:windowsPathQuickStart}
- Go to: Control Panel->System->Advanced tab->Environment Variables.
- The top part contains a list of User variables.
- Click on the Path variable and then click edit.
- Go to the end of the line, then append the path to the list, for
example, [C:\Program Files\GnuWin32\bin]() for GNU Make.
- Ensure that there is a semicolon before and after [C:\Program Files\GnuWin32\bin]().
- [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
## Getting BTstack from GitHub
@ -35,7 +20,6 @@ Use git to clone the latest version:
git clone https://github.com/bluekitchen/btstack.git
Alternatively, you can download it as a ZIP archive from
[BTstacks page](https://github.com/bluekitchen/btstack/archive/master.zip) on
GitHub.
@ -69,7 +53,7 @@ setups, toolchains, programmers, and init scripts.
### libusb
The quickest way to try BTstack is on a Linux or OS X system with an
additional USB Bluetooth module. The Makefile [platforms/libusb]() in requires
additional USB Bluetooth module. The Makefile [port/libusb]() in requires
[pkg-config](http://www.freedesktop.org/wiki/Software/pkg-config/)
and [libusb-1.0](http://libusb.info) or higher to be
installed.
@ -82,28 +66,22 @@ Bluetooth. For this, execute:
sudo nvram bluetoothHostControllerSwitchBehavior=never
Its also possible to run the examples on Win32 systems. For this:
## Windows-WinUSB
- Install [MSYS](http://www.mingw.org/wiki/msys) and
[MINGW32](http://www.mingw.org) using the MINGW installer
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.
- Compile and install libusb-1.0.19 to [/usr/local/]() in msys command
shell
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:
- Setup a USB Bluetooth dongle for use with libusb-1.0:
- Start [Zadig](http://zadig.akeo.ie)
- Select Options -> “List all devices”
- Select USB Bluetooth dongle in the big pull down list
- Select WinUSB (libusb) in the right pull pull down list
- Select “Replace Driver”
- Start [Zadig](http://zadig.akeo.ie)
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:
- Select Options -> “List all devices”
- Select USB Bluetooth dongle in the big pull down list
- Select WinUSB (libusb) in the right pull pull down list
- Select “Replace Driver”
Now, you can run the examples from the *msys* shell the same way as on
Linux/OS X.
$ winpty ./hfp_hf_demo.exe
### Texas Instruments MSP430-based boards

View File

@ -68,8 +68,8 @@ const char hfp_ag_service_name[] = "BTstack HFP AG Test";
static bd_addr_t device_addr;
static const char * device_addr_string = "00:15:83:5F:9D:46";
// static uint8_t codecs[] = {HFP_CODEC_CVSD, HFP_CODEC_MSBC};
static uint8_t codecs[] = {HFP_CODEC_CVSD};
static uint8_t codecs[] = {HFP_CODEC_CVSD, HFP_CODEC_MSBC};
// static uint8_t codecs[] = {HFP_CODEC_CVSD};
static uint8_t negotiated_codec = HFP_CODEC_CVSD;
static hci_con_handle_t acl_handle = -1;

View File

@ -45,7 +45,11 @@
#include "btstack_util.h"
#ifdef _WIN32
#define LINK_KEY_PATH ""
#else
#define LINK_KEY_PATH "/tmp/"
#endif
#define LINK_KEY_PREFIX "btstack_at_"
#define LINK_KEY_FOR "_link_key_for_"
#define LINK_KEY_SUFFIX ".txt"

View File

@ -44,52 +44,34 @@
#include "stdin_support.h"
#ifndef _WIN32
// From MSDN:
// __WIN32 Defined as 1 when the compilation target is 32-bit ARM, 64-bit ARM, x86, or x64.
// Otherwise, undefined.
#ifdef _WIN32
#include <Windows.h>
#include <conio.h> //provides non standard getch() function
#include <signal.h>
#else
#include <termios.h>
#endif
static btstack_data_source_t stdin_source;
static int activated = 0;
void btstack_stdin_setup(void (*stdin_process)(btstack_data_source_t *_ds, btstack_data_source_callback_type_t callback_type)){
#ifdef _WIN32
static HANDLE stdin_reader_thread_handle;
static char key_read_buffer;
static HANDLE key_processed_handle;
#ifndef _WIN32
struct termios term = {0};
if (tcgetattr(0, &term) < 0)
perror("tcsetattr()");
term.c_lflag &= ~ICANON;
term.c_lflag &= ~ECHO;
if (tcsetattr(0, TCSANOW, &term) < 0) {
perror("tcsetattr ICANON");
static WINAPI DWORD stdin_reader_thread_process(void * p){
while (1){
key_read_buffer = getch();
SignalObjectAndWait(stdin_source.handle , key_processed_handle, INFINITE, FALSE);
}
#endif
btstack_run_loop_set_data_source_fd(&stdin_source, 0); // stdin
btstack_run_loop_set_data_source_handler(&stdin_source, stdin_process);
btstack_run_loop_enable_data_source_callbacks(&stdin_source, DATA_SOURCE_CALLBACK_READ);
btstack_run_loop_add_data_source(&stdin_source);
activated = 1;
return 0;
}
void btstack_stdin_reset(void){
if (!activated) return;
activated = 0;
btstack_run_loop_remove_data_source(&stdin_source);
#ifndef _WIN32
struct termios term = {0};
if (tcgetattr(0, &term) < 0){
perror("tcsetattr()");
}
term.c_lflag |= ICANON;
term.c_lflag |= ECHO;
if (tcsetattr(0, TCSANOW, &term) < 0){
perror("tcsetattr ICANON");
}
#endif
}
#if 0
static int getstring(char *line, int size)
@ -114,10 +96,87 @@ static int getstring(char *line, int size)
}
#endif
// read single byte after data source callback was triggered
char btstack_stdin_read(void){
char buffer;
read(stdin_source.fd, &buffer, 1);
return buffer;
void btstack_stdin_setup(void (*stdin_process)(btstack_data_source_t *_ds, btstack_data_source_callback_type_t callback_type)){
if (activated) return;
#ifdef _WIN32
// asynchronous io on stdin via OVERLAPPED seems to be problematic.
// Use separate thread and event objects instead
stdin_source.handle = CreateEvent(NULL, FALSE, FALSE, NULL);
key_processed_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
// default attributes, default stack size, proc, args, start immediately, don't care for thread id
stdin_reader_thread_handle = CreateThread(NULL, 0, &stdin_reader_thread_process, NULL, 0, NULL);
#else
// disable line buffering
struct termios term = {0};
if (tcgetattr(0, &term) < 0)
perror("tcsetattr()");
term.c_lflag &= ~ICANON;
term.c_lflag &= ~ECHO;
if (tcsetattr(0, TCSANOW, &term) < 0) {
perror("tcsetattr ICANON");
}
btstack_run_loop_set_data_source_fd(&stdin_source, 0); // stdin
#endif
btstack_run_loop_enable_data_source_callbacks(&stdin_source, DATA_SOURCE_CALLBACK_READ);
btstack_run_loop_set_data_source_handler(&stdin_source, stdin_process);
btstack_run_loop_add_data_source(&stdin_source);
activated = 1;
}
void btstack_stdin_reset(void){
if (!activated) return;
activated = 0;
btstack_run_loop_remove_data_source(&stdin_source);
#ifdef _WIN32
// shutdown thread
TerminateThread(stdin_reader_thread_handle, 0);
WaitForSingleObject(stdin_reader_thread_handle, INFINITE);
CloseHandle(stdin_reader_thread_handle);
// free events
CloseHandle(stdin_source.handle);
CloseHandle(key_processed_handle);
#else
struct termios term = {0};
if (tcgetattr(0, &term) < 0){
perror("tcsetattr()");
}
term.c_lflag |= ICANON;
term.c_lflag |= ECHO;
if (tcsetattr(0, TCSANOW, &term) < 0){
perror("tcsetattr ICANON");
}
#endif
}
// read single byte after data source callback was triggered
char btstack_stdin_read(void){
char data;
#ifdef _WIN32
// raise SIGINT for CTRL-c on main thread
if (key_read_buffer == 0x03){
raise(SIGINT);
return 0;
}
data = key_read_buffer;
SetEvent(key_processed_handle);
#else
read(stdin_source.fd, &data, 1);
#endif
return data;
}

View File

@ -0,0 +1,266 @@
/*
* 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
*
*/
/*
* btstack_run_loop_windows.c
*/
#include "btstack_run_loop.h"
#include "btstack_run_loop_windows.h"
#include "btstack_linked_list.h"
#include "btstack_debug.h"
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
static void btstack_run_loop_windows_dump_timer(void);
// the run loop
static btstack_linked_list_t data_sources;
static int data_sources_modified;
static btstack_linked_list_t timers;
// start time.
static ULARGE_INTEGER start_time;
/**
* Add data_source to run_loop
*/
static void btstack_run_loop_windows_add_data_source(btstack_data_source_t *ds){
data_sources_modified = 1;
// log_info("btstack_run_loop_windows_add_data_source %x with fd %u\n", (int) ds, ds->fd);
btstack_linked_list_add(&data_sources, (btstack_linked_item_t *) ds);
}
/**
* Remove data_source from run loop
*/
static int btstack_run_loop_windows_remove_data_source(btstack_data_source_t *ds){
data_sources_modified = 1;
// log_info("btstack_run_loop_windows_remove_data_source %x\n", (int) ds);
return btstack_linked_list_remove(&data_sources, (btstack_linked_item_t *) ds);
}
/**
* Add timer to run_loop (keep list sorted)
*/
static void btstack_run_loop_windows_add_timer(btstack_timer_source_t *ts){
btstack_linked_item_t *it;
for (it = (btstack_linked_item_t *) &timers; it->next ; it = it->next){
btstack_timer_source_t * next = (btstack_timer_source_t *) it->next;
if (next == ts){
log_error( "btstack_run_loop_timer_add error: timer to add already in list!");
return;
}
if (next->timeout > ts->timeout) {
break;
}
}
ts->item.next = it->next;
it->next = (btstack_linked_item_t *) ts;
log_debug("Added timer %p at %u\n", ts, ts->timeout);
// btstack_run_loop_windows_dump_timer();
}
/**
* Remove timer from run loop
*/
static int btstack_run_loop_windows_remove_timer(btstack_timer_source_t *ts){
// log_info("Removed timer %x at %u\n", (int) ts, (unsigned int) ts->timeout.tv_sec);
// btstack_run_loop_windows_dump_timer();
return btstack_linked_list_remove(&timers, (btstack_linked_item_t *) ts);
}
static void btstack_run_loop_windows_dump_timer(void){
btstack_linked_item_t *it;
int i = 0;
for (it = (btstack_linked_item_t *) timers; it ; it = it->next){
btstack_timer_source_t *ts = (btstack_timer_source_t*) it;
log_info("timer %u, timeout %u\n", i, ts->timeout);
}
}
static void btstack_run_loop_windows_enable_data_source_callbacks(btstack_data_source_t * ds, uint16_t callback_types){
ds->flags |= callback_types;
}
static void btstack_run_loop_windows_disable_data_source_callbacks(btstack_data_source_t * ds, uint16_t callback_types){
ds->flags &= ~callback_types;
}
/**
* @brief Queries the current time in ms since start
*/
static uint32_t btstack_run_loop_windows_get_time_ms(void){
FILETIME file_time;
SYSTEMTIME system_time;
ULARGE_INTEGER now_time;
GetSystemTime(&system_time);
SystemTimeToFileTime(&system_time, &file_time);
now_time.LowPart = file_time.dwLowDateTime;
now_time.HighPart = file_time.dwHighDateTime;
uint32_t time_ms = (now_time.QuadPart - start_time.QuadPart) / 10000;
log_debug("btstack_run_loop_windows_get_time_ms: %u", time_ms);
return time_ms;
}
/**
* Execute run_loop
*/
static void btstack_run_loop_windows_execute(void) {
btstack_timer_source_t *ts;
btstack_linked_list_iterator_t it;
while (1) {
// collect handles to wait for
HANDLE handles[100];
memset(handles, 0, sizeof(handles));
int num_handles = 0;
btstack_linked_list_iterator_init(&it, &data_sources);
while (btstack_linked_list_iterator_has_next(&it)){
btstack_data_source_t *ds = (btstack_data_source_t*) btstack_linked_list_iterator_next(&it);
if (ds->handle == 0) continue;
if (ds->flags & (DATA_SOURCE_CALLBACK_READ | DATA_SOURCE_CALLBACK_WRITE)){
handles[num_handles++] = ds->handle;
log_debug("btstack_run_loop_execute adding handle %p", ds->handle);
}
}
// get next timeout
uint32_t timeout_ms = INFINITE;
if (timers) {
ts = (btstack_timer_source_t *) timers;
uint32_t now_ms = btstack_run_loop_windows_get_time_ms();
timeout_ms = ts->timeout - now_ms;
if (timeout_ms < 0){
timeout_ms = 0;
}
log_debug("btstack_run_loop_execute next timeout in %u ms", timeout_ms);
}
int res;
if (num_handles){
// wait for ready Events or timeout
res = WaitForMultipleObjects(num_handles, &handles[0], 0, timeout_ms);
} else {
// just wait for timeout
Sleep(timeout_ms);
res = WAIT_TIMEOUT;
}
// process data source
if (WAIT_OBJECT_0 <= res && res < (WAIT_OBJECT_0 + num_handles)){
void * triggered_handle = handles[res - WAIT_OBJECT_0];
btstack_linked_list_iterator_init(&it, &data_sources);
while (btstack_linked_list_iterator_has_next(&it)){
btstack_data_source_t *ds = (btstack_data_source_t*) btstack_linked_list_iterator_next(&it);
log_debug("btstack_run_loop_windows_execute: check ds %p with handle %p\n", ds, ds->handle);
if (triggered_handle == ds->handle){
if (ds->flags & DATA_SOURCE_CALLBACK_READ){
log_debug("btstack_run_loop_windows_execute: process read ds %p with handle %p\n", ds, ds->handle);
ds->process(ds, DATA_SOURCE_CALLBACK_READ);
} else if (ds->flags & DATA_SOURCE_CALLBACK_WRITE){
log_debug("btstack_run_loop_windows_execute: process write ds %p with handle %p\n", ds, ds->handle);
ds->process(ds, DATA_SOURCE_CALLBACK_WRITE);
}
break;
}
}
}
// process timers
uint32_t now_ms = btstack_run_loop_windows_get_time_ms();
while (timers) {
ts = (btstack_timer_source_t *) timers;
if (ts->timeout > now_ms) break;
log_debug("btstack_run_loop_windows_execute: process timer %p\n", ts);
// remove timer before processing it to allow handler to re-register with run loop
btstack_run_loop_remove_timer(ts);
ts->process(ts);
}
}
}
// set timer
static void btstack_run_loop_windows_set_timer(btstack_timer_source_t *a, uint32_t timeout_in_ms){
uint32_t time_ms = btstack_run_loop_windows_get_time_ms();
a->timeout = time_ms + timeout_in_ms;
log_debug("btstack_run_loop_windows_set_timer to %u ms (now %u, timeout %u)", a->timeout, time_ms, timeout_in_ms);
}
static void btstack_run_loop_windows_init(void){
data_sources = NULL;
timers = NULL;
// store start time
FILETIME file_time;
SYSTEMTIME system_time;
GetSystemTime(&system_time);
SystemTimeToFileTime(&system_time, &file_time);
start_time.LowPart = file_time.dwLowDateTime;
start_time.HighPart = file_time.dwHighDateTime;
log_debug("btstack_run_loop_windows_init");
}
static const btstack_run_loop_t btstack_run_loop_windows = {
&btstack_run_loop_windows_init,
&btstack_run_loop_windows_add_data_source,
&btstack_run_loop_windows_remove_data_source,
&btstack_run_loop_windows_enable_data_source_callbacks,
&btstack_run_loop_windows_disable_data_source_callbacks,
&btstack_run_loop_windows_set_timer,
&btstack_run_loop_windows_add_timer,
&btstack_run_loop_windows_remove_timer,
&btstack_run_loop_windows_execute,
&btstack_run_loop_windows_dump_timer,
&btstack_run_loop_windows_get_time_ms,
};
/**
* Provide btstack_run_loop_windows instance
*/
const btstack_run_loop_t * btstack_run_loop_windows_get_instance(void){
return &btstack_run_loop_windows;
}

View File

@ -0,0 +1,63 @@
/*
* 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
*
*/
/*
* btstack_run_loop_windows.h
* Functionality special to the windows run loop
*/
#ifndef __btstack_run_loop_WINDOWS_H
#define __btstack_run_loop_WINDOWS_H
#include "btstack_run_loop.h"
#if defined __cplusplus
extern "C" {
#endif
/**
* Provide btstack_run_loop_windows instance
*/
const btstack_run_loop_t * btstack_run_loop_windows_get_instance(void);
/* API_END */
#if defined __cplusplus
}
#endif
#endif // __btstack_run_loop_WINDOWS_H

View File

@ -0,0 +1,417 @@
/*
* Copyright (C) 2016 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
*
*/
/*
* btstack_uart_block_windows.c
*
* Common code to access serial port via asynchronous block read/write commands
*
*/
#include "btstack_uart_block.h"
#include "btstack_run_loop.h"
#include "btstack_debug.h"
#include <fcntl.h> /* File control definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <string.h>
#include <errno.h>
#include <Windows.h>
// uart config
static const btstack_uart_config_t * uart_config;
// data source for integration with BTstack Runloop
static btstack_data_source_t transport_data_source_read;
static btstack_data_source_t transport_data_source_write;
// block write
static int write_bytes_len;
static const uint8_t * write_bytes_data;
// block read
static uint16_t read_bytes_len;
static uint8_t * read_bytes_data;
// callbacks
static void (*block_sent)(void);
static void (*block_received)(void);
// port and async control structure
static HANDLE serial_port_handle;
static OVERLAPPED overlapped_read;
static OVERLAPPED overlapped_write;
static int btstack_uart_windows_init(const btstack_uart_config_t * config){
uart_config = config;
return 0;
}
static void btstack_uart_windows_process_write(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) {
btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE);
DWORD bytes_written;
BOOL ok = GetOverlappedResult(serial_port_handle, &overlapped_write, &bytes_written, FALSE);
if(!ok){
DWORD err = GetLastError();
if (err == ERROR_IO_INCOMPLETE){
// IO_INCOMPLETE -> wait for completed
btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE);
} else {
log_error("btstack_uart_windows_process_write: error writing");
}
return;
}
// assert all bytes written
if (bytes_written != write_bytes_len){
log_error("btstack_uart_windows_process_write: requested write %u but %u were written", (int) write_bytes_len, (int) bytes_written);
return;
}
// notify done
if (block_sent){
block_sent();
}
}
static void btstack_uart_windows_process_read(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) {
btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ);
DWORD bytes_read;
BOOL ok = GetOverlappedResult(serial_port_handle, &overlapped_read, &bytes_read, FALSE);
if(!ok){
DWORD err = GetLastError();
if (err == ERROR_IO_INCOMPLETE){
// IO_INCOMPLETE -> wait for completed
btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ);
} else {
log_error("btstack_uart_windows_process_write: error writing");
}
return;
}
// assert all bytes read
if (bytes_read != read_bytes_len){
log_error("btstack_uart_windows_process_read: requested read %u but %u were read", (int) read_bytes_len, (int) bytes_read);
return;
}
// notify done
if (block_received){
block_received();
}
}
static void btstack_uart_windows_send_block(const uint8_t *data, uint16_t size){
// setup async write
write_bytes_data = data;
write_bytes_len = size;
// start write
DWORD bytes_written;
BOOL ok = WriteFile(serial_port_handle, // handle
write_bytes_data, // (LPCSTR) 8-bit data
write_bytes_len, // length
&bytes_written, // amount written
&overlapped_write); // overlapped structure
if (ok){
// assert all bytes written
if (bytes_written != write_bytes_len){
log_error("btstack_uart_windows_send_block: requested write %u but %u were written", (int) write_bytes_len, (int) bytes_written);
return;
}
//
// TODO: to defer sending done event by enabling POLL Callback for Write
//
// notify done
if (block_sent){
block_sent();
}
return;
}
DWORD err = GetLastError();
if (err != ERROR_IO_PENDING){
log_error("btstack_uart_windows_send_block: error writing");
return;
}
// IO_PENDING -> wait for completed
btstack_run_loop_enable_data_source_callbacks(&transport_data_source_write, DATA_SOURCE_CALLBACK_WRITE);
}
static void btstack_uart_windows_receive_block(uint8_t *buffer, uint16_t len){
// setup async read
read_bytes_data = buffer;
read_bytes_len = len;
// go
DWORD bytes_read;
BOOL ok = ReadFile(serial_port_handle, // handle
read_bytes_data, // (LPCSTR) 8-bit data
read_bytes_len, // length
&bytes_read, // amount read
&overlapped_read); // overlapped structure
if (ok){
// assert all bytes read
if (bytes_read != read_bytes_len){
log_error("btstack_uart_windows_receive_block: requested read %u but %u were read", (int) read_bytes_len, (int) bytes_read);
return;
}
//
// TODO: to defer sending done event by enabling POLL Callback
//
// notify done
if (block_received){
block_received();
}
return;
}
DWORD err = GetLastError();
if (err != ERROR_IO_PENDING){
log_error("btstack_uart_windows_receive_block: error reading");
return;
}
// IO_PENDING -> wait for completed
btstack_run_loop_enable_data_source_callbacks(&transport_data_source_read, DATA_SOURCE_CALLBACK_READ);
}
static int btstack_uart_windows_set_baudrate(uint32_t baudrate){
DCB serial_params;
memset(&serial_params, 0, sizeof(DCB));
serial_params.DCBlength = sizeof(DCB);
int ok = GetCommState(serial_port_handle, &serial_params);
if (!ok){
log_error("windows_set_baudrate: Couldn't get serial parameters");
return -1;
}
serial_params.BaudRate = baudrate;
ok = SetCommState(serial_port_handle, &serial_params);
if (!ok){
log_error("windows_set_baudrate: Couldn't serial parameters");
return -1;
}
return 0;
}
static int btstack_uart_windows_set_parity(int parity){
DCB serial_params;
memset(&serial_params, 0, sizeof(DCB));
serial_params.DCBlength = sizeof(DCB);
int ok = GetCommState(serial_port_handle, &serial_params);
if (!ok){
log_error("windows_set_parity: Couldn't get serial parameters");
return -1;
}
serial_params.Parity = parity;
ok = SetCommState(serial_port_handle, &serial_params);
if (!ok){
log_error("windows_set_parity: Couldn't serial parameters");
return -1;
}
return 0;
}
static int btstack_uart_windows_open(void){
const char * device_name = uart_config->device_name;
const uint32_t baudrate = uart_config->baudrate;
const int flowcontrol = uart_config->flowcontrol;
serial_port_handle = CreateFile( device_name,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);
if (device_name == INVALID_HANDLE_VALUE){
log_error("windows_open: Unable to open port %s", device_name);
return -1;
}
DCB serial_params;
memset(&serial_params, 0, sizeof(DCB));
serial_params.DCBlength = sizeof(DCB);
int ok;
#if 0
// test - try to set internal buffer
ok = SetupComm(serial_port_handle, 64, 64);
printf("SetupCommL ok %u\n", ok);
#endif
#if 0
// test - read internal buffer sizes
COMMPROP comm_prop;
GetCommProperties(serial_port_handle, &comm_prop);
printf("dwMaxTxQueue %ld\n", comm_prop.dwMaxTxQueue);
printf("dwMaxRxQueue %ld\n", comm_prop.dwMaxRxQueue);
printf("dwCurrentTxQueue %ld\n", comm_prop.dwCurrentTxQueue);
printf("dwCurrentRxQueue %ld\n", comm_prop.dwCurrentRxQueue);
#endif
// Caveat: with the default FTDI driver and a FT232R on Windows 10, the default USB RX/TX buffer sizes are 4096
// this causes a problem when data is received back to back, like with SCO audio data
// Workaround: manually set these values in the Device Manager to 64 bytes
ok = GetCommState(serial_port_handle, &serial_params);
if (!ok){
log_error("windows_open: Couldn't get serial parameters");
return -1;
}
// 8-N-1
serial_params.ByteSize = 8;
serial_params.StopBits = ONESTOPBIT;
serial_params.Parity = NOPARITY;
// Flowcontrol
serial_params.fOutxCtsFlow = flowcontrol;
serial_params.fRtsControl = flowcontrol ? RTS_CONTROL_HANDSHAKE : 0;
ok = SetCommState(serial_port_handle, &serial_params);
if (!ok){
log_error("windows_open: Couldn't serial parameters");
return -1;
}
// also set baudrate
if (btstack_uart_windows_set_baudrate(baudrate) < 0){
return -1;
}
// setup overlapped structures for async io
memset(&overlapped_read, 0, sizeof(overlapped_read));
memset(&overlapped_write, 0, sizeof(overlapped_write));
overlapped_read.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
overlapped_write.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
// setup read + write data sources
transport_data_source_read.handle = overlapped_read.hEvent;
transport_data_source_write.handle = overlapped_write.hEvent;
btstack_run_loop_set_data_source_handler(&transport_data_source_read, &btstack_uart_windows_process_read);
btstack_run_loop_set_data_source_handler(&transport_data_source_write, &btstack_uart_windows_process_write);
btstack_run_loop_add_data_source(&transport_data_source_read);
btstack_run_loop_add_data_source(&transport_data_source_write);
return 0;
}
static int btstack_uart_windows_close_new(void){
// first remove run loop handler
btstack_run_loop_remove_data_source(&transport_data_source_read);
btstack_run_loop_remove_data_source(&transport_data_source_write);
// note: an event cannot be freed while a kernel function is waiting.
// in our single-threaded environment, this cannot happen.
// free events
CloseHandle(overlapped_read.hEvent);
CloseHandle(overlapped_write.hEvent);
CloseHandle(serial_port_handle);
// set pointers to zero
overlapped_read.hEvent = NULL;
overlapped_write.hEvent = NULL;
serial_port_handle = NULL;
return 0;
}
static void btstack_uart_windows_set_block_received( void (*block_handler)(void)){
block_received = block_handler;
}
static void btstack_uart_windows_set_block_sent( void (*block_handler)(void)){
block_sent = block_handler;
}
// static void btstack_uart_windows_set_sleep(uint8_t sleep){
// }
// static void btstack_uart_windows_set_csr_irq_handler( void (*csr_irq_handler)(void)){
// }
static const btstack_uart_block_t btstack_uart_windows = {
/* int (*init)(hci_transport_config_uart_t * config); */ &btstack_uart_windows_init,
/* int (*open)(void); */ &btstack_uart_windows_open,
/* int (*close)(void); */ &btstack_uart_windows_close_new,
/* void (*set_block_received)(void (*handler)(void)); */ &btstack_uart_windows_set_block_received,
/* void (*set_block_sent)(void (*handler)(void)); */ &btstack_uart_windows_set_block_sent,
/* int (*set_baudrate)(uint32_t baudrate); */ &btstack_uart_windows_set_baudrate,
/* int (*set_parity)(int parity); */ &btstack_uart_windows_set_parity,
/* void (*receive_block)(uint8_t *buffer, uint16_t len); */ &btstack_uart_windows_receive_block,
/* void (*send_block)(const uint8_t *buffer, uint16_t length); */ &btstack_uart_windows_send_block,
/* int (*get_supported_sleep_modes); */ NULL,
/* void (*set_sleep)(btstack_uart_sleep_mode_t sleep_mode); */ NULL
};
const btstack_uart_block_t * btstack_uart_block_windows_instance(void){
return &btstack_uart_windows;
}

File diff suppressed because it is too large Load Diff

View File

@ -75,13 +75,14 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
static void sigint_handler(int param){
UNUSED(param);
#ifndef _WIN32
printf("CTRL-C - SIGINT received, shutting down..\n");
log_info("sigint_handler: shutting down");
// reset anyway
btstack_stdin_reset();
#endif
log_info(" <= SIGINT received, shutting down..\n");
// power down
hci_power_control(HCI_POWER_OFF);
hci_close();
log_info("Good bye, see you.\n");

View File

@ -108,13 +108,15 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
}
static void sigint_handler(int param){
UNUSED(param);
printf("CTRL-C - SIGINT received, shutting down..\n");
log_info("sigint_handler: shutting down");
#ifndef _WIN32
// reset anyway
btstack_stdin_reset();
#endif
log_info(" <= SIGINT received, shutting down..\n");
// power down
hci_power_control(HCI_POWER_OFF);
hci_close();
log_info("Good bye, see you.\n");

View File

@ -79,13 +79,15 @@ static hci_transport_config_uart_t config = {
static btstack_packet_callback_registration_t hci_event_callback_registration;
static void sigint_handler(int param){
UNUSED(param);
printf("CTRL-C - SIGINT received, shutting down..\n");
log_info("sigint_handler: shutting down");
#ifndef _WIN32
// reset anyway
btstack_stdin_reset();
#endif
log_info(" <= SIGINT received, shutting down..\n");
// power down
hci_power_control(HCI_POWER_OFF);
hci_close();
log_info("Good bye, see you.\n");

39
port/windows-h4/.gitignore vendored Normal file
View File

@ -0,0 +1,39 @@
ancs_client_demo
ancs_client_demo.h
ble_central_test
ble_peripheral_test
bnep_test
classic_test
gap_dedicated_bonding
gap_inquiry
gap_inquiry_and_bond
gap_le_advertisements
gap_le_advertisements
gatt_battery_query
gatt_browser
hfp_ag_demo
hfp_hf_demo
hsp_ag_demo
hsp_hs_demo
l2cap_test
le_counter
le_counter.h
le_streamer
le_streamer
le_streamer.h
led_counter
panu_demo
profile.h
sdp_bnep_query
sdp_general_query
sdp_rfcomm_query
sm_pairing_central
sm_pairing_peripheral
sm_pairing_peripheral.h
spp_and_le_counter
spp_and_le_counter.h
spp_counter
spp_streamer
spp_streamer
sco_input*
sco_output*

57
port/windows-h4/Makefile Normal file
View File

@ -0,0 +1,57 @@
# Makefile for windows-h4 examples
BTSTACK_ROOT = ../..
CORE += main.c stdin_support.c
COMMON += \
btstack_run_loop_windows.c \
hci_transport_h4.c \
btstack_uart_block_windows.c \
le_device_db_fs.c \
btstack_link_key_db_fs.c \
bluetooth_init_cc2564B_1.4_BT_Spec_4.1.c \
btstack_chipset_cc256x.c \
btstack_chipset_csr.c \
btstack_chipset_em9301.c \
btstack_chipset_stlc2500d.c \
btstack_chipset_tc3566x.c \
btstack_chipset_bcm.c \
# examples
include ${BTSTACK_ROOT}/example/Makefile.inc
# fetch and convert TI init scripts
include ${BTSTACK_ROOT}/chipset/cc256x/Makefile.inc
# fetch Broadcom init scripts
# include ${BTSTACK_ROOT}/chipset/bcm/Makefile.inc
# CC = gcc-fsf-4.9
CFLAGS += -g -Wall -Wmissing-prototypes -Wstrict-prototypes -Wshadow -Werror
# CFLAGS += -Werror
CFLAGS += -I${BTSTACK_ROOT}/platform/posix \
-I${BTSTACK_ROOT}/platform/windows \
-I${BTSTACK_ROOT}/platform/embedded \
-I$(BTSTACK_ROOT)/chipset/bcm \
-I$(BTSTACK_ROOT)/chipset/cc256x \
-I$(BTSTACK_ROOT)/chipset/csr \
-I$(BTSTACK_ROOT)/chipset/em9301 \
-I$(BTSTACK_ROOT)/chipset/stlc2500d \
-I$(BTSTACK_ROOT)/chipset/tc3566x \
VPATH += ${BTSTACK_ROOT}/platform/windows
VPATH += ${BTSTACK_ROOT}/platform/posix
VPATH += ${BTSTACK_ROOT}/chipset/bcm
VPATH += ${BTSTACK_ROOT}/chipset/cc256x
VPATH += ${BTSTACK_ROOT}/chipset/csr
VPATH += ${BTSTACK_ROOT}/chipset/em9301
VPATH += ${BTSTACK_ROOT}/chipset/stlc2500d
VPATH += ${BTSTACK_ROOT}/chipset/tc3566x
# assume portaudio is installed in /usr/local
# CFLAGS += -I/usr/local/include -DHAVE_PORTAUDIO
# LDFLAGS += -L/sw/lib -lportaudio
all: ${EXAMPLES}

View File

@ -0,0 +1,30 @@
//
// 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_POSIX_STDIN
#define HAVE_POSIX_TIME
// BTstack features that can be enabled
#define ENABLE_BLE
#define ENABLE_CLASSIC
#define ENABLE_LE_PERIPHERAL
#define ENABLE_LE_CENTRAL
#define ENABLE_LE_SECURE_CONNECTIONS
#define ENABLE_LOG_ERROR
#define ENABLE_LOG_INFO
#define ENABLE_LOG_INTO_HCI_DUMP
#define ENABLE_SCO_OVER_HCI
#define ENABLE_SDP_DES_DUMP
// BTstack configuration. buffers, sizes, ...
#define HCI_ACL_PAYLOAD_SIZE (1691 + 4)
#define HCI_INCOMING_PRE_BUFFER_SIZE 14 // sizeof BNEP header, avoid memcpy
#endif

188
port/windows-h4/main.c Normal file
View File

@ -0,0 +1,188 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include "btstack_config.h"
#include "btstack_debug.h"
#include "btstack_event.h"
#include "btstack_memory.h"
#include "btstack_run_loop.h"
#include "btstack_run_loop_windows.h"
#include "hci.h"
#include "hci_dump.h"
#include "hal_led.h"
#include "btstack_link_key_db_fs.h"
#include "stdin_support.h"
#include "btstack_chipset_bcm.h"
#include "btstack_chipset_csr.h"
#include "btstack_chipset_cc256x.h"
#include "btstack_chipset_em9301.h"
#include "btstack_chipset_stlc2500d.h"
#include "btstack_chipset_tc3566x.h"
int btstack_main(int argc, const char * argv[]);
static void local_version_information_handler(uint8_t * packet);
static hci_transport_config_uart_t config = {
HCI_TRANSPORT_CONFIG_UART,
115200,
0, // main baudrate
1, // flow control
NULL,
};
int is_bcm;
static int led_state = 0;
void hal_led_toggle(void){
led_state = 1 - led_state;
printf("LED State %u\n", led_state);
}
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 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){
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) break;
printf("BTstack up and running.\n");
break;
case HCI_EVENT_COMMAND_COMPLETE:
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_name)){
// terminate, name 248 chars
packet[6+248] = 0;
printf("Local name: %s\n", &packet[6]);
if (is_bcm){
btstack_chipset_bcm_set_device_name((const char *)&packet[6]);
}
}
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_version_information)){
local_version_information_handler(packet);
}
break;
default:
break;
}
}
static void use_fast_uart(void){
printf("Using 921600 baud.\n");
config.baudrate_main = 921600;
}
static void local_version_information_handler(uint8_t * packet){
printf("Local version information:\n");
uint16_t hci_version = little_endian_read_16(packet, 4);
uint16_t hci_revision = little_endian_read_16(packet, 6);
uint16_t lmp_version = little_endian_read_16(packet, 8);
uint16_t manufacturer = little_endian_read_16(packet, 10);
uint16_t lmp_subversion = little_endian_read_16(packet, 12);
printf("- HCI Version 0x%04x\n", hci_version);
printf("- HCI Revision 0x%04x\n", hci_revision);
printf("- LMP Version 0x%04x\n", lmp_version);
printf("- LMP Revision 0x%04x\n", lmp_subversion);
printf("- Manufacturer 0x%04x\n", manufacturer);
switch (manufacturer){
case COMPANY_ID_CAMBRIDGE_SILICON_RADIO:
printf("Cambridge Silicon Radio - CSR chipset.\n");
use_fast_uart();
hci_set_chipset(btstack_chipset_csr_instance());
break;
case COMPANY_ID_TEXAS_INSTRUMENTS_INC:
printf("Texas Instruments - CC256x compatible chipset.\n");
if (lmp_subversion != btstack_chipset_cc256x_lmp_subversion()){
printf("Error: LMP Subversion does not match initscript!");
printf("Your initscripts is for %s chipset\n", btstack_chipset_cc256x_lmp_subversion() < lmp_subversion ? "an older" : "a newer");
printf("Please update Makefile to include the appropriate bluetooth_init_cc256???.c file\n");
exit(10);
}
use_fast_uart();
hci_set_chipset(btstack_chipset_cc256x_instance());
#ifdef ENABLE_EHCILL
printf("eHCILL enabled.\n");
#else
printf("eHCILL disable.\n");
#endif
break;
case COMPANY_ID_BROADCOM_CORPORATION:
printf("Broadcom - using BCM driver.\n");
hci_set_chipset(btstack_chipset_bcm_instance());
use_fast_uart();
is_bcm = 1;
break;
case COMPANY_ID_ST_MICROELECTRONICS:
printf("ST Microelectronics - using STLC2500d driver.\n");
use_fast_uart();
hci_set_chipset(btstack_chipset_stlc2500d_instance());
break;
case COMPANY_ID_EM_MICROELECTRONICS_MARIN:
printf("EM Microelectronics - using EM9301 driver.\n");
hci_set_chipset(btstack_chipset_em9301_instance());
break;
case COMPANY_ID_NORDIC_SEMICONDUCTOR_ASA:
printf("Nordic Semiconductor nRF5 chipset.\n");
break;
default:
printf("Unknown manufacturer / manufacturer not supported yet.\n");
break;
}
}
int main(int argc, const char * argv[]){
printf("BTstack on windows booting up\n");
/// GET STARTED with BTstack ///
btstack_memory_init();
btstack_run_loop_init(btstack_run_loop_windows_get_instance());
hci_dump_open("hci_dump.pklg", HCI_DUMP_PACKETLOGGER);
// pick serial port
config.device_name = "\\\\.\\COM7";
// init HCI
const btstack_uart_block_t * uart_driver = btstack_uart_block_windows_instance();
const hci_transport_t * transport = hci_transport_h4_instance(uart_driver);
const btstack_link_key_db_t * link_key_db = btstack_link_key_db_fs_instance();
hci_init(transport, (void*) &config);
hci_set_link_key_db(link_key_db);
// inform about BTstack state
hci_event_callback_registration.callback = &packet_handler;
hci_add_event_handler(&hci_event_callback_registration);
// handle CTRL-c
signal(SIGINT, sigint_handler);
// setup app
btstack_main(argc, argv);
// go
btstack_run_loop_execute();
return 0;
}

39
port/windows-winusb/.gitignore vendored Normal file
View File

@ -0,0 +1,39 @@
ancs_client_demo
ancs_client_demo.h
ble_central_test
ble_peripheral_test
bnep_test
classic_test
gap_dedicated_bonding
gap_inquiry
gap_inquiry_and_bond
gap_le_advertisements
gap_le_advertisements
gatt_battery_query
gatt_browser
hfp_ag_demo
hfp_hf_demo
hsp_ag_demo
hsp_hs_demo
l2cap_test
le_counter
le_counter.h
le_streamer
le_streamer
le_streamer.h
led_counter
panu_demo
profile.h
sdp_bnep_query
sdp_general_query
sdp_rfcomm_query
sm_pairing_central
sm_pairing_peripheral
sm_pairing_peripheral.h
spp_and_le_counter
spp_and_le_counter.h
spp_counter
spp_streamer
spp_streamer
sco_input*
sco_output*

View File

@ -0,0 +1,33 @@
# Makefile for windows WinUSB based examples
BTSTACK_ROOT = ../..
CORE += main.c stdin_support.c
COMMON += hci_transport_h2_winusb.c btstack_run_loop_windows.c le_device_db_fs.c btstack_link_key_db_fs.c
include ${BTSTACK_ROOT}/example/Makefile.inc
# CC = gcc-fsf-4.9
CFLAGS += -g -Wall -Wmissing-prototypes -Wstrict-prototypes -Wshadow -Werror
# CFLAGS += -Werror
CFLAGS += -I${BTSTACK_ROOT}/platform/windows \
-I${BTSTACK_ROOT}/platform/posix \
-I${BTSTACK_ROOT}/platform/embedded
VPATH += ${BTSTACK_ROOT}/platform/embedded
VPATH += ${BTSTACK_ROOT}/platform/posix
VPATH += ${BTSTACK_ROOT}/platform/windows
# 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
LDFLAGS += -lsetupapi -lwinusb
EXAMPLES=le_counter hfp_hf_demo
all: ${EXAMPLES}

View File

@ -0,0 +1,30 @@
//
// 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_POSIX_STDIN
#define HAVE_POSIX_TIME
// BTstack features that can be enabled
#define ENABLE_BLE
#define ENABLE_CLASSIC
#define ENABLE_LE_PERIPHERAL
#define ENABLE_LE_CENTRAL
#define ENABLE_LE_SECURE_CONNECTIONS
#define ENABLE_LOG_ERROR
#define ENABLE_LOG_INFO
#define ENABLE_LOG_INTO_HCI_DUMP
#define ENABLE_SCO_OVER_HCI
#define ENABLE_SDP_DES_DUMP
// BTstack configuration. buffers, sizes, ...
#define HCI_ACL_PAYLOAD_SIZE (1691 + 4)
#define HCI_INCOMING_PRE_BUFFER_SIZE 14 // sizeof BNEP header, avoid memcpy
#endif

173
port/windows-winusb/main.c Normal file
View File

@ -0,0 +1,173 @@
/*
* 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
*
*/
// *****************************************************************************
//
// minimal setup for HCI code
//
// *****************************************************************************
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#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_windows.h"
#include "hal_led.h"
#include "hci.h"
#include "hci_dump.h"
#include "stdin_support.h"
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){
if (packet_type != HCI_EVENT_PACKET) return;
if (hci_event_packet_get_type(packet) != BTSTACK_EVENT_STATE) return;
if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return;
printf("BTstack up and running.\n");
}
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);
}
#define USB_MAX_PATH_LEN 7
int main(int argc, const char * argv[]){
// Prevent stdout buffering
setvbuf(stdout, NULL, _IONBF, 0);
printf("BTstack/windows-winusb booting up\n");
#if 0
int usb_path_len = 0;
uint8_t usb_path[USB_MAX_PATH_LEN];
if (argc >= 3 && strcmp(argv[1], "-u") == 0){
// parse command line options for "-u 11:22:33"
const char * port_str = argv[2];
printf("Specified USB Path: ");
while (1){
char * delimiter;
int port = strtol(port_str, &delimiter, 16);
usb_path[usb_path_len] = port;
usb_path_len++;
printf("%02x ", port);
if (!delimiter) break;
if (*delimiter != ':' && *delimiter != '-') break;
port_str = delimiter+1;
}
printf("\n");
}
#endif
/// GET STARTED with BTstack ///
btstack_memory_init();
btstack_run_loop_init(btstack_run_loop_windows_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
#if 1
char pklg_path[100];
strcpy(pklg_path, "hci_dump");
#if 0
if (usb_path_len){
strcat(pklg_path, "_");
strcat(pklg_path, argv[2]);
}
#endif
strcat(pklg_path, ".pklg");
printf("Packet Log: %s\n", pklg_path);
hci_dump_open(pklg_path, HCI_DUMP_PACKETLOGGER);
#else
hci_dump_open(NULL, HCI_DUMP_STDOUT);
#endif
// init HCI
hci_init(hci_transport_usb_instance(), NULL);
#ifdef ENABLE_CLASSIC
hci_set_link_key_db(btstack_link_key_db_fs_instance());
#endif
// inform about BTstack state
hci_event_callback_registration.callback = &packet_handler;
hci_add_event_handler(&hci_event_callback_registration);
// handle CTRL-c
signal(SIGINT, sigint_handler);
// setup app
btstack_main(argc, argv);
// go
btstack_run_loop_execute();
return 0;
}

View File

@ -65,14 +65,23 @@ typedef enum {
} btstack_data_source_callback_type_t;
typedef struct btstack_data_source {
//
// linked item
btstack_linked_item_t item;
// file descriptor to watch for run loops that support file descriptors
int fd;
// item to watch in run loop
union {
// file descriptor for posix systems
int fd;
// handle on windows
void * handle;
};
// callback to call for enabled callback types
void (*process)(struct btstack_data_source *ds, btstack_data_source_callback_type_t callback_type);
// flags storing enabled callback types
uint16_t flags;
} btstack_data_source_t;
typedef struct btstack_timer_source {

View File

@ -136,6 +136,7 @@ typedef struct {
// common implementations
const btstack_uart_block_t * btstack_uart_block_posix_instance(void);
const btstack_uart_block_t * btstack_uart_block_windows_instance(void);
const btstack_uart_block_t * btstack_uart_block_embedded_instance(void);
#endif

View File

@ -530,6 +530,8 @@ static int codecs_exchange_state_machine(hfp_connection_t * hfp_connection){
hfp_connection->codec_confirmed = hfp_connection->suggested_codec;
hfp_connection->ok_pending = 1;
hfp_connection->codecs_state = HFP_CODECS_HF_CONFIRMED_CODEC;
hfp_connection->negotiated_codec = hfp_connection->suggested_codec;
log_info("hfp: codec confirmed: %s", hfp_connection->negotiated_codec == HFP_CODEC_MSBC ? "mSBC" : "CVSD");
hfp_hf_cmd_confirm_codec(hfp_connection->rfcomm_cid, hfp_connection->codec_confirmed);
} else {
hfp_connection->codec_confirmed = 0;
@ -965,8 +967,6 @@ static void hfp_hf_switch_on_ok(hfp_connection_t *hfp_connection){
break;
case HFP_CODECS_HF_CONFIRMED_CODEC:
hfp_connection->codecs_state = HFP_CODECS_EXCHANGED;
hfp_connection->negotiated_codec = hfp_connection->suggested_codec;
log_info("hfp: codec confirmed: %s", hfp_connection->negotiated_codec == HFP_CODEC_MSBC ? "mSBC" : "CVSD");
break;
default:
break;

View File

@ -176,7 +176,7 @@ static void printf_timestamp(void){
}
#endif
void hci_dump_packet(uint8_t packet_type, uint8_t in, uint8_t *packet, uint16_t len) {
void hci_dump_packet(uint8_t packet_type, uint8_t in, uint8_t *packet, uint16_t len) {
if (dump_file < 0) return; // not activated yet

View File

@ -204,7 +204,6 @@ static int media_initialized = 0;
static int init_media_processing(avdtp_media_codec_configuration_sbc_t configuration){
int num_channels = configuration.num_channels;
int sample_rate = configuration.sampling_frequency;
int frames_per_buffer = configuration.frames_per_buffer;
#ifdef STORE_SBC_TO_WAV_FILE
btstack_sbc_decoder_init(&state, mode, handle_pcm_data, NULL);
@ -216,6 +215,7 @@ static int init_media_processing(avdtp_media_codec_configuration_sbc_t configura
#endif
#ifdef HAVE_PORTAUDIO
int frames_per_buffer = configuration.frames_per_buffer;
PaError err;
PaStreamParameters outputParameters;
@ -314,6 +314,8 @@ static void handle_l2cap_media_data_packet(avdtp_stream_endpoint_t * stream_endp
media_header.synchronization_source = big_endian_read_32(packet, pos);
pos+=4;
UNUSED(media_header);
// TODO: read csrc list
// printf_hexdump( packet, pos );
@ -329,6 +331,7 @@ static void handle_l2cap_media_data_packet(avdtp_stream_endpoint_t * stream_endp
sbc_header.num_frames = packet[pos] & 0x0f;
pos++;
UNUSED(sbc_header);
// printf("SBC HEADER: num_frames %u, fragmented %u, start %u, stop %u\n", sbc_header.num_frames, sbc_header.fragmentation, sbc_header.starting_packet, sbc_header.last_packet);
// printf_hexdump( packet+pos, size-pos );
@ -476,14 +479,13 @@ static const uint8_t media_sbc_codec_info[] = {
};
static void stdin_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type){
if (app_state != AVDTP_APPLICATION_IDLE) {
printf("Application is not idle.\n");
return;
}
char buffer;
read(ds->fd, &buffer, 1);
UNUSED(ds);
UNUSED(callback_type);
int cmd = btstack_stdin_read();
sep.seid = 1;
switch (buffer){
switch (cmd){
case 'c':
printf("Creating L2CAP Connection to %s, PSM_AVDTP\n", bd_addr_to_str(remote));
avdtp_sink_connect(remote);