Permalink
Browse files

windows: repeat UART read/write operation if not all bytes have been …

…read or written
  • Loading branch information...
mringwal committed Jan 4, 2018
1 parent a1a8565 commit 5b81efe2932eb28c77d4817bca75c0006be99b68
Showing with 98 additions and 79 deletions.
  1. +98 −79 platform/windows/btstack_uart_block_windows.c
@@ -79,12 +79,84 @@ static HANDLE serial_port_handle;
static OVERLAPPED overlapped_read;
static OVERLAPPED overlapped_write;
// -- engine that retries send/receive if not all bytes have been transferred
static int btstack_uart_windows_init(const btstack_uart_config_t * config){
uart_config = config;
return 0;
static void btstack_uart_windows_send_engine(void){
// 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_engine(void){
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("error reading");
return;
}
// IO_PENDING -> wait for completed
btstack_run_loop_enable_data_source_callbacks(&transport_data_source_read, DATA_SOURCE_CALLBACK_READ);
}
// -- overlapped IO handlers for read & write
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);
@@ -97,14 +169,17 @@ static void btstack_uart_windows_process_write(btstack_data_source_t *ds, btstac
// 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");
log_error("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);
log_debug("write: requested to write %u but %u were written, try again", (int) write_bytes_len, (int) bytes_written);
btstack_uart_windows_send_engine();
write_bytes_data += bytes_written;
write_bytes_len -= bytes_written;
return;
}
@@ -114,6 +189,7 @@ static void btstack_uart_windows_process_write(btstack_data_source_t *ds, btstac
}
}
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);
@@ -126,14 +202,18 @@ static void btstack_uart_windows_process_read(btstack_data_source_t *ds, btstack
// 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");
log_error("error reading");
}
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);
log_debug("read: requested read %u but %u were read, try again", (int) read_bytes_len, (int) bytes_read);
read_bytes_data += bytes_read;
read_bytes_len -= bytes_read;
btstack_uart_windows_receive_engine();
return;
}
@@ -143,90 +223,29 @@ static void btstack_uart_windows_process_read(btstack_data_source_t *ds, btstack
}
}
static void btstack_uart_windows_send_block(const uint8_t *data, uint16_t size){
// -- API implementation
static int btstack_uart_windows_init(const btstack_uart_config_t * config){
uart_config = config;
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;
// 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);
// go
btstack_uart_windows_send_engine();
}
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);
btstack_uart_windows_receive_engine();
}
static void btstack_uart_windows_set_baudrate_option(DCB * serial_params, uint32_t baudrate){
@@ -444,4 +463,4 @@ static const btstack_uart_block_t btstack_uart_windows = {
const btstack_uart_block_t * btstack_uart_block_windows_instance(void){
return &btstack_uart_windows;
}
}

0 comments on commit 5b81efe

Please sign in to comment.