mirror of
git://sigrok.org/libserialport
synced 2023-08-10 21:13:24 +03:00
Compare commits
93 Commits
libserialp
...
master
Author | SHA1 | Date | |
---|---|---|---|
6f9b03e597 | |||
1abec20502 | |||
a06a765515 | |||
1b011060df | |||
086a418145 | |||
ffbfc5c76b | |||
0a24247de8 | |||
251890e3b9 | |||
ba49ee82db | |||
2913355f7e | |||
6711e43e9b | |||
75a280a597 | |||
7b0686ed58 | |||
4349b1f6a2 | |||
cd1a7d4361 | |||
d81a4dfdc6 | |||
78c3db9bfb | |||
42b3cf3b98 | |||
fb58f12ee9 | |||
2be41b1265 | |||
f6abee5c78 | |||
6339fa04d6 | |||
28981e0793 | |||
67b55d10b8 | |||
d8c4d388e8 | |||
d6412d2801 | |||
60fc49ceab | |||
41fc921ce4 | |||
528e8c0002 | |||
988ace6c9f | |||
bf40b1cea9 | |||
e47c7dcbff | |||
2149db9e93 | |||
4651adb4f6 | |||
75f468923b | |||
e919e2efaa | |||
a20ed2965b | |||
4720053160 | |||
6dba844779 | |||
9ddf08588d | |||
0838c979cc | |||
f6e32b2dfa | |||
6aaf844863 | |||
fdbb55ae1e | |||
a9900f8b64 | |||
e9d78d82c4 | |||
8488868187 | |||
c79e0ac8ef | |||
060d1d8a73 | |||
8073f87d45 | |||
39acdc47db | |||
bd72614f08 | |||
9d1ca7c855 | |||
3317d678de | |||
08eb25f53a | |||
32dbe2d298 | |||
9a7945af84 | |||
d9cc984fe7 | |||
44df415480 | |||
89c3d63e1a | |||
ee12a01e52 | |||
ad19d60493 | |||
7c8d67efdc | |||
8c1a14e658 | |||
abd31fd9f9 | |||
277f832a6a | |||
9118f753f4 | |||
fa106ef155 | |||
bd0fb6094f | |||
7fb9a7b0a7 | |||
192e77492a | |||
f40ea9d461 | |||
46bdc20c26 | |||
573feabc63 | |||
b457865b8f | |||
39df7833f7 | |||
6bd6a8b520 | |||
55ab7e0b6b | |||
81243567bc | |||
2e0437c28e | |||
38b71192dd | |||
a84ffb5372 | |||
42ad781896 | |||
62ed9f801a | |||
15541ebd78 | |||
95bad38c5b | |||
2a6c24be33 | |||
6c8115820d | |||
d8de88de32 | |||
0b53933127 | |||
5ec2f93bce | |||
df3b70a888 | |||
b2359c5c99 |
6
.gitignore
vendored
6
.gitignore
vendored
@ -12,7 +12,11 @@
|
||||
/configure
|
||||
/configure.lineno
|
||||
/libserialport-*.tar.*
|
||||
/libserialport.h
|
||||
/libserialport.pc
|
||||
/libtool
|
||||
stamp-h?
|
||||
.vs/
|
||||
Debug/
|
||||
Release/
|
||||
x64/
|
||||
*.vcxproj.user
|
||||
|
19
Makefile.am
19
Makefile.am
@ -24,10 +24,13 @@ GNUMAKEFLAGS = --no-print-directory
|
||||
|
||||
# Enable more compiler warnings.
|
||||
AM_CFLAGS = -std=c99 -Wall -Wextra -pedantic -Wmissing-prototypes -Wshadow
|
||||
# Set flag used in libserialport.h to indicate we are building the library
|
||||
# using autotools.
|
||||
AM_CFLAGS += -DLIBSERIALPORT_ATBUILD
|
||||
|
||||
lib_LTLIBRARIES = libserialport.la
|
||||
|
||||
libserialport_la_SOURCES = serialport.c libserialport_internal.h
|
||||
libserialport_la_SOURCES = serialport.c timing.c libserialport_internal.h
|
||||
if LINUX
|
||||
libserialport_la_SOURCES += linux.c linux_termios.c linux_termios.h
|
||||
endif
|
||||
@ -53,7 +56,19 @@ nodist_include_HEADERS = libserialport.h
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libserialport.pc
|
||||
|
||||
EXTRA_DIST = Doxyfile
|
||||
TESTS = test_timing
|
||||
check_PROGRAMS = test_timing
|
||||
test_timing_SOURCES = timing.c test_timing.c
|
||||
test_timing_CFLAGS = $(AM_CFLAGS)
|
||||
|
||||
EXTRA_DIST = Doxyfile \
|
||||
examples/Makefile \
|
||||
examples/README \
|
||||
examples/list_ports.c \
|
||||
examples/port_info.c \
|
||||
examples/port_config.c \
|
||||
examples/await_events.c \
|
||||
examples/handle_errors.c
|
||||
|
||||
MAINTAINERCLEANFILES = ChangeLog
|
||||
|
||||
|
38
README
38
README
@ -40,18 +40,27 @@ No other libraries are required.
|
||||
Building
|
||||
========
|
||||
|
||||
The package uses a GNU style build system and requires a Unix style shell.
|
||||
On Windows, libserialport can be built with Visual Studio 2019 or with
|
||||
the standalone MSBuild tool, using the solution and project files provided.
|
||||
|
||||
Windows builds can be created natively with the MinGW-w64 toolchain and
|
||||
MSYS2 environment, or cross-compiled using a MinGW-w64 toolchain:
|
||||
|
||||
http://mingw-w64.sourceforge.net/
|
||||
|
||||
The "old" MinGW from http://mingw.org/ is not supported.
|
||||
For other environments, the package uses a GNU style build based on autotools.
|
||||
|
||||
Run "./autogen.sh" to generate the build system, "./configure" to setup, then
|
||||
"make" to build the library and "make install" to install it.
|
||||
|
||||
Windows builds can also be created using the autotools build system, using the
|
||||
MinGW-w64 toolchain from http://mingw-w64.sourceforge.net/ - either natively
|
||||
in Windows with the MSYS2 environment, or cross-compiling from another system.
|
||||
|
||||
To build from MSYS2, the following packages must be installed: autoconf,
|
||||
automake-wrapper, libtool, make, and either mingw-w64-i686-gcc (for 32-bit)
|
||||
or mingw-w64-x86_64-gcc (for 64-bit). Open either the "MSYS2 MinGW 32-bit" or
|
||||
"MSYS2 MinGW 64-bit" command window from the Start menu and use this when
|
||||
configuring and building the package. Using the "MSYS2 MSYS" shell will build
|
||||
against the Cygwin compatibility layer; this works, but port enumeration and
|
||||
metadata will not be available, and binaries will depend on Cygwin. The builds
|
||||
produced by MinGW-w64 are normal Windows DLLs without additional dependencies.
|
||||
|
||||
API
|
||||
===
|
||||
|
||||
@ -61,6 +70,21 @@ It can also be viewed online at:
|
||||
|
||||
http://sigrok.org/api/libserialport/unstable/
|
||||
|
||||
Bug reports
|
||||
===========
|
||||
|
||||
You can report bugs for libserialport at https://sigrok.org/bugzilla.
|
||||
|
||||
Mailing list
|
||||
============
|
||||
|
||||
https://lists.sourceforge.net/lists/listinfo/sigrok-devel
|
||||
|
||||
IRC
|
||||
===
|
||||
|
||||
You can find the developers in the #sigrok IRC channel on Libera.Chat.
|
||||
|
||||
Website
|
||||
=======
|
||||
|
||||
|
23
common.props
Normal file
23
common.props
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Label="PropertySheets" />
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_PropertySheetDisplayName>Common</_PropertySheetDisplayName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalDependencies>setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup />
|
||||
</Project>
|
54
configure.ac
54
configure.ac
@ -29,7 +29,7 @@ m4_define([sp_package_version], [sp_package_version_major.sp_package_version_min
|
||||
|
||||
AC_INIT([libserialport], [sp_package_version], [martin-libserialport@earth.li],
|
||||
[libserialport], [http://sigrok.org/wiki/Libserialport])
|
||||
AC_CONFIG_HEADERS([config.h libserialport.h])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIR([autostuff])
|
||||
AC_CONFIG_AUX_DIR([autostuff])
|
||||
|
||||
@ -50,6 +50,19 @@ AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
|
||||
## SP_PROG_VERSION(program, sh-var)
|
||||
## Obtain the version of <program> and store it in <sh-var>.
|
||||
AC_DEFUN([SP_PROG_VERSION],
|
||||
[dnl
|
||||
m4_assert([$# >= 2])[]dnl
|
||||
sp_prog_ver=`$1 --version 2>&AS_MESSAGE_LOG_FD | sed 1q 2>&AS_MESSAGE_LOG_FD`
|
||||
AS_CASE([[$]?:$sp_prog_ver],
|
||||
[[0:*[0-9].[0-9]*]], [$2=$sp_prog_ver],
|
||||
[$2=unknown])[]dnl
|
||||
])
|
||||
|
||||
SP_PROG_VERSION([$CC], [sp_cc_version])
|
||||
|
||||
# Initialize libtool.
|
||||
LT_INIT
|
||||
|
||||
@ -74,18 +87,21 @@ AC_DEFINE_UNQUOTED([SP_LIB_VERSION_REVISION], [$SP_LIB_VERSION_REVISION], [.])
|
||||
AC_DEFINE_UNQUOTED([SP_LIB_VERSION_AGE], [$SP_LIB_VERSION_AGE], [.])
|
||||
AC_DEFINE_UNQUOTED([SP_LIB_VERSION_STRING], ["$SP_LIB_VERSION"], [.])
|
||||
|
||||
AM_CONDITIONAL([LINUX], [test -z "${host_os##linux*}"])
|
||||
AM_CONDITIONAL([WIN32], [test -z "${host_os##mingw*}" || test -z "${host_os##cygwin*}"])
|
||||
AM_CONDITIONAL([LINUX], [test -z "${host_os##linux*}" || test -z "${host_os##uclinux*}"])
|
||||
AM_CONDITIONAL([WIN32], [test -z "${host_os##mingw*}"])
|
||||
AM_CONDITIONAL([MACOSX], [test -z "${host_os##darwin*}"])
|
||||
AM_CONDITIONAL([FREEBSD], [test -z "${host_os##freebsd*}"])
|
||||
|
||||
AM_COND_IF([WIN32], [SP_LIBS='-lsetupapi'], [SP_LIBS=])
|
||||
AC_SUBST([SP_LIBS])
|
||||
|
||||
AM_COND_IF([FREEBSD], [SP_PKGLIBS='libusb-2.0'], [SP_PKGLIBS=])
|
||||
AC_SUBST([SP_PKGLIBS])
|
||||
|
||||
AM_COND_IF([MACOSX], [AC_CHECK_HEADER([IOKit/IOKitLib.h], [],
|
||||
[AC_MSG_ERROR([IOKit/IOKitLib.h not found])])])
|
||||
|
||||
AS_CASE([$host_os], [linux*|darwin*|mingw*|cygwin*|freebsd*],, [
|
||||
AS_CASE([$host_os], [linux*|darwin*|mingw*|freebsd*],, [
|
||||
AC_DEFINE([NO_ENUMERATION], [1], [Enumeration is unsupported.])
|
||||
AC_DEFINE([NO_PORT_METADATA], [1], [Port metadata is unavailable.])
|
||||
])
|
||||
@ -96,7 +112,7 @@ AC_SYS_LARGEFILE
|
||||
AC_TYPE_SIZE_T
|
||||
|
||||
# Check for specific termios structures.
|
||||
AC_CHECK_TYPES([struct termios2, struct termiox],,,
|
||||
AC_CHECK_TYPES([struct termios2],,,
|
||||
[[#include <linux/termios.h>]])
|
||||
AC_CHECK_MEMBERS([struct termios.c_ispeed, struct termios.c_ospeed,
|
||||
struct termios2.c_ispeed, struct termios2.c_ospeed],,,
|
||||
@ -110,6 +126,17 @@ AC_CHECK_DECLS([BOTHER],,, [[#include <linux/termios.h>]])
|
||||
# Check for serial_struct.
|
||||
AC_CHECK_TYPES([struct serial_struct],,, [[#include <linux/serial.h>]])
|
||||
|
||||
# Check for realpath().
|
||||
AC_CHECK_FUNC([realpath], [AC_DEFINE(HAVE_REALPATH, 1, [realpath is available.])], [])
|
||||
|
||||
# Check for flock().
|
||||
AC_CHECK_HEADER([sys/file.h], [AC_DEFINE(HAVE_SYS_FILE_H, 1, [sys/file.h is available.])], [])
|
||||
AC_CHECK_FUNC([flock], [AC_DEFINE(HAVE_FLOCK, 1, [flock is available.])], [])
|
||||
|
||||
# Check for clock_gettime().
|
||||
AC_CHECK_FUNC([clock_gettime],
|
||||
[AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [clock_gettime is available.])], [])
|
||||
|
||||
AC_CACHE_CHECK([for visibility control], [sp_cv_visibility_control], [
|
||||
sp_saved_CFLAGS=$CFLAGS
|
||||
CFLAGS="$CFLAGS -Werror"
|
||||
@ -138,10 +165,17 @@ cat >&AS_MESSAGE_FD <<_EOF
|
||||
|
||||
libserialport configuration summary:
|
||||
|
||||
- Package version (major.minor.micro): $SP_PACKAGE_VERSION
|
||||
- Library version (current:revision:age): $SP_LIB_VERSION
|
||||
- Prefix: $prefix
|
||||
- Building on: $build
|
||||
- Building for: $host
|
||||
- Package version................. $SP_PACKAGE_VERSION
|
||||
- Library ABI version............. $SP_LIB_VERSION
|
||||
- Prefix.......................... $prefix
|
||||
- Building on..................... $build
|
||||
- Building for.................... $host
|
||||
- Building shared / static........ $enable_shared / $enable_static
|
||||
|
||||
Compile configuration:
|
||||
- C compiler...................... $CC
|
||||
- C compiler version.............. $sp_cc_version
|
||||
- C compiler flags................ $CFLAGS
|
||||
- Linker flags.................... $LDFLAGS
|
||||
|
||||
_EOF
|
||||
|
17
debug.props
Normal file
17
debug.props
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Label="PropertySheets" />
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_PropertySheetDisplayName>Debug</_PropertySheetDisplayName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>LIBSERIALPORT_MSBUILD;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup />
|
||||
</Project>
|
6
examples/.gitignore
vendored
Normal file
6
examples/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
await_events
|
||||
handle_errors
|
||||
list_ports
|
||||
port_info
|
||||
port_config
|
||||
send_receive
|
20
examples/Makefile
Normal file
20
examples/Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
# A simple Makefile to build the examples in this directory.
|
||||
#
|
||||
# This example file is released to the public domain.
|
||||
|
||||
CC = gcc
|
||||
PKG_CONFIG = pkg-config
|
||||
CFLAGS = -g -Wall $(shell $(PKG_CONFIG) --cflags libserialport)
|
||||
LIBS = $(shell $(PKG_CONFIG) --libs libserialport)
|
||||
|
||||
SOURCES = $(wildcard *.c)
|
||||
|
||||
BINARIES = $(SOURCES:.c=)
|
||||
|
||||
%: %.c
|
||||
$(CC) $(CFLAGS) $< $(LIBS) -o $@
|
||||
|
||||
all: $(BINARIES)
|
||||
|
||||
clean:
|
||||
rm $(BINARIES)
|
33
examples/README
Normal file
33
examples/README
Normal file
@ -0,0 +1,33 @@
|
||||
This directory contains example programs showing how to use libserialport.
|
||||
|
||||
The examples currently included are:
|
||||
|
||||
list_ports.c - displays a list of ports on the system.
|
||||
port_info.c - displays info about a particular port on the system.
|
||||
port_config.c - sets and displays configuration settings on a port.
|
||||
send_receive.c - loopback test sending & receiving data on 1 or 2 ports.
|
||||
await_events.c - awaits receive events on multiple ports simultaneously.
|
||||
handle_errors.c - demonstrates handling errors returned from the library.
|
||||
|
||||
The programs themselves are completely OS-independent, and require only a
|
||||
C compiler and libserialport.
|
||||
|
||||
The 'examples.sln' file is a solution file for Microsoft Visual Studio 2019
|
||||
which will build libserialport and all of the example programs.
|
||||
|
||||
The Makefile in this directory will attempt to build all the examples,
|
||||
using 'gcc' to compile them and 'pkg-config' to discover the include
|
||||
paths and linker settings needed to build with libserialport. It provides
|
||||
a minimal example of how to write a Makefile to build a program using
|
||||
libserialport.
|
||||
|
||||
If you have make, gcc, pkg-config and libserialport installed correctly
|
||||
then running 'make' should build the example programs in this directory.
|
||||
If this doesn't work, you may need to modify the Makefile or set necessary
|
||||
paths in your environment to suit your system.
|
||||
|
||||
You can also build these examples using any other compiler, IDE or build
|
||||
system. You just need the libserialport.h header available to compile them,
|
||||
and the libserialport library available to link and run them.
|
||||
|
||||
These example files are hereby released into the public domain by the author.
|
101
examples/await_events.c
Normal file
101
examples/await_events.c
Normal file
@ -0,0 +1,101 @@
|
||||
#include <libserialport.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Example of how to wait for events on multiple ports.
|
||||
*
|
||||
* This example file is released to the public domain. */
|
||||
|
||||
/* Helper function for error handling. */
|
||||
int check(enum sp_return result);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* Get the port names from the command line. */
|
||||
if (argc < 2) {
|
||||
printf("Usage: %s <port name>...\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
int num_ports = argc - 1;
|
||||
char **port_names = argv + 1;
|
||||
|
||||
/* The ports we will use. */
|
||||
struct sp_port **ports = malloc(num_ports * sizeof(struct sp_port *));
|
||||
if (!ports)
|
||||
abort();
|
||||
|
||||
/* The set of events we will wait for. */
|
||||
struct sp_event_set *event_set;
|
||||
|
||||
/* Allocate the event set. */
|
||||
check(sp_new_event_set(&event_set));
|
||||
|
||||
/* Open and configure each port, and then add its RX event
|
||||
* to the event set. */
|
||||
for (int i = 0; i < num_ports; i++) {
|
||||
printf("Looking for port %s.\n", port_names[i]);
|
||||
check(sp_get_port_by_name(port_names[i], &ports[i]));
|
||||
|
||||
printf("Opening port.\n");
|
||||
check(sp_open(ports[i], SP_MODE_READ));
|
||||
|
||||
printf("Setting port to 9600 8N1, no flow control.\n");
|
||||
check(sp_set_baudrate(ports[i], 9600));
|
||||
check(sp_set_bits(ports[i], 8));
|
||||
check(sp_set_parity(ports[i], SP_PARITY_NONE));
|
||||
check(sp_set_stopbits(ports[i], 1));
|
||||
check(sp_set_flowcontrol(ports[i], SP_FLOWCONTROL_NONE));
|
||||
|
||||
printf("Adding port RX event to event set.\n");
|
||||
check(sp_add_port_events(event_set, ports[i], SP_EVENT_RX_READY));
|
||||
}
|
||||
|
||||
/* Now we can call sp_wait() to await any event in the set.
|
||||
* It will return when an event occurs, or the timeout elapses. */
|
||||
printf("Waiting up to 5 seconds for RX on any port...\n");
|
||||
check(sp_wait(event_set, 5000));
|
||||
|
||||
/* Iterate over ports to see which have data waiting. */
|
||||
for (int i = 0; i < num_ports; i++) {
|
||||
/* Get number of bytes waiting. */
|
||||
int bytes_waiting = check(sp_input_waiting(ports[i]));
|
||||
printf("Port %s: %d bytes received.\n",
|
||||
sp_get_port_name(ports[i]), bytes_waiting);
|
||||
}
|
||||
|
||||
/* Close ports and free resources. */
|
||||
sp_free_event_set(event_set);
|
||||
for (int i = 0; i < num_ports; i++) {
|
||||
check(sp_close(ports[i]));
|
||||
sp_free_port(ports[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper function for error handling. */
|
||||
int check(enum sp_return result)
|
||||
{
|
||||
/* For this example we'll just exit on any error by calling abort(). */
|
||||
char *error_message;
|
||||
|
||||
switch (result) {
|
||||
case SP_ERR_ARG:
|
||||
printf("Error: Invalid argument.\n");
|
||||
abort();
|
||||
case SP_ERR_FAIL:
|
||||
error_message = sp_last_error_message();
|
||||
printf("Error: Failed: %s\n", error_message);
|
||||
sp_free_error_message(error_message);
|
||||
abort();
|
||||
case SP_ERR_SUPP:
|
||||
printf("Error: Not supported.\n");
|
||||
abort();
|
||||
case SP_ERR_MEM:
|
||||
printf("Error: Couldn't allocate memory.\n");
|
||||
abort();
|
||||
case SP_OK:
|
||||
default:
|
||||
return result;
|
||||
}
|
||||
}
|
91
examples/examples.sln
Normal file
91
examples/examples.sln
Normal file
@ -0,0 +1,91 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29613.14
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "list_ports", "projects\list_ports.vcxproj", "{4447C677-0B59-4E1A-9EFD-50D0BE8A0F64}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "port_info", "projects\port_info.vcxproj", "{4BD48C7E-E097-4580-BC63-B4F586D53B8A}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libserialport", "..\libserialport.vcxproj", "{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "port_config", "projects\port_config.vcxproj", "{6CD526C6-0710-4ECA-BE23-6F85032C95F4}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "await_events", "projects\await_events.vcxproj", "{E757BAB5-C79B-49AD-B9C1-B81276B0A6FA}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "handle_errors", "projects\handle_errors.vcxproj", "{09EC5FFB-4DB0-4FE8-BF1E-050F03EC7ED4}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "send_receive", "projects\send_receive.vcxproj", "{F0B68251-C73A-4B7F-AA62-6778586A72A0}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{4447C677-0B59-4E1A-9EFD-50D0BE8A0F64}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{4447C677-0B59-4E1A-9EFD-50D0BE8A0F64}.Debug|x64.Build.0 = Debug|x64
|
||||
{4447C677-0B59-4E1A-9EFD-50D0BE8A0F64}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{4447C677-0B59-4E1A-9EFD-50D0BE8A0F64}.Debug|x86.Build.0 = Debug|Win32
|
||||
{4447C677-0B59-4E1A-9EFD-50D0BE8A0F64}.Release|x64.ActiveCfg = Release|x64
|
||||
{4447C677-0B59-4E1A-9EFD-50D0BE8A0F64}.Release|x64.Build.0 = Release|x64
|
||||
{4447C677-0B59-4E1A-9EFD-50D0BE8A0F64}.Release|x86.ActiveCfg = Release|Win32
|
||||
{4447C677-0B59-4E1A-9EFD-50D0BE8A0F64}.Release|x86.Build.0 = Release|Win32
|
||||
{4BD48C7E-E097-4580-BC63-B4F586D53B8A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{4BD48C7E-E097-4580-BC63-B4F586D53B8A}.Debug|x64.Build.0 = Debug|x64
|
||||
{4BD48C7E-E097-4580-BC63-B4F586D53B8A}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{4BD48C7E-E097-4580-BC63-B4F586D53B8A}.Debug|x86.Build.0 = Debug|Win32
|
||||
{4BD48C7E-E097-4580-BC63-B4F586D53B8A}.Release|x64.ActiveCfg = Release|x64
|
||||
{4BD48C7E-E097-4580-BC63-B4F586D53B8A}.Release|x64.Build.0 = Release|x64
|
||||
{4BD48C7E-E097-4580-BC63-B4F586D53B8A}.Release|x86.ActiveCfg = Release|Win32
|
||||
{4BD48C7E-E097-4580-BC63-B4F586D53B8A}.Release|x86.Build.0 = Release|Win32
|
||||
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Debug|x64.Build.0 = Debug|x64
|
||||
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Debug|x86.Build.0 = Debug|Win32
|
||||
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Release|x64.ActiveCfg = Release|x64
|
||||
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Release|x64.Build.0 = Release|x64
|
||||
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Release|x86.ActiveCfg = Release|Win32
|
||||
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Release|x86.Build.0 = Release|Win32
|
||||
{6CD526C6-0710-4ECA-BE23-6F85032C95F4}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6CD526C6-0710-4ECA-BE23-6F85032C95F4}.Debug|x64.Build.0 = Debug|x64
|
||||
{6CD526C6-0710-4ECA-BE23-6F85032C95F4}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{6CD526C6-0710-4ECA-BE23-6F85032C95F4}.Debug|x86.Build.0 = Debug|Win32
|
||||
{6CD526C6-0710-4ECA-BE23-6F85032C95F4}.Release|x64.ActiveCfg = Release|x64
|
||||
{6CD526C6-0710-4ECA-BE23-6F85032C95F4}.Release|x64.Build.0 = Release|x64
|
||||
{6CD526C6-0710-4ECA-BE23-6F85032C95F4}.Release|x86.ActiveCfg = Release|Win32
|
||||
{6CD526C6-0710-4ECA-BE23-6F85032C95F4}.Release|x86.Build.0 = Release|Win32
|
||||
{E757BAB5-C79B-49AD-B9C1-B81276B0A6FA}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{E757BAB5-C79B-49AD-B9C1-B81276B0A6FA}.Debug|x64.Build.0 = Debug|x64
|
||||
{E757BAB5-C79B-49AD-B9C1-B81276B0A6FA}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{E757BAB5-C79B-49AD-B9C1-B81276B0A6FA}.Debug|x86.Build.0 = Debug|Win32
|
||||
{E757BAB5-C79B-49AD-B9C1-B81276B0A6FA}.Release|x64.ActiveCfg = Release|x64
|
||||
{E757BAB5-C79B-49AD-B9C1-B81276B0A6FA}.Release|x64.Build.0 = Release|x64
|
||||
{E757BAB5-C79B-49AD-B9C1-B81276B0A6FA}.Release|x86.ActiveCfg = Release|Win32
|
||||
{E757BAB5-C79B-49AD-B9C1-B81276B0A6FA}.Release|x86.Build.0 = Release|Win32
|
||||
{09EC5FFB-4DB0-4FE8-BF1E-050F03EC7ED4}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{09EC5FFB-4DB0-4FE8-BF1E-050F03EC7ED4}.Debug|x64.Build.0 = Debug|x64
|
||||
{09EC5FFB-4DB0-4FE8-BF1E-050F03EC7ED4}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{09EC5FFB-4DB0-4FE8-BF1E-050F03EC7ED4}.Debug|x86.Build.0 = Debug|Win32
|
||||
{09EC5FFB-4DB0-4FE8-BF1E-050F03EC7ED4}.Release|x64.ActiveCfg = Release|x64
|
||||
{09EC5FFB-4DB0-4FE8-BF1E-050F03EC7ED4}.Release|x64.Build.0 = Release|x64
|
||||
{09EC5FFB-4DB0-4FE8-BF1E-050F03EC7ED4}.Release|x86.ActiveCfg = Release|Win32
|
||||
{09EC5FFB-4DB0-4FE8-BF1E-050F03EC7ED4}.Release|x86.Build.0 = Release|Win32
|
||||
{F0B68251-C73A-4B7F-AA62-6778586A72A0}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F0B68251-C73A-4B7F-AA62-6778586A72A0}.Debug|x64.Build.0 = Debug|x64
|
||||
{F0B68251-C73A-4B7F-AA62-6778586A72A0}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{F0B68251-C73A-4B7F-AA62-6778586A72A0}.Debug|x86.Build.0 = Debug|Win32
|
||||
{F0B68251-C73A-4B7F-AA62-6778586A72A0}.Release|x64.ActiveCfg = Release|x64
|
||||
{F0B68251-C73A-4B7F-AA62-6778586A72A0}.Release|x64.Build.0 = Release|x64
|
||||
{F0B68251-C73A-4B7F-AA62-6778586A72A0}.Release|x86.ActiveCfg = Release|Win32
|
||||
{F0B68251-C73A-4B7F-AA62-6778586A72A0}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {EEED7125-B08F-4EB9-8F10-F036CCD5F4CF}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
117
examples/handle_errors.c
Normal file
117
examples/handle_errors.c
Normal file
@ -0,0 +1,117 @@
|
||||
#include <libserialport.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Example of how to handle errors from libserialport.
|
||||
*
|
||||
* This example file is released to the public domain. */
|
||||
|
||||
/* Pointers used in the program to resources that may need to be freed. */
|
||||
struct sp_port **port_list = NULL;
|
||||
struct sp_port_config *config = NULL;
|
||||
struct sp_port *port = NULL;
|
||||
|
||||
/* Example of a function to clean up and exit the program with a given return code. */
|
||||
void end_program(int return_code)
|
||||
{
|
||||
/* Free any structures we allocated. */
|
||||
if (port_list != NULL)
|
||||
sp_free_port_list(port_list);
|
||||
if (config != NULL)
|
||||
sp_free_config(config);
|
||||
if (port != NULL)
|
||||
sp_free_port(port);
|
||||
|
||||
/* Exit with the given return code. */
|
||||
exit(return_code);
|
||||
}
|
||||
|
||||
/* Example of a helper function for error handling. */
|
||||
int check(enum sp_return result)
|
||||
{
|
||||
int error_code;
|
||||
char *error_message;
|
||||
|
||||
switch (result) {
|
||||
|
||||
/* Handle each of the four negative error codes that can be returned.
|
||||
*
|
||||
* In this example, we will end the program on any error, using
|
||||
* a different return code for each possible class of error. */
|
||||
|
||||
case SP_ERR_ARG:
|
||||
/* When SP_ERR_ARG is returned, there was a problem with one
|
||||
* or more of the arguments passed to the function, e.g. a null
|
||||
* pointer or an invalid value. This generally implies a bug in
|
||||
* the calling code. */
|
||||
printf("Error: Invalid argument.\n");
|
||||
end_program(1);
|
||||
|
||||
case SP_ERR_FAIL:
|
||||
/* When SP_ERR_FAIL is returned, there was an error from the OS,
|
||||
* which we can obtain the error code and message for. These
|
||||
* calls must be made in the same thread as the call that
|
||||
* returned SP_ERR_FAIL, and before any other system functions
|
||||
* are called in that thread, or they may not return the
|
||||
* correct results. */
|
||||
error_code = sp_last_error_code();
|
||||
error_message = sp_last_error_message();
|
||||
printf("Error: Failed: OS error code: %d, message: '%s'\n",
|
||||
error_code, error_message);
|
||||
/* The error message should be freed after use. */
|
||||
sp_free_error_message(error_message);
|
||||
end_program(2);
|
||||
|
||||
case SP_ERR_SUPP:
|
||||
/* When SP_ERR_SUPP is returned, the function was asked to do
|
||||
* something that isn't supported by the current OS or device,
|
||||
* or that libserialport doesn't know how to do in the current
|
||||
* version. */
|
||||
printf("Error: Not supported.\n");
|
||||
end_program(3);
|
||||
|
||||
case SP_ERR_MEM:
|
||||
/* When SP_ERR_MEM is returned, libserialport wasn't able to
|
||||
* allocate some memory it needed. Since the library doesn't
|
||||
* normally use any large data structures, this probably means
|
||||
* the system is critically low on memory and recovery will
|
||||
* require very careful handling. The library itself will
|
||||
* always try to handle any allocation failure safely.
|
||||
*
|
||||
* In this example, we'll just try to exit gracefully without
|
||||
* calling printf, which might need to allocate further memory. */
|
||||
end_program(4);
|
||||
|
||||
case SP_OK:
|
||||
default:
|
||||
/* A return value of SP_OK, defined as zero, means that the
|
||||
* operation succeeded. */
|
||||
printf("Operation succeeded.\n");
|
||||
|
||||
/* Some fuctions can also return a value greater than zero to
|
||||
* indicate a numeric result, such as the number of bytes read by
|
||||
* sp_blocking_read(). So when writing an error handling wrapper
|
||||
* function like this one, it's helpful to return the result so
|
||||
* that it can be used. */
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* Call some functions that should not result in errors. */
|
||||
|
||||
printf("Getting list of ports.\n");
|
||||
check(sp_list_ports(&port_list));
|
||||
|
||||
printf("Creating a new port configuration.\n");
|
||||
check(sp_new_config(&config));
|
||||
|
||||
/* Now make a function call that will result in an error. */
|
||||
|
||||
printf("Trying to find a port that doesn't exist.\n");
|
||||
check(sp_get_port_by_name("NON-EXISTENT-PORT", &port));
|
||||
|
||||
/* We could now clean up and exit normally if an error hadn't occured. */
|
||||
end_program(0);
|
||||
}
|
50
examples/list_ports.c
Normal file
50
examples/list_ports.c
Normal file
@ -0,0 +1,50 @@
|
||||
#include <libserialport.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Example of how to get a list of serial ports on the system.
|
||||
*
|
||||
* This example file is released to the public domain. */
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* A pointer to a null-terminated array of pointers to
|
||||
* struct sp_port, which will contain the ports found.*/
|
||||
struct sp_port **port_list;
|
||||
|
||||
printf("Getting port list.\n");
|
||||
|
||||
/* Call sp_list_ports() to get the ports. The port_list
|
||||
* pointer will be updated to refer to the array created. */
|
||||
enum sp_return result = sp_list_ports(&port_list);
|
||||
|
||||
if (result != SP_OK) {
|
||||
printf("sp_list_ports() failed!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Iterate through the ports. When port_list[i] is NULL
|
||||
* this indicates the end of the list. */
|
||||
int i;
|
||||
for (i = 0; port_list[i] != NULL; i++) {
|
||||
struct sp_port *port = port_list[i];
|
||||
|
||||
/* Get the name of the port. */
|
||||
char *port_name = sp_get_port_name(port);
|
||||
|
||||
printf("Found port: %s\n", port_name);
|
||||
}
|
||||
|
||||
printf("Found %d ports.\n", i);
|
||||
|
||||
printf("Freeing port list.\n");
|
||||
|
||||
/* Free the array created by sp_list_ports(). */
|
||||
sp_free_port_list(port_list);
|
||||
|
||||
/* Note that this will also free all the sp_port structures
|
||||
* it points to. If you want to keep one of them (e.g. to
|
||||
* use that port in the rest of your program), take a copy
|
||||
* of it first using sp_copy_port(). */
|
||||
|
||||
return 0;
|
||||
}
|
174
examples/port_config.c
Normal file
174
examples/port_config.c
Normal file
@ -0,0 +1,174 @@
|
||||
#include <libserialport.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Example of how to configure a serial port.
|
||||
*
|
||||
* This example file is released to the public domain. */
|
||||
|
||||
/* Helper function for error handling. */
|
||||
int check(enum sp_return result);
|
||||
|
||||
/* Helper function to give a name for each parity mode. */
|
||||
const char *parity_name(enum sp_parity parity);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* Get the port name from the command line. */
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s <port name>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
char *port_name = argv[1];
|
||||
|
||||
/* A pointer to a struct sp_port, which will refer to
|
||||
* the port found. */
|
||||
struct sp_port *port;
|
||||
|
||||
printf("Looking for port %s.\n", port_name);
|
||||
|
||||
/* Call sp_get_port_by_name() to find the port. The port
|
||||
* pointer will be updated to refer to the port found. */
|
||||
check(sp_get_port_by_name(port_name, &port));
|
||||
|
||||
/* Display some basic information about the port. */
|
||||
printf("Port name: %s\n", sp_get_port_name(port));
|
||||
printf("Description: %s\n", sp_get_port_description(port));
|
||||
|
||||
/* The port must be open to access its configuration. */
|
||||
printf("Opening port.\n");
|
||||
check(sp_open(port, SP_MODE_READ_WRITE));
|
||||
|
||||
/* There are two ways to access a port's configuration:
|
||||
*
|
||||
* 1. You can read and write a whole configuration (all settings at
|
||||
* once) using sp_get_config() and sp_set_config(). This is handy
|
||||
* if you want to change between some preset combinations, or save
|
||||
* and restore an existing configuration. It also ensures the
|
||||
* changes are made together, via an efficient set of calls into
|
||||
* the OS - in some cases a single system call can be used.
|
||||
*
|
||||
* Use accessor functions like sp_get_config_baudrate() and
|
||||
* sp_set_config_baudrate() to get and set individual settings
|
||||
* from a configuration.
|
||||
*
|
||||
* Configurations are allocated using sp_new_config() and freed
|
||||
* with sp_free_config(). You need to manage them yourself.
|
||||
*
|
||||
* 2. As a shortcut, you can set individual settings on a port
|
||||
* directly by calling functions like sp_set_baudrate() and
|
||||
* sp_set_parity(). This saves you the work of allocating
|
||||
* a temporary config, setting it up, applying it to a port
|
||||
* and then freeing it.
|
||||
*
|
||||
* In this example we'll do a bit of both: apply some initial settings
|
||||
* to the port, read out that config and display it, then switch to a
|
||||
* different configuration and back using sp_set_config(). */
|
||||
|
||||
/* First let's set some initial settings directly on the port.
|
||||
*
|
||||
* You should always configure all settings before using a port.
|
||||
* There are no "default" settings applied by libserialport.
|
||||
* When you open a port it has the defaults from the OS or driver,
|
||||
* or the settings left over by the last program to use it. */
|
||||
printf("Setting port to 115200 8N1, no flow control.\n");
|
||||
check(sp_set_baudrate(port, 115200));
|
||||
check(sp_set_bits(port, 8));
|
||||
check(sp_set_parity(port, SP_PARITY_NONE));
|
||||
check(sp_set_stopbits(port, 1));
|
||||
check(sp_set_flowcontrol(port, SP_FLOWCONTROL_NONE));
|
||||
|
||||
/* A pointer to a struct sp_port_config, which we'll use for the config
|
||||
* read back from the port. The pointer will be set by sp_new_config(). */
|
||||
struct sp_port_config *initial_config;
|
||||
|
||||
/* Allocate a configuration for us to read the port config into. */
|
||||
check(sp_new_config(&initial_config));
|
||||
|
||||
/* Read the current config from the port into that configuration. */
|
||||
check(sp_get_config(port, initial_config));
|
||||
|
||||
/* Display some of the settings read back from the port. */
|
||||
int baudrate, bits, stopbits;
|
||||
enum sp_parity parity;
|
||||
check(sp_get_config_baudrate(initial_config, &baudrate));
|
||||
check(sp_get_config_bits(initial_config, &bits));
|
||||
check(sp_get_config_stopbits(initial_config, &stopbits));
|
||||
check(sp_get_config_parity(initial_config, &parity));
|
||||
printf("Baudrate: %d, data bits: %d, parity: %s, stop bits: %d\n",
|
||||
baudrate, bits, parity_name(parity), stopbits);
|
||||
|
||||
/* Create a different configuration to have ready for use. */
|
||||
printf("Creating new config for 9600 7E2, XON/XOFF flow control.\n");
|
||||
struct sp_port_config *other_config;
|
||||
check(sp_new_config(&other_config));
|
||||
check(sp_set_config_baudrate(other_config, 9600));
|
||||
check(sp_set_config_bits(other_config, 7));
|
||||
check(sp_set_config_parity(other_config, SP_PARITY_EVEN));
|
||||
check(sp_set_config_stopbits(other_config, 2));
|
||||
check(sp_set_config_flowcontrol(other_config, SP_FLOWCONTROL_XONXOFF));
|
||||
|
||||
/* We can apply the new config to the port in one call. */
|
||||
printf("Applying new configuration.\n");
|
||||
check(sp_set_config(port, other_config));
|
||||
|
||||
/* And now switch back to our original config. */
|
||||
printf("Setting port back to previous config.\n");
|
||||
check(sp_set_config(port, initial_config));
|
||||
|
||||
/* Now clean up by closing the port and freeing structures. */
|
||||
check(sp_close(port));
|
||||
sp_free_port(port);
|
||||
sp_free_config(initial_config);
|
||||
sp_free_config(other_config);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper function for error handling. */
|
||||
int check(enum sp_return result)
|
||||
{
|
||||
/* For this example we'll just exit on any error by calling abort(). */
|
||||
char *error_message;
|
||||
|
||||
switch (result) {
|
||||
case SP_ERR_ARG:
|
||||
printf("Error: Invalid argument.\n");
|
||||
abort();
|
||||
case SP_ERR_FAIL:
|
||||
error_message = sp_last_error_message();
|
||||
printf("Error: Failed: %s\n", error_message);
|
||||
sp_free_error_message(error_message);
|
||||
abort();
|
||||
case SP_ERR_SUPP:
|
||||
printf("Error: Not supported.\n");
|
||||
abort();
|
||||
case SP_ERR_MEM:
|
||||
printf("Error: Couldn't allocate memory.\n");
|
||||
abort();
|
||||
case SP_OK:
|
||||
default:
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper function to give a name for each parity mode. */
|
||||
const char *parity_name(enum sp_parity parity)
|
||||
{
|
||||
switch (parity) {
|
||||
case SP_PARITY_INVALID:
|
||||
return "(Invalid)";
|
||||
case SP_PARITY_NONE:
|
||||
return "None";
|
||||
case SP_PARITY_ODD:
|
||||
return "Odd";
|
||||
case SP_PARITY_EVEN:
|
||||
return "Even";
|
||||
case SP_PARITY_MARK:
|
||||
return "Mark";
|
||||
case SP_PARITY_SPACE:
|
||||
return "Space";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
80
examples/port_info.c
Normal file
80
examples/port_info.c
Normal file
@ -0,0 +1,80 @@
|
||||
#include <libserialport.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Example of how to get information about a serial port.
|
||||
*
|
||||
* This example file is released to the public domain. */
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* Get the port name from the command line. */
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s <port name>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
char *port_name = argv[1];
|
||||
|
||||
/* A pointer to a struct sp_port, which will refer to
|
||||
* the port found. */
|
||||
struct sp_port *port;
|
||||
|
||||
printf("Looking for port %s.\n", port_name);
|
||||
|
||||
/* Call sp_get_port_by_name() to find the port. The port
|
||||
* pointer will be updated to refer to the port found. */
|
||||
enum sp_return result = sp_get_port_by_name(port_name, &port);
|
||||
|
||||
if (result != SP_OK) {
|
||||
printf("sp_get_port_by_name() failed!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Display some basic information about the port. */
|
||||
printf("Port name: %s\n", sp_get_port_name(port));
|
||||
printf("Description: %s\n", sp_get_port_description(port));
|
||||
|
||||
/* Identify the transport which this port is connected through,
|
||||
* e.g. native port, USB or Bluetooth. */
|
||||
enum sp_transport transport = sp_get_port_transport(port);
|
||||
|
||||
if (transport == SP_TRANSPORT_NATIVE) {
|
||||
/* This is a "native" port, usually directly connected
|
||||
* to the system rather than some external interface. */
|
||||
printf("Type: Native\n");
|
||||
} else if (transport == SP_TRANSPORT_USB) {
|
||||
/* This is a USB to serial converter of some kind. */
|
||||
printf("Type: USB\n");
|
||||
|
||||
/* Display string information from the USB descriptors. */
|
||||
printf("Manufacturer: %s\n", sp_get_port_usb_manufacturer(port));
|
||||
printf("Product: %s\n", sp_get_port_usb_product(port));
|
||||
printf("Serial: %s\n", sp_get_port_usb_serial(port));
|
||||
|
||||
/* Display USB vendor and product IDs. */
|
||||
int usb_vid, usb_pid;
|
||||
sp_get_port_usb_vid_pid(port, &usb_vid, &usb_pid);
|
||||
printf("VID: %04X PID: %04X\n", usb_vid, usb_pid);
|
||||
|
||||
/* Display bus and address. */
|
||||
int usb_bus, usb_address;
|
||||
sp_get_port_usb_bus_address(port, &usb_bus, &usb_address);
|
||||
printf("Bus: %d Address: %d\n", usb_bus, usb_address);
|
||||
} else if (transport == SP_TRANSPORT_BLUETOOTH) {
|
||||
/* This is a Bluetooth serial port. */
|
||||
printf("Type: Bluetooth\n");
|
||||
|
||||
/* Display Bluetooth MAC address. */
|
||||
printf("MAC: %s\n", sp_get_port_bluetooth_address(port));
|
||||
}
|
||||
|
||||
printf("Freeing port.\n");
|
||||
|
||||
/* Free the port structure created by sp_get_port_by_name(). */
|
||||
sp_free_port(port);
|
||||
|
||||
/* Note that this will also free the port name and other
|
||||
* strings retrieved from the port structure. If you want
|
||||
* to keep these, copy them before freeing the port. */
|
||||
|
||||
return 0;
|
||||
}
|
167
examples/projects/await_events.vcxproj
Normal file
167
examples/projects/await_events.vcxproj
Normal file
@ -0,0 +1,167 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\await_events.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\libserialport.vcxproj">
|
||||
<Project>{1c8eaaf2-133e-4cee-8981-4a903a8b3935}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\libserialport.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{E757BAB5-C79B-49AD-B9C1-B81276B0A6FA}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>listports</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
27
examples/projects/await_events.vcxproj.filters
Normal file
27
examples/projects/await_events.vcxproj.filters
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\await_events.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\libserialport.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
18
examples/projects/common.props
Normal file
18
examples/projects/common.props
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Label="PropertySheets" />
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_PropertySheetDisplayName>Common</_PropertySheetDisplayName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<ProgramDatabaseFile>$(OutDir)$(ProjectName).pdb</ProgramDatabaseFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup />
|
||||
</Project>
|
167
examples/projects/handle_errors.vcxproj
Normal file
167
examples/projects/handle_errors.vcxproj
Normal file
@ -0,0 +1,167 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\handle_errors.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\libserialport.vcxproj">
|
||||
<Project>{1c8eaaf2-133e-4cee-8981-4a903a8b3935}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\libserialport.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{09EC5FFB-4DB0-4FE8-BF1E-050F03EC7ED4}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>listports</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
27
examples/projects/handle_errors.vcxproj.filters
Normal file
27
examples/projects/handle_errors.vcxproj.filters
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\handle_errors.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\libserialport.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
167
examples/projects/list_ports.vcxproj
Normal file
167
examples/projects/list_ports.vcxproj
Normal file
@ -0,0 +1,167 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\list_ports.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\libserialport.vcxproj">
|
||||
<Project>{1c8eaaf2-133e-4cee-8981-4a903a8b3935}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\libserialport.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{4447C677-0B59-4E1A-9EFD-50D0BE8A0F64}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>listports</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
27
examples/projects/list_ports.vcxproj.filters
Normal file
27
examples/projects/list_ports.vcxproj.filters
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\list_ports.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\libserialport.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
167
examples/projects/port_config.vcxproj
Normal file
167
examples/projects/port_config.vcxproj
Normal file
@ -0,0 +1,167 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\port_config.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\libserialport.vcxproj">
|
||||
<Project>{1c8eaaf2-133e-4cee-8981-4a903a8b3935}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\libserialport.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{6CD526C6-0710-4ECA-BE23-6F85032C95F4}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>listports</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
27
examples/projects/port_config.vcxproj.filters
Normal file
27
examples/projects/port_config.vcxproj.filters
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\port_config.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\libserialport.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
167
examples/projects/port_info.vcxproj
Normal file
167
examples/projects/port_info.vcxproj
Normal file
@ -0,0 +1,167 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\port_info.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\libserialport.vcxproj">
|
||||
<Project>{1c8eaaf2-133e-4cee-8981-4a903a8b3935}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\libserialport.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{4BD48C7E-E097-4580-BC63-B4F586D53B8A}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>listports</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
27
examples/projects/port_info.vcxproj.filters
Normal file
27
examples/projects/port_info.vcxproj.filters
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\port_info.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\libserialport.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
167
examples/projects/send_receive.vcxproj
Normal file
167
examples/projects/send_receive.vcxproj
Normal file
@ -0,0 +1,167 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\send_receive.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\libserialport.vcxproj">
|
||||
<Project>{1c8eaaf2-133e-4cee-8981-4a903a8b3935}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\libserialport.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{F0B68251-C73A-4B7F-AA62-6778586A72A0}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>listports</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
27
examples/projects/send_receive.vcxproj.filters
Normal file
27
examples/projects/send_receive.vcxproj.filters
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\send_receive.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\libserialport.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
139
examples/send_receive.c
Normal file
139
examples/send_receive.c
Normal file
@ -0,0 +1,139 @@
|
||||
#include <libserialport.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Example of how to send and receive data.
|
||||
*
|
||||
* This example file is released to the public domain. */
|
||||
|
||||
/* Helper function for error handling. */
|
||||
int check(enum sp_return result);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* This example can be used with one or two ports. With one port, it
|
||||
* will send data and try to receive it on the same port. This can be
|
||||
* done by connecting a single wire between the TX and RX pins of the
|
||||
* port.
|
||||
*
|
||||
* Alternatively it can be used with two serial ports connected to each
|
||||
* other, so that data can be sent on one and received on the other.
|
||||
* This can be done with two ports with TX/RX cross-connected, e.g. by
|
||||
* a "null modem" cable, or with a pair of interconnected virtual ports,
|
||||
* such as those created by com0com on Windows or tty0tty on Linux. */
|
||||
|
||||
/* Get the port names from the command line. */
|
||||
if (argc < 2 || argc > 3) {
|
||||
printf("Usage: %s <port 1> [<port 2>]\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
int num_ports = argc - 1;
|
||||
char **port_names = argv + 1;
|
||||
|
||||
/* The ports we will use. */
|
||||
struct sp_port *ports[2];
|
||||
|
||||
/* Open and configure each port. */
|
||||
for (int i = 0; i < num_ports; i++) {
|
||||
printf("Looking for port %s.\n", port_names[i]);
|
||||
check(sp_get_port_by_name(port_names[i], &ports[i]));
|
||||
|
||||
printf("Opening port.\n");
|
||||
check(sp_open(ports[i], SP_MODE_READ_WRITE));
|
||||
|
||||
printf("Setting port to 9600 8N1, no flow control.\n");
|
||||
check(sp_set_baudrate(ports[i], 9600));
|
||||
check(sp_set_bits(ports[i], 8));
|
||||
check(sp_set_parity(ports[i], SP_PARITY_NONE));
|
||||
check(sp_set_stopbits(ports[i], 1));
|
||||
check(sp_set_flowcontrol(ports[i], SP_FLOWCONTROL_NONE));
|
||||
}
|
||||
|
||||
/* Now send some data on each port and receive it back. */
|
||||
for (int tx = 0; tx < num_ports; tx++) {
|
||||
/* Get the ports to send and receive on. */
|
||||
int rx = num_ports == 1 ? 0 : ((tx == 0) ? 1 : 0);
|
||||
struct sp_port *tx_port = ports[tx];
|
||||
struct sp_port *rx_port = ports[rx];
|
||||
|
||||
/* The data we will send. */
|
||||
char *data = "Hello!";
|
||||
int size = strlen(data);
|
||||
|
||||
/* We'll allow a 1 second timeout for send and receive. */
|
||||
unsigned int timeout = 1000;
|
||||
|
||||
/* On success, sp_blocking_write() and sp_blocking_read()
|
||||
* return the number of bytes sent/received before the
|
||||
* timeout expired. We'll store that result here. */
|
||||
int result;
|
||||
|
||||
/* Send data. */
|
||||
printf("Sending '%s' (%d bytes) on port %s.\n",
|
||||
data, size, sp_get_port_name(tx_port));
|
||||
result = check(sp_blocking_write(tx_port, data, size, timeout));
|
||||
|
||||
/* Check whether we sent all of the data. */
|
||||
if (result == size)
|
||||
printf("Sent %d bytes successfully.\n", size);
|
||||
else
|
||||
printf("Timed out, %d/%d bytes sent.\n", result, size);
|
||||
|
||||
/* Allocate a buffer to receive data. */
|
||||
char *buf = malloc(size + 1);
|
||||
|
||||
/* Try to receive the data on the other port. */
|
||||
printf("Receiving %d bytes on port %s.\n",
|
||||
size, sp_get_port_name(rx_port));
|
||||
result = check(sp_blocking_read(rx_port, buf, size, timeout));
|
||||
|
||||
/* Check whether we received the number of bytes we wanted. */
|
||||
if (result == size)
|
||||
printf("Received %d bytes successfully.\n", size);
|
||||
else
|
||||
printf("Timed out, %d/%d bytes received.\n", result, size);
|
||||
|
||||
/* Check if we received the same data we sent. */
|
||||
buf[result] = '\0';
|
||||
printf("Received '%s'.\n", buf);
|
||||
|
||||
/* Free receive buffer. */
|
||||
free(buf);
|
||||
}
|
||||
|
||||
/* Close ports and free resources. */
|
||||
for (int i = 0; i < num_ports; i++) {
|
||||
check(sp_close(ports[i]));
|
||||
sp_free_port(ports[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper function for error handling. */
|
||||
int check(enum sp_return result)
|
||||
{
|
||||
/* For this example we'll just exit on any error by calling abort(). */
|
||||
char *error_message;
|
||||
|
||||
switch (result) {
|
||||
case SP_ERR_ARG:
|
||||
printf("Error: Invalid argument.\n");
|
||||
abort();
|
||||
case SP_ERR_FAIL:
|
||||
error_message = sp_last_error_message();
|
||||
printf("Error: Failed: %s\n", error_message);
|
||||
sp_free_error_message(error_message);
|
||||
abort();
|
||||
case SP_ERR_SUPP:
|
||||
printf("Error: Not supported.\n");
|
||||
abort();
|
||||
case SP_ERR_MEM:
|
||||
printf("Error: Couldn't allocate memory.\n");
|
||||
abort();
|
||||
case SP_OK:
|
||||
default:
|
||||
return result;
|
||||
}
|
||||
}
|
21
freebsd.c
21
freebsd.c
@ -325,8 +325,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
||||
SP_PRIV enum sp_return list_ports(struct sp_port ***list)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent entry;
|
||||
struct dirent *result;
|
||||
struct dirent *entry;
|
||||
struct termios tios;
|
||||
char name[PATH_MAX];
|
||||
int fd, ret;
|
||||
@ -336,20 +335,20 @@ SP_PRIV enum sp_return list_ports(struct sp_port ***list)
|
||||
RETURN_FAIL("Could not open dir /dev");
|
||||
|
||||
DEBUG("Iterating over results");
|
||||
while (!readdir_r(dir, &entry, &result) && result) {
|
||||
while ((entry = readdir(dir))) {
|
||||
ret = SP_OK;
|
||||
if (entry.d_type != DT_CHR)
|
||||
if (entry->d_type != DT_CHR)
|
||||
continue;
|
||||
if (strncmp(entry.d_name, "cuaU", 4) != 0)
|
||||
if (strncmp(entry.d_name, "cuau", 4) != 0)
|
||||
if (strncmp(entry.d_name, "cuad", 4) != 0)
|
||||
if (strncmp(entry->d_name, "cuaU", 4) != 0)
|
||||
if (strncmp(entry->d_name, "cuau", 4) != 0)
|
||||
if (strncmp(entry->d_name, "cuad", 4) != 0)
|
||||
continue;
|
||||
if (strend(entry.d_name, ".init"))
|
||||
if (strend(entry->d_name, ".init"))
|
||||
continue;
|
||||
if (strend(entry.d_name, ".lock"))
|
||||
if (strend(entry->d_name, ".lock"))
|
||||
continue;
|
||||
|
||||
snprintf(name, sizeof(name), "/dev/%s", entry.d_name);
|
||||
snprintf(name, sizeof(name), "/dev/%s", entry->d_name);
|
||||
DEBUG_FMT("Found device %s", name);
|
||||
|
||||
/* Check that we can open tty/cua device in rw mode - we need that. */
|
||||
@ -370,7 +369,7 @@ SP_PRIV enum sp_return list_ports(struct sp_port ***list)
|
||||
continue;
|
||||
|
||||
DEBUG_FMT("Found port %s", name);
|
||||
DBG("%s: %s\n", __func__, entry.d_name);
|
||||
DBG("%s: %s\n", __func__, entry->d_name);
|
||||
|
||||
*list = list_append(*list, name);
|
||||
if (!*list) {
|
||||
|
@ -59,19 +59,38 @@
|
||||
* to restructure things somewhat, or do without some specialised features.
|
||||
* For particular notes on porting existing code, see @ref Porting.
|
||||
*
|
||||
* The following subsections will help explain the principles of the API.
|
||||
* Examples
|
||||
* --------
|
||||
*
|
||||
* Some simple example programs using libserialport are included in the
|
||||
* @c examples directory in the source package:
|
||||
*
|
||||
* - @ref list_ports.c - Getting a list of ports present on the system.
|
||||
* - @ref port_info.c - Getting information on a particular serial port.
|
||||
* - @ref port_config.c - Accessing configuration settings of a port.
|
||||
* - @ref send_receive.c - Sending and receiving data.
|
||||
* - @ref await_events.c - Awaiting events on multiple ports.
|
||||
* - @ref handle_errors.c - Handling errors returned from the library.
|
||||
*
|
||||
* These examples are linked with the API documentation. Each function
|
||||
* in the API reference includes links to where it is used in an example
|
||||
* program, and each appearance of a function in the examples links
|
||||
* to that function's entry in the API reference.
|
||||
*
|
||||
* Headers
|
||||
* -------
|
||||
*
|
||||
* To use libserialport functions in your code, you should include the
|
||||
* libserialport.h header, i.e. "#include <libserialport.h>".
|
||||
* libserialport.h header, i.e.
|
||||
* @code
|
||||
* #include <libserialport.h>
|
||||
* @endcode
|
||||
*
|
||||
* Namespace
|
||||
* ---------
|
||||
*
|
||||
* All identifiers defined by the public libserialport headers use the prefix
|
||||
* sp_ (for functions and data types) or SP_ (for macros and constants).
|
||||
* @c sp_ (for functions and data types) or @c SP_ (for macros and constants).
|
||||
*
|
||||
* Functions
|
||||
* ---------
|
||||
@ -132,12 +151,12 @@
|
||||
* numeric result, e.g. sp_blocking_read() or sp_blocking_write().
|
||||
*
|
||||
* An error message is only available via sp_last_error_message() in the case
|
||||
* where SP_ERR_FAIL was returned by the previous function call. The error
|
||||
* where @ref SP_ERR_FAIL was returned by the previous function call. The error
|
||||
* message returned is that provided by the OS, using the current language
|
||||
* settings. It is an error to call sp_last_error_code() or
|
||||
* sp_last_error_message() except after a previous function call returned
|
||||
* SP_ERR_FAIL. The library does not define its own error codes or messages
|
||||
* to accompany other return codes.
|
||||
* @ref SP_ERR_FAIL. The library does not define its own error codes or
|
||||
* messages to accompany other return codes.
|
||||
*
|
||||
* Thread safety
|
||||
* -------------
|
||||
@ -178,7 +197,7 @@
|
||||
*
|
||||
* The library can output extensive tracing and debugging information. The
|
||||
* simplest way to use this is to set the environment variable
|
||||
* LIBSERIALPORT_DEBUG to any value; messages will then be output to the
|
||||
* @c LIBSERIALPORT_DEBUG to any value; messages will then be output to the
|
||||
* standard error stream.
|
||||
*
|
||||
* This behaviour is implemented by a default debug message handling
|
||||
@ -206,21 +225,21 @@
|
||||
* libserialport provides only a raw binary channel with no special handling.
|
||||
*
|
||||
* The second relates to blocking versus non-blocking I/O behaviour. In
|
||||
* Unix-like systems this is normally specified by setting the O_NONBLOCK
|
||||
* flag on the file descriptor, affecting the semantics of subsequent read()
|
||||
* and write() calls.
|
||||
* Unix-like systems this is normally specified by setting the @c O_NONBLOCK
|
||||
* flag on the file descriptor, affecting the semantics of subsequent @c read()
|
||||
* and @c write() calls.
|
||||
*
|
||||
* In libserialport, blocking and nonblocking operations are both available at
|
||||
* any time. If your existing code ѕets O_NONBLOCK, you should use
|
||||
* any time. If your existing code ѕets @c O_NONBLOCK, you should use
|
||||
* sp_nonblocking_read() and sp_nonblocking_write() to get the same behaviour
|
||||
* as your existing read() and write() calls. If it does not, you should use
|
||||
* sp_blocking_read() and sp_blocking_write() instead. You may also find
|
||||
* as your existing @c read() and @c write() calls. If it does not, you should
|
||||
* use sp_blocking_read() and sp_blocking_write() instead. You may also find
|
||||
* sp_blocking_read_next() useful, which reproduces the semantics of a blocking
|
||||
* read() with VTIME = 0 and VMIN = 1 set in termios.
|
||||
* read() with @c VTIME=0 and @c VMIN=1 set in termios.
|
||||
*
|
||||
* Finally, you should take care if your program uses custom signal handlers.
|
||||
* The blocking calls provided by libserialport will restart system calls that
|
||||
* return with EINTR, so you will need to make your own arrangements if you
|
||||
* return with @c EINTR, so you will need to make your own arrangements if you
|
||||
* need to interrupt blocking operations when your signal handlers are called.
|
||||
* This is not an issue if you only use the default handlers.
|
||||
*
|
||||
@ -231,23 +250,23 @@
|
||||
*
|
||||
* If your program does not use overlapped I/O, you can simply use
|
||||
* sp_blocking_read() and sp_blocking_write() as direct equivalents for
|
||||
* ReadFile() and WriteFile(). You may also find sp_blocking_read_next()
|
||||
* useful, which reproduces the special semantics of ReadFile() with
|
||||
* ReadIntervalTimeout and ReadTotalTimeoutMultiplier set to MAXDWORD
|
||||
* and 0 < ReadTotalTimeoutConstant < MAXDWORD.
|
||||
* @c ReadFile() and @c WriteFile(). You may also find sp_blocking_read_next()
|
||||
* useful, which reproduces the special semantics of @c ReadFile() with
|
||||
* @c ReadIntervalTimeout and @c ReadTotalTimeoutMultiplier set to @c MAXDWORD
|
||||
* and @c ReadTotalTimeoutConstant set to between @c 1 and @c MAXDWORD-1 .
|
||||
*
|
||||
* If your program makes use of overlapped I/O to continue work while a serial
|
||||
* operation is in progress, then you can achieve the same results using
|
||||
* sp_nonblocking_read() and sp_nonblocking_write().
|
||||
*
|
||||
* Generally, overlapped I/O is combined with either waiting for completion
|
||||
* once there is no more background work to do (using WaitForSingleObject() or
|
||||
* WaitForMultipleObjects()), or periodically checking for completion with
|
||||
* GetOverlappedResult(). If the aim is to start a new operation for further
|
||||
* data once the previous one has completed, you can instead simply call the
|
||||
* nonblocking functions again with the next data. If you need to wait for
|
||||
* completion, use sp_wait() to determine when the port is ready to send or
|
||||
* receive further data.
|
||||
* once there is no more background work to do (using @c WaitForSingleObject()
|
||||
* or @c WaitForMultipleObjects()), or periodically checking for completion
|
||||
* with @c GetOverlappedResult(). If the aim is to start a new operation for
|
||||
* further data once the previous one has completed, you can instead simply
|
||||
* call the nonblocking functions again with the next data. If you need to
|
||||
* wait for completion, use sp_wait() to determine when the port is ready to
|
||||
* send or receive further data.
|
||||
*/
|
||||
|
||||
#ifndef LIBSERIALPORT_LIBSERIALPORT_H
|
||||
@ -259,6 +278,25 @@ extern "C" {
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/** @cond */
|
||||
#ifdef _MSC_VER
|
||||
/* Microsoft Visual C/C++ compiler in use */
|
||||
#ifdef LIBSERIALPORT_MSBUILD
|
||||
/* Building the library - need to export DLL symbols */
|
||||
#define SP_API __declspec(dllexport)
|
||||
#else
|
||||
/* Using the library - need to import DLL symbols */
|
||||
#define SP_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
/* Some other compiler in use */
|
||||
#ifndef LIBSERIALPORT_ATBUILD
|
||||
/* Not building the library itself - don't need any special prefixes. */
|
||||
#define SP_API
|
||||
#endif
|
||||
#endif
|
||||
/** @endcond */
|
||||
|
||||
/** Return values. */
|
||||
enum sp_return {
|
||||
/** Operation completed successfully. */
|
||||
@ -445,6 +483,8 @@ struct sp_event_set {
|
||||
*
|
||||
* Enumerating the serial ports of a system.
|
||||
*
|
||||
* See @ref list_ports.c for a working example of port enumeration.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
@ -465,7 +505,7 @@ struct sp_event_set {
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_get_port_by_name(const char *portname, struct sp_port **port_ptr);
|
||||
SP_API enum sp_return sp_get_port_by_name(const char *portname, struct sp_port **port_ptr);
|
||||
|
||||
/**
|
||||
* Free a port structure obtained from sp_get_port_by_name() or sp_copy_port().
|
||||
@ -474,7 +514,7 @@ enum sp_return sp_get_port_by_name(const char *portname, struct sp_port **port_p
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
void sp_free_port(struct sp_port *port);
|
||||
SP_API void sp_free_port(struct sp_port *port);
|
||||
|
||||
/**
|
||||
* List the serial ports available on the system.
|
||||
@ -495,7 +535,7 @@ void sp_free_port(struct sp_port *port);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_list_ports(struct sp_port ***list_ptr);
|
||||
SP_API enum sp_return sp_list_ports(struct sp_port ***list_ptr);
|
||||
|
||||
/**
|
||||
* Make a new copy of an sp_port structure.
|
||||
@ -514,7 +554,7 @@ enum sp_return sp_list_ports(struct sp_port ***list_ptr);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_copy_port(const struct sp_port *port, struct sp_port **copy_ptr);
|
||||
SP_API enum sp_return sp_copy_port(const struct sp_port *port, struct sp_port **copy_ptr);
|
||||
|
||||
/**
|
||||
* Free a port list obtained from sp_list_ports().
|
||||
@ -526,7 +566,7 @@ enum sp_return sp_copy_port(const struct sp_port *port, struct sp_port **copy_pt
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
void sp_free_port_list(struct sp_port **ports);
|
||||
SP_API void sp_free_port_list(struct sp_port **ports);
|
||||
|
||||
/**
|
||||
* @}
|
||||
@ -534,6 +574,8 @@ void sp_free_port_list(struct sp_port **ports);
|
||||
*
|
||||
* Opening, closing and querying ports.
|
||||
*
|
||||
* See @ref port_info.c for a working example of getting port information.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
@ -547,7 +589,7 @@ void sp_free_port_list(struct sp_port **ports);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_open(struct sp_port *port, enum sp_mode flags);
|
||||
SP_API enum sp_return sp_open(struct sp_port *port, enum sp_mode flags);
|
||||
|
||||
/**
|
||||
* Close the specified serial port.
|
||||
@ -558,7 +600,7 @@ enum sp_return sp_open(struct sp_port *port, enum sp_mode flags);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_close(struct sp_port *port);
|
||||
SP_API enum sp_return sp_close(struct sp_port *port);
|
||||
|
||||
/**
|
||||
* Get the name of a port.
|
||||
@ -575,7 +617,7 @@ enum sp_return sp_close(struct sp_port *port);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
char *sp_get_port_name(const struct sp_port *port);
|
||||
SP_API char *sp_get_port_name(const struct sp_port *port);
|
||||
|
||||
/**
|
||||
* Get a description for a port, to present to end user.
|
||||
@ -588,7 +630,7 @@ char *sp_get_port_name(const struct sp_port *port);
|
||||
*
|
||||
* @since 0.1.1
|
||||
*/
|
||||
char *sp_get_port_description(const struct sp_port *port);
|
||||
SP_API char *sp_get_port_description(const struct sp_port *port);
|
||||
|
||||
/**
|
||||
* Get the transport type used by a port.
|
||||
@ -599,7 +641,7 @@ char *sp_get_port_description(const struct sp_port *port);
|
||||
*
|
||||
* @since 0.1.1
|
||||
*/
|
||||
enum sp_transport sp_get_port_transport(const struct sp_port *port);
|
||||
SP_API enum sp_transport sp_get_port_transport(const struct sp_port *port);
|
||||
|
||||
/**
|
||||
* Get the USB bus number and address on bus of a USB serial adapter port.
|
||||
@ -614,7 +656,7 @@ enum sp_transport sp_get_port_transport(const struct sp_port *port);
|
||||
*
|
||||
* @since 0.1.1
|
||||
*/
|
||||
enum sp_return sp_get_port_usb_bus_address(const struct sp_port *port,
|
||||
SP_API enum sp_return sp_get_port_usb_bus_address(const struct sp_port *port,
|
||||
int *usb_bus, int *usb_address);
|
||||
|
||||
/**
|
||||
@ -630,7 +672,7 @@ enum sp_return sp_get_port_usb_bus_address(const struct sp_port *port,
|
||||
*
|
||||
* @since 0.1.1
|
||||
*/
|
||||
enum sp_return sp_get_port_usb_vid_pid(const struct sp_port *port, int *usb_vid, int *usb_pid);
|
||||
SP_API enum sp_return sp_get_port_usb_vid_pid(const struct sp_port *port, int *usb_vid, int *usb_pid);
|
||||
|
||||
/**
|
||||
* Get the USB manufacturer string of a USB serial adapter port.
|
||||
@ -643,7 +685,7 @@ enum sp_return sp_get_port_usb_vid_pid(const struct sp_port *port, int *usb_vid,
|
||||
*
|
||||
* @since 0.1.1
|
||||
*/
|
||||
char *sp_get_port_usb_manufacturer(const struct sp_port *port);
|
||||
SP_API char *sp_get_port_usb_manufacturer(const struct sp_port *port);
|
||||
|
||||
/**
|
||||
* Get the USB product string of a USB serial adapter port.
|
||||
@ -656,7 +698,7 @@ char *sp_get_port_usb_manufacturer(const struct sp_port *port);
|
||||
*
|
||||
* @since 0.1.1
|
||||
*/
|
||||
char *sp_get_port_usb_product(const struct sp_port *port);
|
||||
SP_API char *sp_get_port_usb_product(const struct sp_port *port);
|
||||
|
||||
/**
|
||||
* Get the USB serial number string of a USB serial adapter port.
|
||||
@ -669,7 +711,7 @@ char *sp_get_port_usb_product(const struct sp_port *port);
|
||||
*
|
||||
* @since 0.1.1
|
||||
*/
|
||||
char *sp_get_port_usb_serial(const struct sp_port *port);
|
||||
SP_API char *sp_get_port_usb_serial(const struct sp_port *port);
|
||||
|
||||
/**
|
||||
* Get the MAC address of a Bluetooth serial adapter port.
|
||||
@ -682,7 +724,7 @@ char *sp_get_port_usb_serial(const struct sp_port *port);
|
||||
*
|
||||
* @since 0.1.1
|
||||
*/
|
||||
char *sp_get_port_bluetooth_address(const struct sp_port *port);
|
||||
SP_API char *sp_get_port_bluetooth_address(const struct sp_port *port);
|
||||
|
||||
/**
|
||||
* Get the operating system handle for a port.
|
||||
@ -714,7 +756,7 @@ char *sp_get_port_bluetooth_address(const struct sp_port *port);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_get_port_handle(const struct sp_port *port, void *result_ptr);
|
||||
SP_API enum sp_return sp_get_port_handle(const struct sp_port *port, void *result_ptr);
|
||||
|
||||
/**
|
||||
* @}
|
||||
@ -722,6 +764,63 @@ enum sp_return sp_get_port_handle(const struct sp_port *port, void *result_ptr);
|
||||
* @defgroup Configuration Configuration
|
||||
*
|
||||
* Setting and querying serial port parameters.
|
||||
*
|
||||
* See @ref port_config.c for a working example of port configuration.
|
||||
*
|
||||
* You should always configure all settings before using a port.
|
||||
* There are no default settings applied by libserialport.
|
||||
* When you open a port it may have default settings from the OS or
|
||||
* driver, or the settings left over by the last program to use it.
|
||||
*
|
||||
* You should always set baud rate, data bits, parity and stop bits.
|
||||
*
|
||||
* You should normally also set one of the preset @ref sp_flowcontrol
|
||||
* flow control modes, which will set up the RTS, CTS, DTR and DSR pin
|
||||
* behaviours and enable or disable XON/XOFF. If you need an unusual
|
||||
* configuration not covered by the preset flow control modes, you
|
||||
* will need to configure these settings individually, and avoid
|
||||
* calling sp_set_flowcontrol() or sp_set_config_flowcontrol() which
|
||||
* will overwrite these settings.
|
||||
*
|
||||
* A port must be opened before you can change its settings.
|
||||
*
|
||||
* There are two ways of accessing port settings:
|
||||
*
|
||||
* Configuration structures
|
||||
* ------------------------
|
||||
*
|
||||
* You can read and write a whole configuration (all settings at once)
|
||||
* using sp_get_config() and sp_set_config(). This is handy if you want
|
||||
* to change between some preset combinations, or save and restore an
|
||||
* existing configuration. It also ensures the changes are made
|
||||
* together, via an efficient set of calls into the OS - in some cases
|
||||
* a single system call can be used.
|
||||
*
|
||||
* Use accessor functions like sp_get_config_baudrate() and
|
||||
* sp_set_config_baudrate() to get and set individual settings
|
||||
* from a configuration.
|
||||
*
|
||||
* For each setting in a port configuration, a special value of -1 can
|
||||
* be used, which will cause that setting to be left alone when the
|
||||
* configuration is applied by sp_set_config().
|
||||
*
|
||||
* This value is also be used by sp_get_config() for any settings
|
||||
* which are unconfigured at the OS level, or in a state that is
|
||||
* not representable within the libserialport API.
|
||||
*
|
||||
* Configurations are allocated using sp_new_config() and freed
|
||||
* with sp_free_config(). You need to manage them yourself. When
|
||||
* a new configuration is allocated by sp_new_config(), all of
|
||||
* its settings are initially set to the special -1 value.
|
||||
*
|
||||
* Direct functions for changing port settings
|
||||
* -------------------------------------------
|
||||
*
|
||||
* As a shortcut, you can set individual settings on a port directly
|
||||
* by calling functions like sp_set_baudrate() and sp_set_parity().
|
||||
* This saves you the work of allocating a temporary config, setting it
|
||||
* up, applying it to a port and then freeing it.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
@ -747,7 +846,7 @@ enum sp_return sp_get_port_handle(const struct sp_port *port, void *result_ptr);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_new_config(struct sp_port_config **config_ptr);
|
||||
SP_API enum sp_return sp_new_config(struct sp_port_config **config_ptr);
|
||||
|
||||
/**
|
||||
* Free a port configuration structure.
|
||||
@ -756,7 +855,7 @@ enum sp_return sp_new_config(struct sp_port_config **config_ptr);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
void sp_free_config(struct sp_port_config *config);
|
||||
SP_API void sp_free_config(struct sp_port_config *config);
|
||||
|
||||
/**
|
||||
* Get the current configuration of the specified serial port.
|
||||
@ -778,7 +877,7 @@ void sp_free_config(struct sp_port_config *config);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_get_config(struct sp_port *port, struct sp_port_config *config);
|
||||
SP_API enum sp_return sp_get_config(struct sp_port *port, struct sp_port_config *config);
|
||||
|
||||
/**
|
||||
* Set the configuration for the specified serial port.
|
||||
@ -797,7 +896,7 @@ enum sp_return sp_get_config(struct sp_port *port, struct sp_port_config *config
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_config(struct sp_port *port, const struct sp_port_config *config);
|
||||
SP_API enum sp_return sp_set_config(struct sp_port *port, const struct sp_port_config *config);
|
||||
|
||||
/**
|
||||
* Set the baud rate for the specified serial port.
|
||||
@ -809,7 +908,7 @@ enum sp_return sp_set_config(struct sp_port *port, const struct sp_port_config *
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_baudrate(struct sp_port *port, int baudrate);
|
||||
SP_API enum sp_return sp_set_baudrate(struct sp_port *port, int baudrate);
|
||||
|
||||
/**
|
||||
* Get the baud rate from a port configuration.
|
||||
@ -824,7 +923,7 @@ enum sp_return sp_set_baudrate(struct sp_port *port, int baudrate);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_get_config_baudrate(const struct sp_port_config *config, int *baudrate_ptr);
|
||||
SP_API enum sp_return sp_get_config_baudrate(const struct sp_port_config *config, int *baudrate_ptr);
|
||||
|
||||
/**
|
||||
* Set the baud rate in a port configuration.
|
||||
@ -836,7 +935,7 @@ enum sp_return sp_get_config_baudrate(const struct sp_port_config *config, int *
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_config_baudrate(struct sp_port_config *config, int baudrate);
|
||||
SP_API enum sp_return sp_set_config_baudrate(struct sp_port_config *config, int baudrate);
|
||||
|
||||
/**
|
||||
* Set the data bits for the specified serial port.
|
||||
@ -848,7 +947,7 @@ enum sp_return sp_set_config_baudrate(struct sp_port_config *config, int baudrat
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_bits(struct sp_port *port, int bits);
|
||||
SP_API enum sp_return sp_set_bits(struct sp_port *port, int bits);
|
||||
|
||||
/**
|
||||
* Get the data bits from a port configuration.
|
||||
@ -863,7 +962,7 @@ enum sp_return sp_set_bits(struct sp_port *port, int bits);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_get_config_bits(const struct sp_port_config *config, int *bits_ptr);
|
||||
SP_API enum sp_return sp_get_config_bits(const struct sp_port_config *config, int *bits_ptr);
|
||||
|
||||
/**
|
||||
* Set the data bits in a port configuration.
|
||||
@ -875,7 +974,7 @@ enum sp_return sp_get_config_bits(const struct sp_port_config *config, int *bits
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_config_bits(struct sp_port_config *config, int bits);
|
||||
SP_API enum sp_return sp_set_config_bits(struct sp_port_config *config, int bits);
|
||||
|
||||
/**
|
||||
* Set the parity setting for the specified serial port.
|
||||
@ -887,7 +986,7 @@ enum sp_return sp_set_config_bits(struct sp_port_config *config, int bits);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_parity(struct sp_port *port, enum sp_parity parity);
|
||||
SP_API enum sp_return sp_set_parity(struct sp_port *port, enum sp_parity parity);
|
||||
|
||||
/**
|
||||
* Get the parity setting from a port configuration.
|
||||
@ -902,7 +1001,7 @@ enum sp_return sp_set_parity(struct sp_port *port, enum sp_parity parity);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_get_config_parity(const struct sp_port_config *config, enum sp_parity *parity_ptr);
|
||||
SP_API enum sp_return sp_get_config_parity(const struct sp_port_config *config, enum sp_parity *parity_ptr);
|
||||
|
||||
/**
|
||||
* Set the parity setting in a port configuration.
|
||||
@ -914,7 +1013,7 @@ enum sp_return sp_get_config_parity(const struct sp_port_config *config, enum sp
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_config_parity(struct sp_port_config *config, enum sp_parity parity);
|
||||
SP_API enum sp_return sp_set_config_parity(struct sp_port_config *config, enum sp_parity parity);
|
||||
|
||||
/**
|
||||
* Set the stop bits for the specified serial port.
|
||||
@ -926,7 +1025,7 @@ enum sp_return sp_set_config_parity(struct sp_port_config *config, enum sp_parit
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_stopbits(struct sp_port *port, int stopbits);
|
||||
SP_API enum sp_return sp_set_stopbits(struct sp_port *port, int stopbits);
|
||||
|
||||
/**
|
||||
* Get the stop bits from a port configuration.
|
||||
@ -941,7 +1040,7 @@ enum sp_return sp_set_stopbits(struct sp_port *port, int stopbits);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_get_config_stopbits(const struct sp_port_config *config, int *stopbits_ptr);
|
||||
SP_API enum sp_return sp_get_config_stopbits(const struct sp_port_config *config, int *stopbits_ptr);
|
||||
|
||||
/**
|
||||
* Set the stop bits in a port configuration.
|
||||
@ -953,7 +1052,7 @@ enum sp_return sp_get_config_stopbits(const struct sp_port_config *config, int *
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_config_stopbits(struct sp_port_config *config, int stopbits);
|
||||
SP_API enum sp_return sp_set_config_stopbits(struct sp_port_config *config, int stopbits);
|
||||
|
||||
/**
|
||||
* Set the RTS pin behaviour for the specified serial port.
|
||||
@ -965,7 +1064,7 @@ enum sp_return sp_set_config_stopbits(struct sp_port_config *config, int stopbit
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_rts(struct sp_port *port, enum sp_rts rts);
|
||||
SP_API enum sp_return sp_set_rts(struct sp_port *port, enum sp_rts rts);
|
||||
|
||||
/**
|
||||
* Get the RTS pin behaviour from a port configuration.
|
||||
@ -980,7 +1079,7 @@ enum sp_return sp_set_rts(struct sp_port *port, enum sp_rts rts);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_get_config_rts(const struct sp_port_config *config, enum sp_rts *rts_ptr);
|
||||
SP_API enum sp_return sp_get_config_rts(const struct sp_port_config *config, enum sp_rts *rts_ptr);
|
||||
|
||||
/**
|
||||
* Set the RTS pin behaviour in a port configuration.
|
||||
@ -992,7 +1091,7 @@ enum sp_return sp_get_config_rts(const struct sp_port_config *config, enum sp_rt
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_config_rts(struct sp_port_config *config, enum sp_rts rts);
|
||||
SP_API enum sp_return sp_set_config_rts(struct sp_port_config *config, enum sp_rts rts);
|
||||
|
||||
/**
|
||||
* Set the CTS pin behaviour for the specified serial port.
|
||||
@ -1004,7 +1103,7 @@ enum sp_return sp_set_config_rts(struct sp_port_config *config, enum sp_rts rts)
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_cts(struct sp_port *port, enum sp_cts cts);
|
||||
SP_API enum sp_return sp_set_cts(struct sp_port *port, enum sp_cts cts);
|
||||
|
||||
/**
|
||||
* Get the CTS pin behaviour from a port configuration.
|
||||
@ -1019,7 +1118,7 @@ enum sp_return sp_set_cts(struct sp_port *port, enum sp_cts cts);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_get_config_cts(const struct sp_port_config *config, enum sp_cts *cts_ptr);
|
||||
SP_API enum sp_return sp_get_config_cts(const struct sp_port_config *config, enum sp_cts *cts_ptr);
|
||||
|
||||
/**
|
||||
* Set the CTS pin behaviour in a port configuration.
|
||||
@ -1031,7 +1130,7 @@ enum sp_return sp_get_config_cts(const struct sp_port_config *config, enum sp_ct
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_config_cts(struct sp_port_config *config, enum sp_cts cts);
|
||||
SP_API enum sp_return sp_set_config_cts(struct sp_port_config *config, enum sp_cts cts);
|
||||
|
||||
/**
|
||||
* Set the DTR pin behaviour for the specified serial port.
|
||||
@ -1043,7 +1142,7 @@ enum sp_return sp_set_config_cts(struct sp_port_config *config, enum sp_cts cts)
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_dtr(struct sp_port *port, enum sp_dtr dtr);
|
||||
SP_API enum sp_return sp_set_dtr(struct sp_port *port, enum sp_dtr dtr);
|
||||
|
||||
/**
|
||||
* Get the DTR pin behaviour from a port configuration.
|
||||
@ -1058,7 +1157,7 @@ enum sp_return sp_set_dtr(struct sp_port *port, enum sp_dtr dtr);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_get_config_dtr(const struct sp_port_config *config, enum sp_dtr *dtr_ptr);
|
||||
SP_API enum sp_return sp_get_config_dtr(const struct sp_port_config *config, enum sp_dtr *dtr_ptr);
|
||||
|
||||
/**
|
||||
* Set the DTR pin behaviour in a port configuration.
|
||||
@ -1070,7 +1169,7 @@ enum sp_return sp_get_config_dtr(const struct sp_port_config *config, enum sp_dt
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_config_dtr(struct sp_port_config *config, enum sp_dtr dtr);
|
||||
SP_API enum sp_return sp_set_config_dtr(struct sp_port_config *config, enum sp_dtr dtr);
|
||||
|
||||
/**
|
||||
* Set the DSR pin behaviour for the specified serial port.
|
||||
@ -1082,7 +1181,7 @@ enum sp_return sp_set_config_dtr(struct sp_port_config *config, enum sp_dtr dtr)
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_dsr(struct sp_port *port, enum sp_dsr dsr);
|
||||
SP_API enum sp_return sp_set_dsr(struct sp_port *port, enum sp_dsr dsr);
|
||||
|
||||
/**
|
||||
* Get the DSR pin behaviour from a port configuration.
|
||||
@ -1097,7 +1196,7 @@ enum sp_return sp_set_dsr(struct sp_port *port, enum sp_dsr dsr);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_get_config_dsr(const struct sp_port_config *config, enum sp_dsr *dsr_ptr);
|
||||
SP_API enum sp_return sp_get_config_dsr(const struct sp_port_config *config, enum sp_dsr *dsr_ptr);
|
||||
|
||||
/**
|
||||
* Set the DSR pin behaviour in a port configuration.
|
||||
@ -1109,7 +1208,7 @@ enum sp_return sp_get_config_dsr(const struct sp_port_config *config, enum sp_ds
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_config_dsr(struct sp_port_config *config, enum sp_dsr dsr);
|
||||
SP_API enum sp_return sp_set_config_dsr(struct sp_port_config *config, enum sp_dsr dsr);
|
||||
|
||||
/**
|
||||
* Set the XON/XOFF configuration for the specified serial port.
|
||||
@ -1121,7 +1220,7 @@ enum sp_return sp_set_config_dsr(struct sp_port_config *config, enum sp_dsr dsr)
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_xon_xoff(struct sp_port *port, enum sp_xonxoff xon_xoff);
|
||||
SP_API enum sp_return sp_set_xon_xoff(struct sp_port *port, enum sp_xonxoff xon_xoff);
|
||||
|
||||
/**
|
||||
* Get the XON/XOFF configuration from a port configuration.
|
||||
@ -1136,7 +1235,7 @@ enum sp_return sp_set_xon_xoff(struct sp_port *port, enum sp_xonxoff xon_xoff);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_get_config_xon_xoff(const struct sp_port_config *config, enum sp_xonxoff *xon_xoff_ptr);
|
||||
SP_API enum sp_return sp_get_config_xon_xoff(const struct sp_port_config *config, enum sp_xonxoff *xon_xoff_ptr);
|
||||
|
||||
/**
|
||||
* Set the XON/XOFF configuration in a port configuration.
|
||||
@ -1148,7 +1247,7 @@ enum sp_return sp_get_config_xon_xoff(const struct sp_port_config *config, enum
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_config_xon_xoff(struct sp_port_config *config, enum sp_xonxoff xon_xoff);
|
||||
SP_API enum sp_return sp_set_config_xon_xoff(struct sp_port_config *config, enum sp_xonxoff xon_xoff);
|
||||
|
||||
/**
|
||||
* Set the flow control type in a port configuration.
|
||||
@ -1165,7 +1264,7 @@ enum sp_return sp_set_config_xon_xoff(struct sp_port_config *config, enum sp_xon
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config, enum sp_flowcontrol flowcontrol);
|
||||
SP_API enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config, enum sp_flowcontrol flowcontrol);
|
||||
|
||||
/**
|
||||
* Set the flow control type for the specified serial port.
|
||||
@ -1182,7 +1281,7 @@ enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config, enum sp_
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_set_flowcontrol(struct sp_port *port, enum sp_flowcontrol flowcontrol);
|
||||
SP_API enum sp_return sp_set_flowcontrol(struct sp_port *port, enum sp_flowcontrol flowcontrol);
|
||||
|
||||
/**
|
||||
* @}
|
||||
@ -1191,6 +1290,8 @@ enum sp_return sp_set_flowcontrol(struct sp_port *port, enum sp_flowcontrol flow
|
||||
*
|
||||
* Reading, writing, and flushing data.
|
||||
*
|
||||
* See @ref send_receive.c for an example of sending and receiving data.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
@ -1220,7 +1321,7 @@ enum sp_return sp_set_flowcontrol(struct sp_port *port, enum sp_flowcontrol flow
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_blocking_read(struct sp_port *port, void *buf, size_t count, unsigned int timeout_ms);
|
||||
SP_API enum sp_return sp_blocking_read(struct sp_port *port, void *buf, size_t count, unsigned int timeout_ms);
|
||||
|
||||
/**
|
||||
* Read bytes from the specified serial port, returning as soon as any data is
|
||||
@ -1248,7 +1349,7 @@ enum sp_return sp_blocking_read(struct sp_port *port, void *buf, size_t count, u
|
||||
*
|
||||
* @since 0.1.1
|
||||
*/
|
||||
enum sp_return sp_blocking_read_next(struct sp_port *port, void *buf, size_t count, unsigned int timeout_ms);
|
||||
SP_API enum sp_return sp_blocking_read_next(struct sp_port *port, void *buf, size_t count, unsigned int timeout_ms);
|
||||
|
||||
/**
|
||||
* Read bytes from the specified serial port, without blocking.
|
||||
@ -1263,7 +1364,7 @@ enum sp_return sp_blocking_read_next(struct sp_port *port, void *buf, size_t cou
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_nonblocking_read(struct sp_port *port, void *buf, size_t count);
|
||||
SP_API enum sp_return sp_nonblocking_read(struct sp_port *port, void *buf, size_t count);
|
||||
|
||||
/**
|
||||
* Write bytes to the specified serial port, blocking until complete.
|
||||
@ -1299,7 +1400,7 @@ enum sp_return sp_nonblocking_read(struct sp_port *port, void *buf, size_t count
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_blocking_write(struct sp_port *port, const void *buf, size_t count, unsigned int timeout_ms);
|
||||
SP_API enum sp_return sp_blocking_write(struct sp_port *port, const void *buf, size_t count, unsigned int timeout_ms);
|
||||
|
||||
/**
|
||||
* Write bytes to the specified serial port, without blocking.
|
||||
@ -1320,7 +1421,7 @@ enum sp_return sp_blocking_write(struct sp_port *port, const void *buf, size_t c
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_nonblocking_write(struct sp_port *port, const void *buf, size_t count);
|
||||
SP_API enum sp_return sp_nonblocking_write(struct sp_port *port, const void *buf, size_t count);
|
||||
|
||||
/**
|
||||
* Gets the number of bytes waiting in the input buffer.
|
||||
@ -1331,7 +1432,7 @@ enum sp_return sp_nonblocking_write(struct sp_port *port, const void *buf, size_
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_input_waiting(struct sp_port *port);
|
||||
SP_API enum sp_return sp_input_waiting(struct sp_port *port);
|
||||
|
||||
/**
|
||||
* Gets the number of bytes waiting in the output buffer.
|
||||
@ -1342,7 +1443,7 @@ enum sp_return sp_input_waiting(struct sp_port *port);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_output_waiting(struct sp_port *port);
|
||||
SP_API enum sp_return sp_output_waiting(struct sp_port *port);
|
||||
|
||||
/**
|
||||
* Flush serial port buffers. Data in the selected buffer(s) is discarded.
|
||||
@ -1354,7 +1455,7 @@ enum sp_return sp_output_waiting(struct sp_port *port);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers);
|
||||
SP_API enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers);
|
||||
|
||||
/**
|
||||
* Wait for buffered data to be transmitted.
|
||||
@ -1372,7 +1473,7 @@ enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_drain(struct sp_port *port);
|
||||
SP_API enum sp_return sp_drain(struct sp_port *port);
|
||||
|
||||
/**
|
||||
* @}
|
||||
@ -1381,6 +1482,8 @@ enum sp_return sp_drain(struct sp_port *port);
|
||||
*
|
||||
* Waiting for events and timeout handling.
|
||||
*
|
||||
* See @ref await_events.c for an example of awaiting events on multiple ports.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
@ -1400,7 +1503,7 @@ enum sp_return sp_drain(struct sp_port *port);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_new_event_set(struct sp_event_set **result_ptr);
|
||||
SP_API enum sp_return sp_new_event_set(struct sp_event_set **result_ptr);
|
||||
|
||||
/**
|
||||
* Add events to a struct sp_event_set for a given port.
|
||||
@ -1419,7 +1522,7 @@ enum sp_return sp_new_event_set(struct sp_event_set **result_ptr);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_add_port_events(struct sp_event_set *event_set,
|
||||
SP_API enum sp_return sp_add_port_events(struct sp_event_set *event_set,
|
||||
const struct sp_port *port, enum sp_event mask);
|
||||
|
||||
/**
|
||||
@ -1432,7 +1535,7 @@ enum sp_return sp_add_port_events(struct sp_event_set *event_set,
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_wait(struct sp_event_set *event_set, unsigned int timeout_ms);
|
||||
SP_API enum sp_return sp_wait(struct sp_event_set *event_set, unsigned int timeout_ms);
|
||||
|
||||
/**
|
||||
* Free a structure allocated by sp_new_event_set().
|
||||
@ -1441,7 +1544,7 @@ enum sp_return sp_wait(struct sp_event_set *event_set, unsigned int timeout_ms);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
void sp_free_event_set(struct sp_event_set *event_set);
|
||||
SP_API void sp_free_event_set(struct sp_event_set *event_set);
|
||||
|
||||
/**
|
||||
* @}
|
||||
@ -1469,7 +1572,7 @@ void sp_free_event_set(struct sp_event_set *event_set);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_get_signals(struct sp_port *port, enum sp_signal *signal_mask);
|
||||
SP_API enum sp_return sp_get_signals(struct sp_port *port, enum sp_signal *signal_mask);
|
||||
|
||||
/**
|
||||
* Put the port transmit line into the break state.
|
||||
@ -1480,7 +1583,7 @@ enum sp_return sp_get_signals(struct sp_port *port, enum sp_signal *signal_mask)
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_start_break(struct sp_port *port);
|
||||
SP_API enum sp_return sp_start_break(struct sp_port *port);
|
||||
|
||||
/**
|
||||
* Take the port transmit line out of the break state.
|
||||
@ -1491,7 +1594,7 @@ enum sp_return sp_start_break(struct sp_port *port);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum sp_return sp_end_break(struct sp_port *port);
|
||||
SP_API enum sp_return sp_end_break(struct sp_port *port);
|
||||
|
||||
/**
|
||||
* @}
|
||||
@ -1500,6 +1603,8 @@ enum sp_return sp_end_break(struct sp_port *port);
|
||||
*
|
||||
* Obtaining error information.
|
||||
*
|
||||
* See @ref handle_errors.c for an example of error handling.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
@ -1516,7 +1621,7 @@ enum sp_return sp_end_break(struct sp_port *port);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
int sp_last_error_code(void);
|
||||
SP_API int sp_last_error_code(void);
|
||||
|
||||
/**
|
||||
* Get the error message for a failed operation.
|
||||
@ -1532,7 +1637,7 @@ int sp_last_error_code(void);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
char *sp_last_error_message(void);
|
||||
SP_API char *sp_last_error_message(void);
|
||||
|
||||
/**
|
||||
* Free an error message returned by sp_last_error_message().
|
||||
@ -1541,7 +1646,7 @@ char *sp_last_error_message(void);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
void sp_free_error_message(char *message);
|
||||
SP_API void sp_free_error_message(char *message);
|
||||
|
||||
/**
|
||||
* Set the handler function for library debugging messages.
|
||||
@ -1560,7 +1665,7 @@ void sp_free_error_message(char *message);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
void sp_set_debug_handler(void (*handler)(const char *format, ...));
|
||||
SP_API void sp_set_debug_handler(void (*handler)(const char *format, ...));
|
||||
|
||||
/**
|
||||
* Default handler function for library debugging messages.
|
||||
@ -1574,7 +1679,7 @@ void sp_set_debug_handler(void (*handler)(const char *format, ...));
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
void sp_default_debug_handler(const char *format, ...);
|
||||
SP_API void sp_default_debug_handler(const char *format, ...);
|
||||
|
||||
/** @} */
|
||||
|
||||
@ -1603,32 +1708,32 @@ void sp_default_debug_handler(const char *format, ...);
|
||||
*/
|
||||
|
||||
/** The libserialport package 'major' version number. */
|
||||
#undef SP_PACKAGE_VERSION_MAJOR
|
||||
#define SP_PACKAGE_VERSION_MAJOR 0
|
||||
|
||||
/** The libserialport package 'minor' version number. */
|
||||
#undef SP_PACKAGE_VERSION_MINOR
|
||||
#define SP_PACKAGE_VERSION_MINOR 1
|
||||
|
||||
/** The libserialport package 'micro' version number. */
|
||||
#undef SP_PACKAGE_VERSION_MICRO
|
||||
#define SP_PACKAGE_VERSION_MICRO 1
|
||||
|
||||
/** The libserialport package version ("major.minor.micro") as string. */
|
||||
#undef SP_PACKAGE_VERSION_STRING
|
||||
#define SP_PACKAGE_VERSION_STRING "0.1.1"
|
||||
|
||||
/*
|
||||
* Library/libtool version macros (can be used for conditional compilation).
|
||||
*/
|
||||
|
||||
/** The libserialport libtool 'current' version number. */
|
||||
#undef SP_LIB_VERSION_CURRENT
|
||||
#define SP_LIB_VERSION_CURRENT 1
|
||||
|
||||
/** The libserialport libtool 'revision' version number. */
|
||||
#undef SP_LIB_VERSION_REVISION
|
||||
#define SP_LIB_VERSION_REVISION 0
|
||||
|
||||
/** The libserialport libtool 'age' version number. */
|
||||
#undef SP_LIB_VERSION_AGE
|
||||
#define SP_LIB_VERSION_AGE 1
|
||||
|
||||
/** The libserialport libtool version ("current:revision:age") as string. */
|
||||
#undef SP_LIB_VERSION_STRING
|
||||
#define SP_LIB_VERSION_STRING "1:0:1"
|
||||
|
||||
/**
|
||||
* Get the major libserialport package version number.
|
||||
@ -1637,7 +1742,7 @@ void sp_default_debug_handler(const char *format, ...);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
int sp_get_major_package_version(void);
|
||||
SP_API int sp_get_major_package_version(void);
|
||||
|
||||
/**
|
||||
* Get the minor libserialport package version number.
|
||||
@ -1646,7 +1751,7 @@ int sp_get_major_package_version(void);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
int sp_get_minor_package_version(void);
|
||||
SP_API int sp_get_minor_package_version(void);
|
||||
|
||||
/**
|
||||
* Get the micro libserialport package version number.
|
||||
@ -1655,7 +1760,7 @@ int sp_get_minor_package_version(void);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
int sp_get_micro_package_version(void);
|
||||
SP_API int sp_get_micro_package_version(void);
|
||||
|
||||
/**
|
||||
* Get the libserialport package version number as a string.
|
||||
@ -1665,7 +1770,7 @@ int sp_get_micro_package_version(void);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
const char *sp_get_package_version_string(void);
|
||||
SP_API const char *sp_get_package_version_string(void);
|
||||
|
||||
/**
|
||||
* Get the "current" part of the libserialport library version number.
|
||||
@ -1674,7 +1779,7 @@ const char *sp_get_package_version_string(void);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
int sp_get_current_lib_version(void);
|
||||
SP_API int sp_get_current_lib_version(void);
|
||||
|
||||
/**
|
||||
* Get the "revision" part of the libserialport library version number.
|
||||
@ -1683,7 +1788,7 @@ int sp_get_current_lib_version(void);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
int sp_get_revision_lib_version(void);
|
||||
SP_API int sp_get_revision_lib_version(void);
|
||||
|
||||
/**
|
||||
* Get the "age" part of the libserialport library version number.
|
||||
@ -1692,7 +1797,7 @@ int sp_get_revision_lib_version(void);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
int sp_get_age_lib_version(void);
|
||||
SP_API int sp_get_age_lib_version(void);
|
||||
|
||||
/**
|
||||
* Get the libserialport library version number as a string.
|
||||
@ -1702,10 +1807,19 @@ int sp_get_age_lib_version(void);
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
const char *sp_get_lib_version_string(void);
|
||||
SP_API const char *sp_get_lib_version_string(void);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @example list_ports.c Getting a list of ports present on the system.
|
||||
* @example port_info.c Getting information on a particular serial port.
|
||||
* @example port_config.c Accessing configuration settings of a port.
|
||||
* @example send_receive.c Sending and receiving data.
|
||||
* @example await_events.c Awaiting events on multiple ports.
|
||||
* @example handle_errors.c Handling errors returned from the library.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -6,7 +6,7 @@ includedir=@includedir@
|
||||
Name: libserialport
|
||||
Description: Cross-platform serial port access library.
|
||||
URL: http://sigrok.org/wiki/Libserialport
|
||||
Requires.private:
|
||||
Requires.private: @SP_PKGLIBS@
|
||||
Version: @SP_PACKAGE_VERSION@
|
||||
Libs: -L${libdir} -lserialport
|
||||
Libs.private: @SP_LIBS@
|
||||
|
31
libserialport.sln
Normal file
31
libserialport.sln
Normal file
@ -0,0 +1,31 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29613.14
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libserialport", "libserialport.vcxproj", "{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Debug|x64.Build.0 = Debug|x64
|
||||
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Debug|x86.Build.0 = Debug|Win32
|
||||
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Release|x64.ActiveCfg = Release|x64
|
||||
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Release|x64.Build.0 = Release|x64
|
||||
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Release|x86.ActiveCfg = Release|Win32
|
||||
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {C2042526-D57D-45CA-B39F-6D9A782D1A05}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
84
libserialport.vcxproj
Normal file
84
libserialport.vcxproj
Normal file
@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="libserialport.h" />
|
||||
<ClInclude Include="libserialport_internal.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="serialport.c" />
|
||||
<ClCompile Include="timing.c" />
|
||||
<ClCompile Include="windows.c" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>libserialport</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)'=='Debug'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
<Import Project="debug.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)'=='Release'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="common.props" />
|
||||
<Import Project="release.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
36
libserialport.vcxproj.filters
Normal file
36
libserialport.vcxproj.filters
Normal file
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="libserialport.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="libserialport_internal.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="serialport.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="windows.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="timing.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -21,23 +21,44 @@
|
||||
#ifndef LIBSERIALPORT_LIBSERIALPORT_INTERNAL_H
|
||||
#define LIBSERIALPORT_LIBSERIALPORT_INTERNAL_H
|
||||
|
||||
/* These MSVC-specific defines must appear before other headers.*/
|
||||
#ifdef _MSC_VER
|
||||
#define _CRT_NONSTDC_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
/* For timeradd, timersub, timercmp. */
|
||||
/* These feature test macros must appear before other headers.*/
|
||||
#if defined(__linux__) || defined(__CYGWIN__)
|
||||
/* For timeradd, timersub, timercmp, realpath. */
|
||||
#define _BSD_SOURCE 1 /* for glibc < 2.19 */
|
||||
#define _DEFAULT_SOURCE 1 /* for glibc >= 2.20 */
|
||||
/* For clock_gettime and associated types. */
|
||||
#define _POSIX_C_SOURCE 199309L
|
||||
#endif
|
||||
|
||||
#ifdef LIBSERIALPORT_ATBUILD
|
||||
/* If building with autoconf, include the generated config.h. */
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef LIBSERIALPORT_MSBUILD
|
||||
/* If building with MS tools, define necessary things that
|
||||
would otherwise appear in config.h. */
|
||||
#define SP_PRIV
|
||||
#endif
|
||||
|
||||
#include "libserialport.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
@ -48,13 +69,22 @@
|
||||
static const GUID name = { l,w1,w2,{ b1,b2,b3,b4,b5,b6,b7,b8 } }
|
||||
#include <usbioctl.h>
|
||||
#include <usbiodef.h>
|
||||
/* The largest size that can be passed to WriteFile() safely
|
||||
* on any architecture. This arises from the expression:
|
||||
* PAGE_SIZE * (65535 - sizeof(MDL)) / sizeof(ULONG_PTR)
|
||||
* and this worst-case value is found on x64. */
|
||||
#define WRITEFILE_MAX_SIZE 33525760
|
||||
#else
|
||||
#include <limits.h>
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_SYS_FILE_H
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
@ -62,11 +92,13 @@
|
||||
#include <IOKit/serial/IOSerialKeys.h>
|
||||
#include <IOKit/serial/ioss.h>
|
||||
#include <sys/syslimits.h>
|
||||
#include <mach/mach_time.h>
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
#include <dirent.h>
|
||||
#ifndef __ANDROID__
|
||||
#include "linux/serial.h"
|
||||
/* Android only has linux/serial.h from platform 21 onwards. */
|
||||
#if !(defined(__ANDROID__) && (__ANDROID_API__ < 21))
|
||||
#include <linux/serial.h>
|
||||
#endif
|
||||
#include "linux_termios.h"
|
||||
|
||||
@ -84,8 +116,18 @@
|
||||
#define TIOCOUTQ FIONWRITE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* O_CLOEXEC is not available everywhere, fallback to not setting the
|
||||
* flag on those systems.
|
||||
*/
|
||||
#ifndef _WIN32
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Non-standard baudrates are not available everywhere. */
|
||||
#if (defined(HAVE_TERMIOS_SPEED) || defined(HAVE_TERMIOS2_SPEED)) && defined(HAVE_DECL_BOTHER)
|
||||
#if (defined(HAVE_TERMIOS_SPEED) || defined(HAVE_TERMIOS2_SPEED)) && HAVE_DECL_BOTHER
|
||||
#define USE_TERMIOS_SPEED
|
||||
#endif
|
||||
|
||||
@ -109,7 +151,8 @@ struct sp_port {
|
||||
OVERLAPPED read_ovl;
|
||||
OVERLAPPED wait_ovl;
|
||||
DWORD events;
|
||||
BYTE pending_byte;
|
||||
BYTE *write_buf;
|
||||
DWORD write_buf_size;
|
||||
BOOL writing;
|
||||
BOOL wait_running;
|
||||
#else
|
||||
@ -234,4 +277,35 @@ SP_PRIV struct sp_port **list_append(struct sp_port **list, const char *portname
|
||||
SP_PRIV enum sp_return get_port_details(struct sp_port *port);
|
||||
SP_PRIV enum sp_return list_ports(struct sp_port ***list);
|
||||
|
||||
/* Timing abstraction */
|
||||
|
||||
struct time {
|
||||
#ifdef _WIN32
|
||||
int64_t ticks;
|
||||
#else
|
||||
struct timeval tv;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct timeout {
|
||||
unsigned int ms, limit_ms;
|
||||
struct time start, now, end, delta, delta_max;
|
||||
struct timeval delta_tv;
|
||||
bool calls_started, overflow;
|
||||
};
|
||||
|
||||
SP_PRIV void time_get(struct time *time);
|
||||
SP_PRIV void time_set_ms(struct time *time, unsigned int ms);
|
||||
SP_PRIV void time_add(const struct time *a, const struct time *b, struct time *result);
|
||||
SP_PRIV void time_sub(const struct time *a, const struct time *b, struct time *result);
|
||||
SP_PRIV bool time_greater(const struct time *a, const struct time *b);
|
||||
SP_PRIV void time_as_timeval(const struct time *time, struct timeval *tv);
|
||||
SP_PRIV unsigned int time_as_ms(const struct time *time);
|
||||
SP_PRIV void timeout_start(struct timeout *timeout, unsigned int timeout_ms);
|
||||
SP_PRIV void timeout_limit(struct timeout *timeout, unsigned int limit_ms);
|
||||
SP_PRIV bool timeout_check(struct timeout *timeout);
|
||||
SP_PRIV void timeout_update(struct timeout *timeout);
|
||||
SP_PRIV struct timeval *timeout_timeval(struct timeout *timeout);
|
||||
SP_PRIV unsigned int timeout_remaining_ms(struct timeout *timeout);
|
||||
|
||||
#endif
|
||||
|
54
linux.c
54
linux.c
@ -22,6 +22,18 @@
|
||||
#include "libserialport.h"
|
||||
#include "libserialport_internal.h"
|
||||
|
||||
/*
|
||||
* The 'e' modifier for O_CLOEXEC is glibc >= 2.7 only, hence not
|
||||
* portable, so provide an own wrapper for this functionality.
|
||||
*/
|
||||
static FILE *fopen_cloexec_rdonly(const char *pathname)
|
||||
{
|
||||
int fd;
|
||||
if ((fd = open(pathname, O_RDONLY | O_CLOEXEC)) < 0)
|
||||
return NULL;
|
||||
return fdopen(fd, "r");
|
||||
}
|
||||
|
||||
SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
||||
{
|
||||
/*
|
||||
@ -34,7 +46,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
||||
char manufacturer[128], product[128], serial[128];
|
||||
char baddr[32];
|
||||
const char dir_name[] = "/sys/class/tty/%s/device/%s%s";
|
||||
char sub_dir[32] = "", file_name[PATH_MAX];
|
||||
char sub_dir[32] = "", link_name[PATH_MAX], file_name[PATH_MAX];
|
||||
char *ptr, *dev = port->name + 5;
|
||||
FILE *file;
|
||||
int i, count;
|
||||
@ -43,12 +55,12 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
||||
if (strncmp(port->name, "/dev/", 5))
|
||||
RETURN_ERROR(SP_ERR_ARG, "Device name not recognized");
|
||||
|
||||
snprintf(file_name, sizeof(file_name), "/sys/class/tty/%s", dev);
|
||||
if (lstat(file_name, &statbuf) == -1)
|
||||
snprintf(link_name, sizeof(link_name), "/sys/class/tty/%s", dev);
|
||||
if (lstat(link_name, &statbuf) == -1)
|
||||
RETURN_ERROR(SP_ERR_ARG, "Device not found");
|
||||
if (!S_ISLNK(statbuf.st_mode))
|
||||
snprintf(file_name, sizeof(file_name), "/sys/class/tty/%s/device", dev);
|
||||
count = readlink(file_name, file_name, sizeof(file_name));
|
||||
snprintf(link_name, sizeof(link_name), "/sys/class/tty/%s/device", dev);
|
||||
count = readlink(link_name, file_name, sizeof(file_name));
|
||||
if (count <= 0 || count >= (int)(sizeof(file_name) - 1))
|
||||
RETURN_ERROR(SP_ERR_ARG, "Device not found");
|
||||
file_name[count] = 0;
|
||||
@ -62,7 +74,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
||||
strcat(sub_dir, "../");
|
||||
|
||||
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "busnum");
|
||||
if (!(file = fopen(file_name, "r")))
|
||||
if (!(file = fopen_cloexec_rdonly(file_name)))
|
||||
continue;
|
||||
count = fscanf(file, "%d", &bus);
|
||||
fclose(file);
|
||||
@ -70,7 +82,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
||||
continue;
|
||||
|
||||
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "devnum");
|
||||
if (!(file = fopen(file_name, "r")))
|
||||
if (!(file = fopen_cloexec_rdonly(file_name)))
|
||||
continue;
|
||||
count = fscanf(file, "%d", &address);
|
||||
fclose(file);
|
||||
@ -78,7 +90,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
||||
continue;
|
||||
|
||||
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "idVendor");
|
||||
if (!(file = fopen(file_name, "r")))
|
||||
if (!(file = fopen_cloexec_rdonly(file_name)))
|
||||
continue;
|
||||
count = fscanf(file, "%4x", &vid);
|
||||
fclose(file);
|
||||
@ -86,7 +98,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
||||
continue;
|
||||
|
||||
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "idProduct");
|
||||
if (!(file = fopen(file_name, "r")))
|
||||
if (!(file = fopen_cloexec_rdonly(file_name)))
|
||||
continue;
|
||||
count = fscanf(file, "%4x", &pid);
|
||||
fclose(file);
|
||||
@ -99,7 +111,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
||||
port->usb_pid = pid;
|
||||
|
||||
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "product");
|
||||
if ((file = fopen(file_name, "r"))) {
|
||||
if ((file = fopen_cloexec_rdonly(file_name))) {
|
||||
if ((ptr = fgets(description, sizeof(description), file))) {
|
||||
ptr = description + strlen(description) - 1;
|
||||
if (ptr >= description && *ptr == '\n')
|
||||
@ -112,7 +124,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
||||
port->description = strdup(dev);
|
||||
|
||||
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "manufacturer");
|
||||
if ((file = fopen(file_name, "r"))) {
|
||||
if ((file = fopen_cloexec_rdonly(file_name))) {
|
||||
if ((ptr = fgets(manufacturer, sizeof(manufacturer), file))) {
|
||||
ptr = manufacturer + strlen(manufacturer) - 1;
|
||||
if (ptr >= manufacturer && *ptr == '\n')
|
||||
@ -123,7 +135,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
||||
}
|
||||
|
||||
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "product");
|
||||
if ((file = fopen(file_name, "r"))) {
|
||||
if ((file = fopen_cloexec_rdonly(file_name))) {
|
||||
if ((ptr = fgets(product, sizeof(product), file))) {
|
||||
ptr = product + strlen(product) - 1;
|
||||
if (ptr >= product && *ptr == '\n')
|
||||
@ -134,7 +146,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
||||
}
|
||||
|
||||
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "serial");
|
||||
if ((file = fopen(file_name, "r"))) {
|
||||
if ((file = fopen_cloexec_rdonly(file_name))) {
|
||||
if ((ptr = fgets(serial, sizeof(serial), file))) {
|
||||
ptr = serial + strlen(serial) - 1;
|
||||
if (ptr >= serial && *ptr == '\n')
|
||||
@ -160,7 +172,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
||||
|
||||
if (port->transport == SP_TRANSPORT_BLUETOOTH) {
|
||||
snprintf(file_name, sizeof(file_name), dir_name, dev, "", "address");
|
||||
if ((file = fopen(file_name, "r"))) {
|
||||
if ((file = fopen_cloexec_rdonly(file_name))) {
|
||||
if ((ptr = fgets(baddr, sizeof(baddr), file))) {
|
||||
ptr = baddr + strlen(baddr) - 1;
|
||||
if (ptr >= baddr && *ptr == '\n')
|
||||
@ -178,12 +190,12 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
||||
SP_PRIV enum sp_return list_ports(struct sp_port ***list)
|
||||
{
|
||||
char name[PATH_MAX], target[PATH_MAX];
|
||||
struct dirent entry, *result;
|
||||
struct dirent *entry;
|
||||
#ifdef HAVE_STRUCT_SERIAL_STRUCT
|
||||
struct serial_struct serial_info;
|
||||
int ioctl_result;
|
||||
#endif
|
||||
char buf[sizeof(entry.d_name) + 23];
|
||||
char buf[sizeof(entry->d_name) + 23];
|
||||
int len, fd;
|
||||
DIR *dir;
|
||||
int ret = SP_OK;
|
||||
@ -194,19 +206,19 @@ SP_PRIV enum sp_return list_ports(struct sp_port ***list)
|
||||
RETURN_FAIL("Could not open /sys/class/tty");
|
||||
|
||||
DEBUG("Iterating over results");
|
||||
while (!readdir_r(dir, &entry, &result) && result) {
|
||||
snprintf(buf, sizeof(buf), "/sys/class/tty/%s", entry.d_name);
|
||||
while ((entry = readdir(dir))) {
|
||||
snprintf(buf, sizeof(buf), "/sys/class/tty/%s", entry->d_name);
|
||||
if (lstat(buf, &statbuf) == -1)
|
||||
continue;
|
||||
if (!S_ISLNK(statbuf.st_mode))
|
||||
snprintf(buf, sizeof(buf), "/sys/class/tty/%s/device", entry.d_name);
|
||||
snprintf(buf, sizeof(buf), "/sys/class/tty/%s/device", entry->d_name);
|
||||
len = readlink(buf, target, sizeof(target));
|
||||
if (len <= 0 || len >= (int)(sizeof(target) - 1))
|
||||
continue;
|
||||
target[len] = 0;
|
||||
if (strstr(target, "virtual"))
|
||||
continue;
|
||||
snprintf(name, sizeof(name), "/dev/%s", entry.d_name);
|
||||
snprintf(name, sizeof(name), "/dev/%s", entry->d_name);
|
||||
DEBUG_FMT("Found device %s", name);
|
||||
if (strstr(target, "serial8250")) {
|
||||
/*
|
||||
@ -215,7 +227,7 @@ SP_PRIV enum sp_return list_ports(struct sp_port ***list)
|
||||
* is to try to open them and make an ioctl call.
|
||||
*/
|
||||
DEBUG("serial8250 device, attempting to open");
|
||||
if ((fd = open(name, O_RDWR | O_NONBLOCK | O_NOCTTY)) < 0) {
|
||||
if ((fd = open(name, O_RDWR | O_NONBLOCK | O_NOCTTY | O_CLOEXEC)) < 0) {
|
||||
DEBUG("Open failed, skipping");
|
||||
continue;
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ SP_PRIV size_t get_termios_size(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (defined(HAVE_TERMIOS_SPEED) || defined(HAVE_TERMIOS2_SPEED)) && defined(HAVE_DECL_BOTHER)
|
||||
#if (defined(HAVE_TERMIOS_SPEED) || defined(HAVE_TERMIOS2_SPEED)) && HAVE_DECL_BOTHER
|
||||
SP_PRIV int get_termios_speed(void *data)
|
||||
{
|
||||
#ifdef HAVE_STRUCT_TERMIOS2
|
||||
|
20
release.props
Normal file
20
release.props
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Label="PropertySheets" />
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_PropertySheetDisplayName>Release</_PropertySheetDisplayName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>LIBSERIALPORT_MSBUILD;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup />
|
||||
</Project>
|
493
serialport.c
493
serialport.c
@ -21,8 +21,6 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "libserialport.h"
|
||||
#include "libserialport_internal.h"
|
||||
|
||||
static const struct std_baudrate std_baudrates[] = {
|
||||
@ -61,7 +59,7 @@ SP_API enum sp_return sp_get_port_by_name(const char *portname, struct sp_port *
|
||||
#ifndef NO_PORT_METADATA
|
||||
enum sp_return ret;
|
||||
#endif
|
||||
int len;
|
||||
size_t len;
|
||||
|
||||
TRACE("%s, %p", portname, port_ptr);
|
||||
|
||||
@ -75,6 +73,20 @@ SP_API enum sp_return sp_get_port_by_name(const char *portname, struct sp_port *
|
||||
|
||||
DEBUG_FMT("Building structure for port %s", portname);
|
||||
|
||||
#if !defined(_WIN32) && defined(HAVE_REALPATH)
|
||||
/*
|
||||
* get_port_details() below tries to be too smart and figure out
|
||||
* some transport properties from the port name which breaks with
|
||||
* symlinks. Therefore we canonicalize the portname first.
|
||||
*/
|
||||
char pathbuf[PATH_MAX + 1];
|
||||
char *res = realpath(portname, pathbuf);
|
||||
if (!res)
|
||||
RETURN_ERROR(SP_ERR_ARG, "Could not retrieve realpath behind port name");
|
||||
|
||||
portname = pathbuf;
|
||||
#endif
|
||||
|
||||
if (!(port = malloc(sizeof(struct sp_port))))
|
||||
RETURN_ERROR(SP_ERR_MEM, "Port structure malloc failed");
|
||||
|
||||
@ -90,6 +102,8 @@ SP_API enum sp_return sp_get_port_by_name(const char *portname, struct sp_port *
|
||||
#ifdef _WIN32
|
||||
port->usb_path = NULL;
|
||||
port->hdl = INVALID_HANDLE_VALUE;
|
||||
port->write_buf = NULL;
|
||||
port->write_buf_size = 0;
|
||||
#else
|
||||
port->fd = -1;
|
||||
#endif
|
||||
@ -141,10 +155,7 @@ SP_API enum sp_transport sp_get_port_transport(const struct sp_port *port)
|
||||
{
|
||||
TRACE("%p", port);
|
||||
|
||||
if (!port)
|
||||
RETURN_ERROR(SP_ERR_ARG, "Null port");
|
||||
|
||||
RETURN_INT(port->transport);
|
||||
RETURN_INT(port ? port->transport : SP_TRANSPORT_NATIVE);
|
||||
}
|
||||
|
||||
SP_API enum sp_return sp_get_port_usb_bus_address(const struct sp_port *port,
|
||||
@ -296,6 +307,8 @@ SP_API void sp_free_port(struct sp_port *port)
|
||||
#ifdef _WIN32
|
||||
if (port->usb_path)
|
||||
free(port->usb_path);
|
||||
if (port->write_buf)
|
||||
free(port->write_buf);
|
||||
#endif
|
||||
|
||||
free(port);
|
||||
@ -307,9 +320,10 @@ SP_PRIV struct sp_port **list_append(struct sp_port **list,
|
||||
const char *portname)
|
||||
{
|
||||
void *tmp;
|
||||
unsigned int count;
|
||||
size_t count;
|
||||
|
||||
for (count = 0; list[count]; count++);
|
||||
for (count = 0; list[count]; count++)
|
||||
;
|
||||
if (!(tmp = realloc(list, sizeof(struct sp_port *) * (count + 2))))
|
||||
goto fail;
|
||||
list = tmp;
|
||||
@ -471,7 +485,7 @@ SP_API enum sp_return sp_open(struct sp_port *port, enum sp_mode flags)
|
||||
if (flags & SP_MODE_WRITE)
|
||||
desired_access |= GENERIC_WRITE;
|
||||
|
||||
port->hdl = CreateFile(escaped_port_name, desired_access, 0, 0,
|
||||
port->hdl = CreateFileA(escaped_port_name, desired_access, 0, 0,
|
||||
OPEN_EXISTING, flags_and_attributes, 0);
|
||||
|
||||
free(escaped_port_name);
|
||||
@ -522,7 +536,7 @@ SP_API enum sp_return sp_open(struct sp_port *port, enum sp_mode flags)
|
||||
RETURN_CODEVAL(ret);
|
||||
}
|
||||
#else
|
||||
int flags_local = O_NONBLOCK | O_NOCTTY;
|
||||
int flags_local = O_NONBLOCK | O_NOCTTY | O_CLOEXEC;
|
||||
|
||||
/* Map 'flags' to the OS-specific settings. */
|
||||
if ((flags & SP_MODE_READ_WRITE) == SP_MODE_READ_WRITE)
|
||||
@ -534,6 +548,39 @@ SP_API enum sp_return sp_open(struct sp_port *port, enum sp_mode flags)
|
||||
|
||||
if ((port->fd = open(port->name, flags_local)) < 0)
|
||||
RETURN_FAIL("open() failed");
|
||||
|
||||
/*
|
||||
* On POSIX in the default case the file descriptor of a serial port
|
||||
* is not opened exclusively. Therefore the settings of a port are
|
||||
* overwritten if the serial port is opened a second time. Windows
|
||||
* opens all serial ports exclusively.
|
||||
* So the idea is to open the serial ports alike in the exclusive mode.
|
||||
*
|
||||
* ioctl(*, TIOCEXCL) defines the file descriptor as exclusive. So all
|
||||
* further open calls on the serial port will fail.
|
||||
*
|
||||
* There is a race condition if two processes open the same serial
|
||||
* port. None of the processes will notice the exclusive ownership of
|
||||
* the other process because ioctl() doesn't return an error code if
|
||||
* the file descriptor is already marked as exclusive.
|
||||
* This can be solved with flock(). It returns an error if the file
|
||||
* descriptor is already locked by another process.
|
||||
*/
|
||||
#ifdef HAVE_FLOCK
|
||||
if (flock(port->fd, LOCK_EX | LOCK_NB) < 0)
|
||||
RETURN_FAIL("flock() failed");
|
||||
#endif
|
||||
|
||||
#ifdef TIOCEXCL
|
||||
/*
|
||||
* Before Linux 3.8 ioctl(*, TIOCEXCL) was not implemented and could
|
||||
* lead to EINVAL or ENOTTY.
|
||||
* These errors aren't fatal and can be ignored.
|
||||
*/
|
||||
if (ioctl(port->fd, TIOCEXCL) < 0 && errno != EINVAL && errno != ENOTTY)
|
||||
RETURN_FAIL("ioctl() failed");
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
ret = get_config(port, &data, &config);
|
||||
@ -543,6 +590,15 @@ SP_API enum sp_return sp_open(struct sp_port *port, enum sp_mode flags)
|
||||
RETURN_CODEVAL(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Assume a default baudrate if the OS does not provide one.
|
||||
* Cannot assign -1 here since Windows holds the baudrate in
|
||||
* the DCB and does not configure the rate individually.
|
||||
*/
|
||||
if (config.baudrate == 0) {
|
||||
config.baudrate = 9600;
|
||||
}
|
||||
|
||||
/* Set sane port settings. */
|
||||
#ifdef _WIN32
|
||||
data.dcb.fBinary = TRUE;
|
||||
@ -586,7 +642,8 @@ SP_API enum sp_return sp_open(struct sp_port *port, enum sp_mode flags)
|
||||
data.term.c_cc[VTIME] = 0;
|
||||
|
||||
/* Ignore modem status lines; enable receiver; leave control lines alone on close. */
|
||||
data.term.c_cflag |= (CLOCAL | CREAD | HUPCL);
|
||||
data.term.c_cflag |= (CLOCAL | CREAD);
|
||||
data.term.c_cflag &= ~(HUPCL);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -628,6 +685,10 @@ SP_API enum sp_return sp_close(struct sp_port *port)
|
||||
CLOSE_OVERLAPPED(write_ovl);
|
||||
CLOSE_OVERLAPPED(wait_ovl);
|
||||
|
||||
if (port->write_buf) {
|
||||
free(port->write_buf);
|
||||
port->write_buf = NULL;
|
||||
}
|
||||
#else
|
||||
/* Returns 0 upon success, -1 upon failure. */
|
||||
if (close(port->fd) == -1)
|
||||
@ -697,7 +758,9 @@ SP_API enum sp_return sp_drain(struct sp_port *port)
|
||||
#else
|
||||
int result;
|
||||
while (1) {
|
||||
#ifdef __ANDROID__
|
||||
#if defined(__ANDROID__) && (__ANDROID_API__ < 21)
|
||||
/* Android only has tcdrain from platform 21 onwards.
|
||||
* On previous API versions, use the ioctl directly. */
|
||||
int arg = 1;
|
||||
result = ioctl(port->fd, TCSBRK, &arg);
|
||||
#else
|
||||
@ -717,6 +780,27 @@ SP_API enum sp_return sp_drain(struct sp_port *port)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static enum sp_return await_write_completion(struct sp_port *port)
|
||||
{
|
||||
TRACE("%p", port);
|
||||
DWORD bytes_written;
|
||||
BOOL result;
|
||||
|
||||
/* Wait for previous non-blocking write to complete, if any. */
|
||||
if (port->writing) {
|
||||
DEBUG("Waiting for previous write to complete");
|
||||
result = GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written, TRUE);
|
||||
port->writing = 0;
|
||||
if (!result)
|
||||
RETURN_FAIL("Previous write failed to complete");
|
||||
DEBUG("Previous write completed");
|
||||
}
|
||||
|
||||
RETURN_OK();
|
||||
}
|
||||
#endif
|
||||
|
||||
SP_API enum sp_return sp_blocking_write(struct sp_port *port, const void *buf,
|
||||
size_t count, unsigned int timeout_ms)
|
||||
{
|
||||
@ -738,82 +822,87 @@ SP_API enum sp_return sp_blocking_write(struct sp_port *port, const void *buf,
|
||||
RETURN_INT(0);
|
||||
|
||||
#ifdef _WIN32
|
||||
DWORD bytes_written = 0;
|
||||
BOOL result;
|
||||
DWORD remaining_ms, write_size, bytes_written;
|
||||
size_t remaining_bytes, total_bytes_written = 0;
|
||||
const uint8_t *write_ptr = (uint8_t *) buf;
|
||||
bool result;
|
||||
struct timeout timeout;
|
||||
|
||||
/* Wait for previous non-blocking write to complete, if any. */
|
||||
if (port->writing) {
|
||||
DEBUG("Waiting for previous write to complete");
|
||||
result = GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written, TRUE);
|
||||
port->writing = 0;
|
||||
if (!result)
|
||||
RETURN_FAIL("Previous write failed to complete");
|
||||
DEBUG("Previous write completed");
|
||||
}
|
||||
timeout_start(&timeout, timeout_ms);
|
||||
|
||||
/* Set timeout. */
|
||||
if (port->timeouts.WriteTotalTimeoutConstant != timeout_ms) {
|
||||
port->timeouts.WriteTotalTimeoutConstant = timeout_ms;
|
||||
if (SetCommTimeouts(port->hdl, &port->timeouts) == 0)
|
||||
RETURN_FAIL("SetCommTimeouts() failed");
|
||||
}
|
||||
TRY(await_write_completion(port));
|
||||
|
||||
/* Start write. */
|
||||
if (WriteFile(port->hdl, buf, count, NULL, &port->write_ovl)) {
|
||||
DEBUG("Write completed immediately");
|
||||
RETURN_INT(count);
|
||||
} else if (GetLastError() == ERROR_IO_PENDING) {
|
||||
DEBUG("Waiting for write to complete");
|
||||
if (GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written, TRUE) == 0) {
|
||||
if (GetLastError() == ERROR_SEM_TIMEOUT) {
|
||||
DEBUG("Write timed out");
|
||||
RETURN_INT(0);
|
||||
} else {
|
||||
RETURN_FAIL("GetOverlappedResult() failed");
|
||||
}
|
||||
while (total_bytes_written < count) {
|
||||
|
||||
if (timeout_check(&timeout))
|
||||
break;
|
||||
|
||||
remaining_ms = timeout_remaining_ms(&timeout);
|
||||
|
||||
if (port->timeouts.WriteTotalTimeoutConstant != remaining_ms) {
|
||||
port->timeouts.WriteTotalTimeoutConstant = remaining_ms;
|
||||
if (SetCommTimeouts(port->hdl, &port->timeouts) == 0)
|
||||
RETURN_FAIL("SetCommTimeouts() failed");
|
||||
}
|
||||
DEBUG_FMT("Write completed, %d/%d bytes written", bytes_written, count);
|
||||
RETURN_INT(bytes_written);
|
||||
} else {
|
||||
RETURN_FAIL("WriteFile() failed");
|
||||
|
||||
/* Reduce write size if it exceeds the WriteFile limit. */
|
||||
remaining_bytes = count - total_bytes_written;
|
||||
if (remaining_bytes > WRITEFILE_MAX_SIZE)
|
||||
write_size = WRITEFILE_MAX_SIZE;
|
||||
else
|
||||
write_size = (DWORD) remaining_bytes;
|
||||
|
||||
/* Start write. */
|
||||
|
||||
result = WriteFile(port->hdl, write_ptr, write_size, NULL, &port->write_ovl);
|
||||
|
||||
timeout_update(&timeout);
|
||||
|
||||
if (result) {
|
||||
DEBUG("Write completed immediately");
|
||||
bytes_written = write_size;
|
||||
} else if (GetLastError() == ERROR_IO_PENDING) {
|
||||
DEBUG("Waiting for write to complete");
|
||||
if (GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written, TRUE) == 0) {
|
||||
if (GetLastError() == ERROR_SEM_TIMEOUT) {
|
||||
DEBUG("Write timed out");
|
||||
break;
|
||||
} else {
|
||||
RETURN_FAIL("GetOverlappedResult() failed");
|
||||
}
|
||||
}
|
||||
DEBUG_FMT("Write completed, %d/%d bytes written", bytes_written, write_size);
|
||||
} else {
|
||||
RETURN_FAIL("WriteFile() failed");
|
||||
}
|
||||
|
||||
write_ptr += bytes_written;
|
||||
total_bytes_written += bytes_written;
|
||||
}
|
||||
|
||||
RETURN_INT((int) total_bytes_written);
|
||||
#else
|
||||
size_t bytes_written = 0;
|
||||
unsigned char *ptr = (unsigned char *) buf;
|
||||
struct timeval start, delta, now, end = {0, 0};
|
||||
int started = 0;
|
||||
struct timeout timeout;
|
||||
fd_set fds;
|
||||
int result;
|
||||
|
||||
if (timeout_ms) {
|
||||
/* Get time at start of operation. */
|
||||
gettimeofday(&start, NULL);
|
||||
/* Define duration of timeout. */
|
||||
delta.tv_sec = timeout_ms / 1000;
|
||||
delta.tv_usec = (timeout_ms % 1000) * 1000;
|
||||
/* Calculate time at which we should give up. */
|
||||
timeradd(&start, &delta, &end);
|
||||
}
|
||||
timeout_start(&timeout, timeout_ms);
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(port->fd, &fds);
|
||||
|
||||
/* Loop until we have written the requested number of bytes. */
|
||||
while (bytes_written < count) {
|
||||
/*
|
||||
* Check timeout only if we have run select() at least once,
|
||||
* to avoid any issues if a short timeout is reached before
|
||||
* select() is even run.
|
||||
*/
|
||||
if (timeout_ms && started) {
|
||||
gettimeofday(&now, NULL);
|
||||
if (timercmp(&now, &end, >))
|
||||
/* Timeout has expired. */
|
||||
break;
|
||||
timersub(&end, &now, &delta);
|
||||
}
|
||||
result = select(port->fd + 1, NULL, &fds, NULL, timeout_ms ? &delta : NULL);
|
||||
started = 1;
|
||||
|
||||
if (timeout_check(&timeout))
|
||||
break;
|
||||
|
||||
result = select(port->fd + 1, NULL, &fds, NULL, timeout_timeval(&timeout));
|
||||
|
||||
timeout_update(&timeout);
|
||||
|
||||
if (result < 0) {
|
||||
if (errno == EINTR) {
|
||||
DEBUG("select() call was interrupted, repeating");
|
||||
@ -865,8 +954,7 @@ SP_API enum sp_return sp_nonblocking_write(struct sp_port *port,
|
||||
RETURN_INT(0);
|
||||
|
||||
#ifdef _WIN32
|
||||
DWORD written = 0;
|
||||
BYTE *ptr = (BYTE *) buf;
|
||||
size_t buf_bytes;
|
||||
|
||||
/* Check whether previous write is complete. */
|
||||
if (port->writing) {
|
||||
@ -887,48 +975,43 @@ SP_API enum sp_return sp_nonblocking_write(struct sp_port *port,
|
||||
RETURN_FAIL("SetCommTimeouts() failed");
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep writing data until the OS has to actually start an async IO
|
||||
* for it. At that point we know the buffer is full.
|
||||
*/
|
||||
while (written < count) {
|
||||
/* Copy first byte of user buffer. */
|
||||
port->pending_byte = *ptr++;
|
||||
/* Reduce count if it exceeds the WriteFile limit. */
|
||||
if (count > WRITEFILE_MAX_SIZE)
|
||||
count = WRITEFILE_MAX_SIZE;
|
||||
|
||||
/* Start asynchronous write. */
|
||||
if (WriteFile(port->hdl, &port->pending_byte, 1, NULL, &port->write_ovl) == 0) {
|
||||
if (GetLastError() == ERROR_IO_PENDING) {
|
||||
if (HasOverlappedIoCompleted(&port->write_ovl)) {
|
||||
DEBUG("Asynchronous write completed immediately");
|
||||
port->writing = 0;
|
||||
written++;
|
||||
continue;
|
||||
} else {
|
||||
DEBUG("Asynchronous write running");
|
||||
port->writing = 1;
|
||||
RETURN_INT(++written);
|
||||
}
|
||||
} else {
|
||||
/* Actual failure of some kind. */
|
||||
RETURN_FAIL("WriteFile() failed");
|
||||
}
|
||||
/* Copy data to our write buffer. */
|
||||
buf_bytes = min(port->write_buf_size, count);
|
||||
memcpy(port->write_buf, buf, buf_bytes);
|
||||
|
||||
/* Start asynchronous write. */
|
||||
if (WriteFile(port->hdl, port->write_buf, (DWORD) buf_bytes, NULL, &port->write_ovl) == 0) {
|
||||
if (GetLastError() == ERROR_IO_PENDING) {
|
||||
if ((port->writing = !HasOverlappedIoCompleted(&port->write_ovl)))
|
||||
DEBUG("Asynchronous write completed immediately");
|
||||
else
|
||||
DEBUG("Asynchronous write running");
|
||||
} else {
|
||||
DEBUG("Single byte written immediately");
|
||||
written++;
|
||||
/* Actual failure of some kind. */
|
||||
RETURN_FAIL("WriteFile() failed");
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG("All bytes written immediately");
|
||||
|
||||
RETURN_INT(written);
|
||||
RETURN_INT((int) buf_bytes);
|
||||
#else
|
||||
/* Returns the number of bytes written, or -1 upon failure. */
|
||||
ssize_t written = write(port->fd, buf, count);
|
||||
|
||||
if (written < 0)
|
||||
RETURN_FAIL("write() failed");
|
||||
else
|
||||
if (written < 0) {
|
||||
if (errno == EAGAIN)
|
||||
// Buffer is full, no bytes written.
|
||||
RETURN_INT(0);
|
||||
else
|
||||
RETURN_FAIL("write() failed");
|
||||
} else {
|
||||
RETURN_INT(written);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -973,7 +1056,7 @@ SP_API enum sp_return sp_blocking_read(struct sp_port *port, void *buf,
|
||||
RETURN_INT(0);
|
||||
|
||||
#ifdef _WIN32
|
||||
DWORD bytes_read = 0;
|
||||
DWORD bytes_read;
|
||||
|
||||
/* Set timeout. */
|
||||
if (port->timeouts.ReadIntervalTimeout != 0 ||
|
||||
@ -987,9 +1070,9 @@ SP_API enum sp_return sp_blocking_read(struct sp_port *port, void *buf,
|
||||
}
|
||||
|
||||
/* Start read. */
|
||||
if (ReadFile(port->hdl, buf, count, NULL, &port->read_ovl)) {
|
||||
if (ReadFile(port->hdl, buf, (DWORD) count, NULL, &port->read_ovl)) {
|
||||
DEBUG("Read completed immediately");
|
||||
bytes_read = count;
|
||||
bytes_read = (DWORD) count;
|
||||
} else if (GetLastError() == ERROR_IO_PENDING) {
|
||||
DEBUG("Waiting for read to complete");
|
||||
if (GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, TRUE) == 0)
|
||||
@ -1001,45 +1084,31 @@ SP_API enum sp_return sp_blocking_read(struct sp_port *port, void *buf,
|
||||
|
||||
TRY(restart_wait_if_needed(port, bytes_read));
|
||||
|
||||
RETURN_INT(bytes_read);
|
||||
RETURN_INT((int) bytes_read);
|
||||
|
||||
#else
|
||||
size_t bytes_read = 0;
|
||||
unsigned char *ptr = (unsigned char *) buf;
|
||||
struct timeval start, delta, now, end = {0, 0};
|
||||
int started = 0;
|
||||
struct timeout timeout;
|
||||
fd_set fds;
|
||||
int result;
|
||||
|
||||
if (timeout_ms) {
|
||||
/* Get time at start of operation. */
|
||||
gettimeofday(&start, NULL);
|
||||
/* Define duration of timeout. */
|
||||
delta.tv_sec = timeout_ms / 1000;
|
||||
delta.tv_usec = (timeout_ms % 1000) * 1000;
|
||||
/* Calculate time at which we should give up. */
|
||||
timeradd(&start, &delta, &end);
|
||||
}
|
||||
timeout_start(&timeout, timeout_ms);
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(port->fd, &fds);
|
||||
|
||||
/* Loop until we have the requested number of bytes. */
|
||||
while (bytes_read < count) {
|
||||
/*
|
||||
* Check timeout only if we have run select() at least once,
|
||||
* to avoid any issues if a short timeout is reached before
|
||||
* select() is even run.
|
||||
*/
|
||||
if (timeout_ms && started) {
|
||||
gettimeofday(&now, NULL);
|
||||
if (timercmp(&now, &end, >))
|
||||
/* Timeout has expired. */
|
||||
break;
|
||||
timersub(&end, &now, &delta);
|
||||
}
|
||||
result = select(port->fd + 1, &fds, NULL, NULL, timeout_ms ? &delta : NULL);
|
||||
started = 1;
|
||||
|
||||
if (timeout_check(&timeout))
|
||||
/* Timeout has expired. */
|
||||
break;
|
||||
|
||||
result = select(port->fd + 1, &fds, NULL, NULL, timeout_timeval(&timeout));
|
||||
|
||||
timeout_update(&timeout);
|
||||
|
||||
if (result < 0) {
|
||||
if (errno == EINTR) {
|
||||
DEBUG("select() call was interrupted, repeating");
|
||||
@ -1118,7 +1187,7 @@ SP_API enum sp_return sp_blocking_read_next(struct sp_port *port, void *buf,
|
||||
/* Loop until we have at least one byte, or timeout is reached. */
|
||||
while (bytes_read == 0) {
|
||||
/* Start read. */
|
||||
if (ReadFile(port->hdl, buf, count, &bytes_read, &port->read_ovl)) {
|
||||
if (ReadFile(port->hdl, buf, (DWORD) count, &bytes_read, &port->read_ovl)) {
|
||||
DEBUG("Read completed immediately");
|
||||
} else if (GetLastError() == ERROR_IO_PENDING) {
|
||||
DEBUG("Waiting for read to complete");
|
||||
@ -1143,40 +1212,26 @@ SP_API enum sp_return sp_blocking_read_next(struct sp_port *port, void *buf,
|
||||
|
||||
#else
|
||||
size_t bytes_read = 0;
|
||||
struct timeval start, delta, now, end = {0, 0};
|
||||
int started = 0;
|
||||
struct timeout timeout;
|
||||
fd_set fds;
|
||||
int result;
|
||||
|
||||
if (timeout_ms) {
|
||||
/* Get time at start of operation. */
|
||||
gettimeofday(&start, NULL);
|
||||
/* Define duration of timeout. */
|
||||
delta.tv_sec = timeout_ms / 1000;
|
||||
delta.tv_usec = (timeout_ms % 1000) * 1000;
|
||||
/* Calculate time at which we should give up. */
|
||||
timeradd(&start, &delta, &end);
|
||||
}
|
||||
timeout_start(&timeout, timeout_ms);
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(port->fd, &fds);
|
||||
|
||||
/* Loop until we have at least one byte, or timeout is reached. */
|
||||
while (bytes_read == 0) {
|
||||
/*
|
||||
* Check timeout only if we have run select() at least once,
|
||||
* to avoid any issues if a short timeout is reached before
|
||||
* select() is even run.
|
||||
*/
|
||||
if (timeout_ms && started) {
|
||||
gettimeofday(&now, NULL);
|
||||
if (timercmp(&now, &end, >))
|
||||
/* Timeout has expired. */
|
||||
break;
|
||||
timersub(&end, &now, &delta);
|
||||
}
|
||||
result = select(port->fd + 1, &fds, NULL, NULL, timeout_ms ? &delta : NULL);
|
||||
started = 1;
|
||||
|
||||
if (timeout_check(&timeout))
|
||||
/* Timeout has expired. */
|
||||
break;
|
||||
|
||||
result = select(port->fd + 1, &fds, NULL, NULL, timeout_timeval(&timeout));
|
||||
|
||||
timeout_update(&timeout);
|
||||
|
||||
if (result < 0) {
|
||||
if (errno == EINTR) {
|
||||
DEBUG("select() call was interrupted, repeating");
|
||||
@ -1238,7 +1293,7 @@ SP_API enum sp_return sp_nonblocking_read(struct sp_port *port, void *buf,
|
||||
}
|
||||
|
||||
/* Do read. */
|
||||
if (ReadFile(port->hdl, buf, count, NULL, &port->read_ovl) == 0)
|
||||
if (ReadFile(port->hdl, buf, (DWORD) count, NULL, &port->read_ovl) == 0)
|
||||
if (GetLastError() != ERROR_IO_PENDING)
|
||||
RETURN_FAIL("ReadFile() failed");
|
||||
|
||||
@ -1292,6 +1347,11 @@ SP_API enum sp_return sp_output_waiting(struct sp_port *port)
|
||||
{
|
||||
TRACE("%p", port);
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
/* TIOCOUTQ is not defined in Cygwin headers */
|
||||
RETURN_ERROR(SP_ERR_SUPP,
|
||||
"Getting output bytes waiting is not supported on Cygwin");
|
||||
#else
|
||||
CHECK_OPEN_PORT();
|
||||
|
||||
DEBUG_FMT("Checking output bytes waiting on port %s", port->name);
|
||||
@ -1309,6 +1369,7 @@ SP_API enum sp_return sp_output_waiting(struct sp_port *port)
|
||||
RETURN_FAIL("TIOCOUTQ ioctl failed");
|
||||
RETURN_INT(bytes_waiting);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
SP_API enum sp_return sp_new_event_set(struct sp_event_set **result_ptr)
|
||||
@ -1426,11 +1487,9 @@ SP_API enum sp_return sp_wait(struct sp_event_set *event_set,
|
||||
|
||||
RETURN_OK();
|
||||
#else
|
||||
struct timeval start, delta, now, end = {0, 0};
|
||||
const struct timeval max_delta = {
|
||||
(INT_MAX / 1000), (INT_MAX % 1000) * 1000};
|
||||
int started = 0, timeout_overflow = 0;
|
||||
int result, timeout_remaining_ms;
|
||||
struct timeout timeout;
|
||||
int poll_timeout;
|
||||
int result;
|
||||
struct pollfd *pollfds;
|
||||
unsigned int i;
|
||||
|
||||
@ -1438,7 +1497,7 @@ SP_API enum sp_return sp_wait(struct sp_event_set *event_set,
|
||||
RETURN_ERROR(SP_ERR_MEM, "pollfds malloc() failed");
|
||||
|
||||
for (i = 0; i < event_set->count; i++) {
|
||||
pollfds[i].fd = ((int *) event_set->handles)[i];
|
||||
pollfds[i].fd = ((int *)event_set->handles)[i];
|
||||
pollfds[i].events = 0;
|
||||
pollfds[i].revents = 0;
|
||||
if (event_set->masks[i] & SP_EVENT_RX_READY)
|
||||
@ -1449,42 +1508,24 @@ SP_API enum sp_return sp_wait(struct sp_event_set *event_set,
|
||||
pollfds[i].events |= POLLERR;
|
||||
}
|
||||
|
||||
if (timeout_ms) {
|
||||
/* Get time at start of operation. */
|
||||
gettimeofday(&start, NULL);
|
||||
/* Define duration of timeout. */
|
||||
delta.tv_sec = timeout_ms / 1000;
|
||||
delta.tv_usec = (timeout_ms % 1000) * 1000;
|
||||
/* Calculate time at which we should give up. */
|
||||
timeradd(&start, &delta, &end);
|
||||
}
|
||||
timeout_start(&timeout, timeout_ms);
|
||||
timeout_limit(&timeout, INT_MAX);
|
||||
|
||||
/* Loop until an event occurs. */
|
||||
while (1) {
|
||||
/*
|
||||
* Check timeout only if we have run poll() at least once,
|
||||
* to avoid any issues if a short timeout is reached before
|
||||
* poll() is even run.
|
||||
*/
|
||||
if (!timeout_ms) {
|
||||
timeout_remaining_ms = -1;
|
||||
} else if (!started) {
|
||||
timeout_overflow = (timeout_ms > INT_MAX);
|
||||
timeout_remaining_ms = timeout_overflow ? INT_MAX : timeout_ms;
|
||||
} else {
|
||||
gettimeofday(&now, NULL);
|
||||
if (timercmp(&now, &end, >)) {
|
||||
DEBUG("Wait timed out");
|
||||
break;
|
||||
}
|
||||
timersub(&end, &now, &delta);
|
||||
if ((timeout_overflow = timercmp(&delta, &max_delta, >)))
|
||||
delta = max_delta;
|
||||
timeout_remaining_ms = delta.tv_sec * 1000 + delta.tv_usec / 1000;
|
||||
|
||||
if (timeout_check(&timeout)) {
|
||||
DEBUG("Wait timed out");
|
||||
break;
|
||||
}
|
||||
|
||||
result = poll(pollfds, event_set->count, timeout_remaining_ms);
|
||||
started = 1;
|
||||
poll_timeout = (int) timeout_remaining_ms(&timeout);
|
||||
if (poll_timeout == 0)
|
||||
poll_timeout = -1;
|
||||
|
||||
result = poll(pollfds, event_set->count, poll_timeout);
|
||||
|
||||
timeout_update(&timeout);
|
||||
|
||||
if (result < 0) {
|
||||
if (errno == EINTR) {
|
||||
@ -1496,7 +1537,7 @@ SP_API enum sp_return sp_wait(struct sp_event_set *event_set,
|
||||
}
|
||||
} else if (result == 0) {
|
||||
DEBUG("poll() timed out");
|
||||
if (!timeout_overflow)
|
||||
if (!timeout.overflow)
|
||||
break;
|
||||
} else {
|
||||
DEBUG("poll() completed");
|
||||
@ -1647,28 +1688,25 @@ static enum sp_return get_config(struct sp_port *port, struct port_data *data,
|
||||
|
||||
config->bits = data->dcb.ByteSize;
|
||||
|
||||
if (data->dcb.fParity)
|
||||
switch (data->dcb.Parity) {
|
||||
case NOPARITY:
|
||||
config->parity = SP_PARITY_NONE;
|
||||
break;
|
||||
case ODDPARITY:
|
||||
config->parity = SP_PARITY_ODD;
|
||||
break;
|
||||
case EVENPARITY:
|
||||
config->parity = SP_PARITY_EVEN;
|
||||
break;
|
||||
case MARKPARITY:
|
||||
config->parity = SP_PARITY_MARK;
|
||||
break;
|
||||
case SPACEPARITY:
|
||||
config->parity = SP_PARITY_SPACE;
|
||||
break;
|
||||
default:
|
||||
config->parity = -1;
|
||||
}
|
||||
else
|
||||
switch (data->dcb.Parity) {
|
||||
case NOPARITY:
|
||||
config->parity = SP_PARITY_NONE;
|
||||
break;
|
||||
case ODDPARITY:
|
||||
config->parity = SP_PARITY_ODD;
|
||||
break;
|
||||
case EVENPARITY:
|
||||
config->parity = SP_PARITY_EVEN;
|
||||
break;
|
||||
case MARKPARITY:
|
||||
config->parity = SP_PARITY_MARK;
|
||||
break;
|
||||
case SPACEPARITY:
|
||||
config->parity = SP_PARITY_SPACE;
|
||||
break;
|
||||
default:
|
||||
config->parity = -1;
|
||||
}
|
||||
|
||||
switch (data->dcb.StopBits) {
|
||||
case ONESTOPBIT:
|
||||
@ -1848,6 +1886,10 @@ static enum sp_return set_config(struct sp_port *port, struct port_data *data,
|
||||
DEBUG_FMT("Setting configuration for port %s", port->name);
|
||||
|
||||
#ifdef _WIN32
|
||||
BYTE* new_buf;
|
||||
|
||||
TRY(await_write_completion(port));
|
||||
|
||||
if (config->baudrate >= 0) {
|
||||
for (i = 0; i < NUM_STD_BAUDRATES; i++) {
|
||||
if (config->baudrate == std_baudrates[i].value) {
|
||||
@ -1858,6 +1900,13 @@ static enum sp_return set_config(struct sp_port *port, struct port_data *data,
|
||||
|
||||
if (i == NUM_STD_BAUDRATES)
|
||||
data->dcb.BaudRate = config->baudrate;
|
||||
|
||||
/* Allocate write buffer for 50ms of data at baud rate. */
|
||||
port->write_buf_size = max(config->baudrate / (8 * 20), 1);
|
||||
new_buf = realloc(port->write_buf, port->write_buf_size);
|
||||
if (!new_buf)
|
||||
RETURN_ERROR(SP_ERR_MEM, "Allocating write buffer failed");
|
||||
port->write_buf = new_buf;
|
||||
}
|
||||
|
||||
if (config->bits >= 0)
|
||||
@ -2477,17 +2526,17 @@ SP_API char *sp_last_error_message(void)
|
||||
TRACE_VOID();
|
||||
|
||||
#ifdef _WIN32
|
||||
TCHAR *message;
|
||||
char *message;
|
||||
DWORD error = GetLastError();
|
||||
|
||||
DWORD length = FormatMessage(
|
||||
DWORD length = FormatMessageA(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
error,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR) &message,
|
||||
(LPSTR) &message,
|
||||
0, NULL );
|
||||
|
||||
if (length >= 2 && message[length - 2] == '\r')
|
||||
|
69
test_timing.c
Normal file
69
test_timing.c
Normal file
@ -0,0 +1,69 @@
|
||||
#include "config.h"
|
||||
#include "libserialport.h"
|
||||
#include "libserialport_internal.h"
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
struct time a, b, c;
|
||||
struct timeval tv;
|
||||
struct timeout to;
|
||||
|
||||
printf("Testing arithmetic\n");
|
||||
time_set_ms(&a, 10050);
|
||||
time_set_ms(&b, 100);
|
||||
assert(time_greater(&a, &b));
|
||||
assert(!time_greater(&b, &a));
|
||||
time_add(&a, &b, &c);
|
||||
assert(time_as_ms(&c) == 10150);
|
||||
time_sub(&a, &b, &c);
|
||||
assert(time_as_ms(&c) == 9950);
|
||||
time_as_timeval(&a, &tv);
|
||||
assert(tv.tv_sec == 10);
|
||||
assert(tv.tv_usec == 50000);
|
||||
time_get(&a);
|
||||
printf("Sleeping for 1s\n");
|
||||
sleep(1);
|
||||
time_get(&b);
|
||||
time_sub(&b, &a, &c);
|
||||
printf("Measured: %ums\n", time_as_ms(&c));
|
||||
assert(time_as_ms(&c) >= 950);
|
||||
assert(time_as_ms(&c) <= 1050);
|
||||
printf("Starting 3s timeout\n");
|
||||
timeout_start(&to, 3000);
|
||||
printf("Time to wait: %dms\n", timeout_remaining_ms(&to));
|
||||
printf("Sleeping for 1s\n");
|
||||
sleep(1);
|
||||
timeout_update(&to);
|
||||
assert(!timeout_check(&to));
|
||||
printf("Sleeping for 1s\n");
|
||||
sleep(1);
|
||||
timeout_update(&to);
|
||||
assert(!timeout_check(&to));
|
||||
printf("Remaining: %ums\n", timeout_remaining_ms(&to));
|
||||
printf("Sleeping for 1s\n");
|
||||
sleep(1);
|
||||
timeout_update(&to);
|
||||
assert(timeout_check(&to));
|
||||
printf("Timeout expired\n");
|
||||
printf("Starting 2s timeout\n");
|
||||
timeout_start(&to, 2000);
|
||||
printf("Limiting steps to 1s\n");
|
||||
timeout_limit(&to, 1000);
|
||||
printf("Time to wait: %ums\n", timeout_remaining_ms(&to));
|
||||
printf("Sleeping for 1s\n");
|
||||
sleep(1);
|
||||
timeout_update(&to);
|
||||
assert(!timeout_check(&to));
|
||||
printf("Remaining: %ums\n", timeout_remaining_ms(&to));
|
||||
printf("Sleeping for 1s\n");
|
||||
sleep(1);
|
||||
timeout_update(&to);
|
||||
assert(timeout_check(&to));
|
||||
printf("Timeout expired\n");
|
||||
|
||||
return 0;
|
||||
}
|
174
timing.c
Normal file
174
timing.c
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* This file is part of the libserialport project.
|
||||
*
|
||||
* Copyright (C) 2019 Martin Ling <martin-libserialport@earth.li>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "libserialport_internal.h"
|
||||
|
||||
SP_PRIV void time_get(struct time *time)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER count;
|
||||
QueryPerformanceCounter(&count);
|
||||
time->ticks = count.QuadPart;
|
||||
#elif defined(HAVE_CLOCK_GETTIME)
|
||||
struct timespec ts;
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
time->tv.tv_sec = ts.tv_sec;
|
||||
time->tv.tv_usec = ts.tv_nsec / 1000;
|
||||
#elif defined(__APPLE__)
|
||||
mach_timebase_info_data_t info;
|
||||
mach_timebase_info(&info);
|
||||
uint64_t ticks = mach_absolute_time();
|
||||
uint64_t ns = (ticks * info.numer) / info.denom;
|
||||
time->tv.tv_sec = ns / 1000000000;
|
||||
time->tv.tv_usec = (ns % 1000000000) / 1000;
|
||||
#else
|
||||
gettimeofday(&time->tv, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
SP_PRIV void time_set_ms(struct time *time, unsigned int ms)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER frequency;
|
||||
QueryPerformanceFrequency(&frequency);
|
||||
time->ticks = ms * (frequency.QuadPart / 1000);
|
||||
#else
|
||||
time->tv.tv_sec = ms / 1000;
|
||||
time->tv.tv_usec = (ms % 1000) * 1000;
|
||||
#endif
|
||||
}
|
||||
|
||||
SP_PRIV void time_add(const struct time *a,
|
||||
const struct time *b, struct time *result)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
result->ticks = a->ticks + b->ticks;
|
||||
#else
|
||||
timeradd(&a->tv, &b->tv, &result->tv);
|
||||
#endif
|
||||
}
|
||||
|
||||
SP_PRIV void time_sub(const struct time *a,
|
||||
const struct time *b, struct time *result)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
result->ticks = a->ticks - b->ticks;
|
||||
#else
|
||||
timersub(&a->tv, &b->tv, &result->tv);
|
||||
#endif
|
||||
}
|
||||
|
||||
SP_PRIV bool time_greater(const struct time *a, const struct time *b)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return (a->ticks > b->ticks);
|
||||
#else
|
||||
return timercmp(&a->tv, &b->tv, >);
|
||||
#endif
|
||||
}
|
||||
|
||||
SP_PRIV void time_as_timeval(const struct time *time, struct timeval *tv)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER frequency;
|
||||
QueryPerformanceFrequency(&frequency);
|
||||
tv->tv_sec = (long) (time->ticks / frequency.QuadPart);
|
||||
tv->tv_usec = (long) ((time->ticks % frequency.QuadPart) /
|
||||
(frequency.QuadPart / 1000000));
|
||||
#else
|
||||
*tv = time->tv;
|
||||
#endif
|
||||
}
|
||||
|
||||
SP_PRIV unsigned int time_as_ms(const struct time *time)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER frequency;
|
||||
QueryPerformanceFrequency(&frequency);
|
||||
return (unsigned int) (time->ticks / (frequency.QuadPart / 1000));
|
||||
#else
|
||||
return time->tv.tv_sec * 1000 + time->tv.tv_usec / 1000;
|
||||
#endif
|
||||
}
|
||||
|
||||
SP_PRIV void timeout_start(struct timeout *timeout, unsigned int timeout_ms)
|
||||
{
|
||||
timeout->ms = timeout_ms;
|
||||
|
||||
/* Get time at start of operation. */
|
||||
time_get(&timeout->start);
|
||||
/* Define duration of timeout. */
|
||||
time_set_ms(&timeout->delta, timeout_ms);
|
||||
/* Calculate time at which we should give up. */
|
||||
time_add(&timeout->start, &timeout->delta, &timeout->end);
|
||||
/* Disable limit unless timeout_limit() called. */
|
||||
timeout->limit_ms = 0;
|
||||
/* First blocking call has not yet been made. */
|
||||
timeout->calls_started = false;
|
||||
}
|
||||
|
||||
SP_PRIV void timeout_limit(struct timeout *timeout, unsigned int limit_ms)
|
||||
{
|
||||
timeout->limit_ms = limit_ms;
|
||||
timeout->overflow = (timeout->ms > timeout->limit_ms);
|
||||
time_set_ms(&timeout->delta_max, timeout->limit_ms);
|
||||
}
|
||||
|
||||
SP_PRIV bool timeout_check(struct timeout *timeout)
|
||||
{
|
||||
if (!timeout->calls_started)
|
||||
return false;
|
||||
|
||||
if (timeout->ms == 0)
|
||||
return false;
|
||||
|
||||
time_get(&timeout->now);
|
||||
time_sub(&timeout->end, &timeout->now, &timeout->delta);
|
||||
if (timeout->limit_ms)
|
||||
if ((timeout->overflow = time_greater(&timeout->delta, &timeout->delta_max)))
|
||||
timeout->delta = timeout->delta_max;
|
||||
|
||||
return time_greater(&timeout->now, &timeout->end);
|
||||
}
|
||||
|
||||
SP_PRIV void timeout_update(struct timeout *timeout)
|
||||
{
|
||||
timeout->calls_started = true;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
SP_PRIV struct timeval *timeout_timeval(struct timeout *timeout)
|
||||
{
|
||||
if (timeout->ms == 0)
|
||||
return NULL;
|
||||
|
||||
time_as_timeval(&timeout->delta, &timeout->delta_tv);
|
||||
|
||||
return &timeout->delta_tv;
|
||||
}
|
||||
#endif
|
||||
|
||||
SP_PRIV unsigned int timeout_remaining_ms(struct timeout *timeout)
|
||||
{
|
||||
if (timeout->limit_ms && timeout->overflow)
|
||||
return timeout->limit_ms;
|
||||
else
|
||||
return time_as_ms(&timeout->delta);
|
||||
}
|
74
windows.c
74
windows.c
@ -18,8 +18,6 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "libserialport.h"
|
||||
#include "libserialport_internal.h"
|
||||
|
||||
/* USB path is a string of at most 8 decimal numbers < 128 separated by dots. */
|
||||
@ -28,31 +26,42 @@
|
||||
static void enumerate_hub(struct sp_port *port, const char *hub_name,
|
||||
const char *parent_path, DEVINST dev_inst);
|
||||
|
||||
static char *wc_to_utf8(PWCHAR wc_buffer, ULONG size)
|
||||
static char *wc_to_utf8(PWCHAR wc_buffer, ULONG wc_bytes)
|
||||
{
|
||||
WCHAR wc_str[(size / sizeof(WCHAR)) + 1];
|
||||
char *utf8_str;
|
||||
ULONG wc_length = wc_bytes / sizeof(WCHAR);
|
||||
ULONG utf8_bytes;
|
||||
WCHAR *wc_str = NULL;
|
||||
char *utf8_str = NULL;
|
||||
|
||||
/* Allocate aligned wide char buffer */
|
||||
if (!(wc_str = malloc((wc_length + 1) * sizeof(WCHAR))))
|
||||
goto wc_to_utf8_end;
|
||||
|
||||
/* Zero-terminate the wide char string. */
|
||||
memcpy(wc_str, wc_buffer, size);
|
||||
wc_str[sizeof(wc_str) - 1] = 0;
|
||||
memcpy(wc_str, wc_buffer, wc_bytes);
|
||||
wc_str[wc_length] = 0;
|
||||
|
||||
/* Compute the size of the UTF-8 converted string. */
|
||||
if (!(size = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, wc_str, -1,
|
||||
if (!(utf8_bytes = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, wc_str, -1,
|
||||
NULL, 0, NULL, NULL)))
|
||||
return NULL;
|
||||
goto wc_to_utf8_end;
|
||||
|
||||
/* Allocate UTF-8 output buffer. */
|
||||
if (!(utf8_str = malloc(size)))
|
||||
return NULL;
|
||||
if (!(utf8_str = malloc(utf8_bytes)))
|
||||
goto wc_to_utf8_end;
|
||||
|
||||
/* Actually converted to UTF-8. */
|
||||
if (!WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, wc_str, -1,
|
||||
utf8_str, size, NULL, NULL)) {
|
||||
utf8_str, utf8_bytes, NULL, NULL)) {
|
||||
free(utf8_str);
|
||||
return NULL;
|
||||
utf8_str = NULL;
|
||||
goto wc_to_utf8_end;
|
||||
}
|
||||
|
||||
wc_to_utf8_end:
|
||||
if (wc_str)
|
||||
free(wc_str);
|
||||
|
||||
return utf8_str;
|
||||
}
|
||||
|
||||
@ -81,7 +90,7 @@ static char *get_root_hub_name(HANDLE host_controller)
|
||||
}
|
||||
|
||||
/* Convert the root hub name string to UTF-8. */
|
||||
root_hub_name_utf8 = wc_to_utf8(root_hub_name_wc->RootHubName, size);
|
||||
root_hub_name_utf8 = wc_to_utf8(root_hub_name_wc->RootHubName, size - offsetof(USB_ROOT_HUB_NAME, RootHubName));
|
||||
free(root_hub_name_wc);
|
||||
return root_hub_name_utf8;
|
||||
}
|
||||
@ -116,7 +125,7 @@ static char *get_external_hub_name(HANDLE hub, ULONG connection_index)
|
||||
}
|
||||
|
||||
/* Convert the external hub name string to UTF-8. */
|
||||
ext_hub_name_utf8 = wc_to_utf8(ext_hub_name_wc->NodeName, size);
|
||||
ext_hub_name_utf8 = wc_to_utf8(ext_hub_name_wc->NodeName, size - offsetof(USB_NODE_CONNECTION_NAME, NodeName));
|
||||
free(ext_hub_name_wc);
|
||||
return ext_hub_name_utf8;
|
||||
}
|
||||
@ -134,7 +143,7 @@ static char *get_string_descriptor(HANDLE hub_device, ULONG connection_index,
|
||||
desc_req->SetupPacket.wValue = (USB_STRING_DESCRIPTOR_TYPE << 8)
|
||||
| descriptor_index;
|
||||
desc_req->SetupPacket.wIndex = 0;
|
||||
desc_req->SetupPacket.wLength = size - sizeof(*desc_req);
|
||||
desc_req->SetupPacket.wLength = (USHORT) (size - sizeof(*desc_req));
|
||||
|
||||
if (!DeviceIoControl(hub_device,
|
||||
IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,
|
||||
@ -145,7 +154,7 @@ static char *get_string_descriptor(HANDLE hub_device, ULONG connection_index,
|
||||
|| desc->bLength % 2)
|
||||
return NULL;
|
||||
|
||||
return wc_to_utf8(desc->bString, desc->bLength);
|
||||
return wc_to_utf8(desc->bString, desc->bLength - offsetof(USB_STRING_DESCRIPTOR, bString));
|
||||
}
|
||||
|
||||
static void enumerate_hub_ports(struct sp_port *port, HANDLE hub_device,
|
||||
@ -219,7 +228,7 @@ static void enumerate_hub_ports(struct sp_port *port, HANDLE hub_device,
|
||||
port->usb_pid = connection_info_ex->DeviceDescriptor.idProduct;
|
||||
|
||||
if (connection_info_ex->DeviceDescriptor.iManufacturer)
|
||||
port->usb_manufacturer = get_string_descriptor(hub_device,index,
|
||||
port->usb_manufacturer = get_string_descriptor(hub_device, index,
|
||||
connection_info_ex->DeviceDescriptor.iManufacturer);
|
||||
if (connection_info_ex->DeviceDescriptor.iProduct)
|
||||
port->usb_product = get_string_descriptor(hub_device, index,
|
||||
@ -256,8 +265,8 @@ static void enumerate_hub(struct sp_port *port, const char *hub_name,
|
||||
return;
|
||||
strcpy(device_name, "\\\\.\\");
|
||||
strcat(device_name, hub_name);
|
||||
hub_device = CreateFile(device_name, GENERIC_WRITE, FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
hub_device = CreateFileA(device_name, GENERIC_WRITE, FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
free(device_name);
|
||||
if (hub_device == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
@ -380,7 +389,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
||||
continue;
|
||||
}
|
||||
RegCloseKey(device_key);
|
||||
value[sizeof(value)-1] = 0;
|
||||
value[sizeof(value) - 1] = 0;
|
||||
if (strcmp(value, port->name))
|
||||
continue;
|
||||
|
||||
@ -458,9 +467,9 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
||||
if (!(escaped_port_name = malloc(strlen(port->name) + 5)))
|
||||
RETURN_ERROR(SP_ERR_MEM, "Escaped port name malloc failed");
|
||||
sprintf(escaped_port_name, "\\\\.\\%s", port->name);
|
||||
handle = CreateFile(escaped_port_name, GENERIC_READ, 0, 0,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, 0);
|
||||
handle = CreateFileA(escaped_port_name, GENERIC_READ, 0, 0,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, 0);
|
||||
free(escaped_port_name);
|
||||
CloseHandle(handle);
|
||||
|
||||
@ -482,19 +491,26 @@ SP_PRIV enum sp_return list_ports(struct sp_port ***list)
|
||||
DWORD max_value_len, max_data_size, max_data_len;
|
||||
DWORD value_len, data_size, data_len;
|
||||
DWORD type, index = 0;
|
||||
LSTATUS result;
|
||||
char *name;
|
||||
int name_len;
|
||||
int ret = SP_OK;
|
||||
|
||||
DEBUG("Opening registry key");
|
||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"),
|
||||
0, KEY_QUERY_VALUE, &key) != ERROR_SUCCESS) {
|
||||
SET_FAIL(ret, "RegOpenKeyEx() failed");
|
||||
if ((result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"),
|
||||
0, KEY_QUERY_VALUE, &key)) != ERROR_SUCCESS) {
|
||||
/* It's possible for this key to not exist if there are no serial ports
|
||||
* at all. In that case we're done. Return a failure for any other error. */
|
||||
if (result != ERROR_FILE_NOT_FOUND) {
|
||||
SetLastError(result);
|
||||
SET_FAIL(ret, "RegOpenKeyEx() failed");
|
||||
}
|
||||
goto out_done;
|
||||
}
|
||||
DEBUG("Querying registry key value and data sizes");
|
||||
if (RegQueryInfoKey(key, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
&max_value_len, &max_data_size, NULL, NULL) != ERROR_SUCCESS) {
|
||||
if ((result = RegQueryInfoKey(key, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
&max_value_len, &max_data_size, NULL, NULL)) != ERROR_SUCCESS) {
|
||||
SetLastError(result);
|
||||
SET_FAIL(ret, "RegQueryInfoKey() failed");
|
||||
goto out_close;
|
||||
}
|
||||
|
Reference in New Issue
Block a user