mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-20 18:40:31 +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