mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-04-16 08:42:28 +00:00
windows: get_time_ms()
This commit is contained in:
parent
fd9ea8fd04
commit
4e630824c7
30
port/windows-h4/Makefile
Normal file
30
port/windows-h4/Makefile
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# 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 \
|
||||||
|
|
||||||
|
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/posix \
|
||||||
|
-I${BTSTACK_ROOT}/platform/embedded
|
||||||
|
|
||||||
|
VPATH += ${BTSTACK_ROOT}/platform/embedded
|
||||||
|
VPATH += ${BTSTACK_ROOT}/platform/posix
|
||||||
|
VPATH += ${BTSTACK_ROOT}/platform/libusb
|
||||||
|
|
||||||
|
# assume portaudio is installed in /usr/local
|
||||||
|
# CFLAGS += -I/usr/local/include -DHAVE_PORTAUDIO
|
||||||
|
# LDFLAGS += -L/sw/lib -lportaudio
|
||||||
|
|
||||||
|
all: ${EXAMPLES}
|
28
port/windows-h4/btstack_config.h
Normal file
28
port/windows-h4/btstack_config.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// 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_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
|
275
port/windows-h4/btstack_run_loop_windows.c
Normal file
275
port/windows-h4/btstack_run_loop_windows.c
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
/*
|
||||||
|
* 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) {
|
||||||
|
#if 0
|
||||||
|
fd_set descriptors_read;
|
||||||
|
fd_set descriptors_write;
|
||||||
|
|
||||||
|
btstack_timer_source_t *ts;
|
||||||
|
btstack_linked_list_iterator_t it;
|
||||||
|
struct timeval * timeout;
|
||||||
|
struct timeval tv;
|
||||||
|
uint32_t now_ms;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
// collect FDs
|
||||||
|
FD_ZERO(&descriptors_read);
|
||||||
|
FD_ZERO(&descriptors_write);
|
||||||
|
int highest_fd = -1;
|
||||||
|
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->fd < 0) continue;
|
||||||
|
if (ds->flags & DATA_SOURCE_CALLBACK_READ){
|
||||||
|
FD_SET(ds->fd, &descriptors_read);
|
||||||
|
if (ds->fd > highest_fd) {
|
||||||
|
highest_fd = ds->fd;
|
||||||
|
}
|
||||||
|
log_debug("btstack_run_loop_execute adding fd %u for read", ds->fd);
|
||||||
|
}
|
||||||
|
if (ds->flags & DATA_SOURCE_CALLBACK_WRITE){
|
||||||
|
FD_SET(ds->fd, &descriptors_write);
|
||||||
|
if (ds->fd > highest_fd) {
|
||||||
|
highest_fd = ds->fd;
|
||||||
|
}
|
||||||
|
log_debug("btstack_run_loop_execute adding fd %u for write", ds->fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get next timeout
|
||||||
|
timeout = NULL;
|
||||||
|
if (timers) {
|
||||||
|
ts = (btstack_timer_source_t *) timers;
|
||||||
|
timeout = &tv;
|
||||||
|
now_ms = btstack_run_loop_windows_get_time_ms();
|
||||||
|
int delta = ts->timeout - now_ms;
|
||||||
|
if (delta < 0){
|
||||||
|
delta = 0;
|
||||||
|
}
|
||||||
|
tv.tv_sec = delta / 1000;
|
||||||
|
tv.tv_usec = (int) (delta - (tv.tv_sec * 1000)) * 1000;
|
||||||
|
log_debug("btstack_run_loop_execute next timeout in %u ms", delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for ready FDs
|
||||||
|
select( highest_fd+1 , &descriptors_read, &descriptors_write, NULL, timeout);
|
||||||
|
|
||||||
|
|
||||||
|
data_sources_modified = 0;
|
||||||
|
btstack_linked_list_iterator_init(&it, &data_sources);
|
||||||
|
while (btstack_linked_list_iterator_has_next(&it) && !data_sources_modified){
|
||||||
|
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 fd %u\n", ds, ds->fd);
|
||||||
|
if (FD_ISSET(ds->fd, &descriptors_read)) {
|
||||||
|
log_debug("btstack_run_loop_windows_execute: process read ds %p with fd %u\n", ds, ds->fd);
|
||||||
|
ds->process(ds, DATA_SOURCE_CALLBACK_READ);
|
||||||
|
}
|
||||||
|
if (FD_ISSET(ds->fd, &descriptors_write)) {
|
||||||
|
log_debug("btstack_run_loop_windows_execute: process write ds %p with fd %u\n", ds, ds->fd);
|
||||||
|
ds->process(ds, DATA_SOURCE_CALLBACK_WRITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log_debug("btstack_run_loop_windows_execute: after ds check\n");
|
||||||
|
|
||||||
|
// process timers
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
63
port/windows-h4/btstack_run_loop_windows.h
Normal file
63
port/windows-h4/btstack_run_loop_windows.h
Normal 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
|
315
port/windows-h4/btstack_uart_block_windows.c
Normal file
315
port/windows-h4/btstack_uart_block_windows.c
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
/*
|
||||||
|
* 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>
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
|
||||||
|
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) {
|
||||||
|
#if 0
|
||||||
|
if (write_bytes_len == 0) return;
|
||||||
|
|
||||||
|
uint32_t start = btstack_run_loop_get_time_ms();
|
||||||
|
|
||||||
|
// write up to write_bytes_len to fd
|
||||||
|
int bytes_written = (int) write(ds->fd, write_bytes_data, write_bytes_len);
|
||||||
|
if (bytes_written < 0) {
|
||||||
|
btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t end = btstack_run_loop_get_time_ms();
|
||||||
|
if (end - start > 10){
|
||||||
|
log_info("h4_process: write took %u ms", end - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
write_bytes_data += bytes_written;
|
||||||
|
write_bytes_len -= bytes_written;
|
||||||
|
|
||||||
|
if (write_bytes_len){
|
||||||
|
btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE);
|
||||||
|
|
||||||
|
// notify done
|
||||||
|
if (block_sent){
|
||||||
|
block_sent();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void btstack_uart_windows_process_read(btstack_data_source_t *ds) {
|
||||||
|
#if 0
|
||||||
|
if (read_bytes_len == 0) {
|
||||||
|
log_info("btstack_uart_windows_process_read but no read requested");
|
||||||
|
btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t start = btstack_run_loop_get_time_ms();
|
||||||
|
|
||||||
|
// read up to bytes_to_read data in
|
||||||
|
ssize_t bytes_read = read(ds->fd, read_bytes_data, read_bytes_len);
|
||||||
|
// log_info("btstack_uart_windows_process_read need %u bytes, got %d", read_bytes_len, (int) bytes_read);
|
||||||
|
uint32_t end = btstack_run_loop_get_time_ms();
|
||||||
|
if (end - start > 10){
|
||||||
|
log_info("h4_process: read took %u ms", end - start);
|
||||||
|
}
|
||||||
|
if (bytes_read < 0) return;
|
||||||
|
|
||||||
|
read_bytes_len -= bytes_read;
|
||||||
|
read_bytes_data += bytes_read;
|
||||||
|
if (read_bytes_len > 0) return;
|
||||||
|
|
||||||
|
btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ);
|
||||||
|
|
||||||
|
if (block_received){
|
||||||
|
block_received();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void btstack_uart_windows_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) {
|
||||||
|
switch (callback_type){
|
||||||
|
case DATA_SOURCE_CALLBACK_READ:
|
||||||
|
btstack_uart_windows_process_read(ds);
|
||||||
|
break;
|
||||||
|
case DATA_SOURCE_CALLBACK_WRITE:
|
||||||
|
btstack_uart_windows_process_write(ds);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int btstack_uart_windows_set_baudrate(uint32_t baudrate){
|
||||||
|
// TODO: implement
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int btstack_uart_windows_open(void){
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
const char * device_name = uart_config->device_name;
|
||||||
|
const int flowcontrol = uart_config->flowcontrol;
|
||||||
|
const uint32_t baudrate = uart_config->baudrate;
|
||||||
|
|
||||||
|
struct termios toptions;
|
||||||
|
int flags = O_RDWR | O_NOCTTY | O_NONBLOCK;
|
||||||
|
int fd = open(device_name, flags);
|
||||||
|
if (fd == -1) {
|
||||||
|
log_error("posix_open: Unable to open port %s", device_name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tcgetattr(fd, &toptions) < 0) {
|
||||||
|
log_error("posix_open: Couldn't get term attributes");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfmakeraw(&toptions); // make raw
|
||||||
|
|
||||||
|
// 8N1
|
||||||
|
toptions.c_cflag &= ~CSTOPB;
|
||||||
|
toptions.c_cflag |= CS8;
|
||||||
|
|
||||||
|
// 8E1
|
||||||
|
// toptions.c_cflag |= PARENB; // enable even parity
|
||||||
|
//
|
||||||
|
|
||||||
|
if (flowcontrol) {
|
||||||
|
// with flow control
|
||||||
|
toptions.c_cflag |= CRTSCTS;
|
||||||
|
} else {
|
||||||
|
// no flow control
|
||||||
|
toptions.c_cflag &= ~CRTSCTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
toptions.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines
|
||||||
|
toptions.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl
|
||||||
|
|
||||||
|
// see: http://unixwiz.net/techtips/termios-vmin-vtime.html
|
||||||
|
toptions.c_cc[VMIN] = 1;
|
||||||
|
toptions.c_cc[VTIME] = 0;
|
||||||
|
|
||||||
|
if(tcsetattr(fd, TCSANOW, &toptions) < 0) {
|
||||||
|
log_error("posix_open: Couldn't set term attributes");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// store fd in data source
|
||||||
|
transport_data_source.fd = fd;
|
||||||
|
|
||||||
|
// also set baudrate
|
||||||
|
if (btstack_uart_windows_set_baudrate(baudrate) < 0){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up data_source
|
||||||
|
btstack_run_loop_set_data_source_fd(&transport_data_source, fd);
|
||||||
|
#endif
|
||||||
|
btstack_run_loop_set_data_source_handler(&transport_data_source, &btstack_uart_windows_process);
|
||||||
|
// btstack_run_loop_add_data_source(&transport_data_source);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int btstack_uart_windows_close_new(void){
|
||||||
|
|
||||||
|
// first remove run loop handler
|
||||||
|
btstack_run_loop_remove_data_source(&transport_data_source);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// then close device
|
||||||
|
close(transport_data_source.fd);
|
||||||
|
transport_data_source.fd = -1;
|
||||||
|
#endif
|
||||||
|
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 int btstack_uart_windows_set_parity(int parity){
|
||||||
|
#if 0
|
||||||
|
int fd = transport_data_source.fd;
|
||||||
|
|
||||||
|
struct termios toptions;
|
||||||
|
if (tcgetattr(fd, &toptions) < 0) {
|
||||||
|
log_error("btstack_uart_windows_set_parity: Couldn't get term attributes");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (parity){
|
||||||
|
toptions.c_cflag |= PARENB; // enable even parity
|
||||||
|
} else {
|
||||||
|
toptions.c_cflag &= ~PARENB; // enable even parity
|
||||||
|
}
|
||||||
|
if(tcsetattr(fd, TCSANOW, &toptions) < 0) {
|
||||||
|
log_error("posix_set_parity: Couldn't set term attributes");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// go
|
||||||
|
// btstack_uart_windows_process_write(&transport_data_source);
|
||||||
|
btstack_run_loop_enable_data_source_callbacks(&transport_data_source, DATA_SOURCE_CALLBACK_WRITE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void btstack_uart_windows_receive_block(uint8_t *buffer, uint16_t len){
|
||||||
|
read_bytes_data = buffer;
|
||||||
|
read_bytes_len = len;
|
||||||
|
btstack_run_loop_enable_data_source_callbacks(&transport_data_source, DATA_SOURCE_CALLBACK_READ);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// go
|
||||||
|
// btstack_uart_windows_process_read(&transport_data_source);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
37
port/windows-h4/main.c
Normal file
37
port/windows-h4/main.c
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#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"
|
||||||
|
|
||||||
|
static int led_state = 0;
|
||||||
|
void hal_led_toggle(void){
|
||||||
|
led_state = 1 - led_state;
|
||||||
|
printf("LED State %u\n", led_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, 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());
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
printf("time ms %u\n", btstack_run_loop_get_time_ms());
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user