cake
/
libp7
Archived
1
0
Fork 1

Modified way streams are managed.

This commit is contained in:
Thomas Touhey 2017-02-07 17:54:11 +01:00
parent f78732a262
commit 6441afaf9a
12 changed files with 242 additions and 279 deletions

View File

@ -5,7 +5,7 @@ platform's libc, such as endianness correcting or sleeping, in the internal
headers located in `include/libp7/internals/`, and make a custom stream adapted
for your platform and prototype it.
Libp7 streams are the libp7 abstraction between it and the calculator device.
libp7 streams are the libp7 abstraction between it and the calculator device.
You can check out the current streams in `src/stream/`. Currently supported
streams are libc FILEs, Unix-like streams (with file descriptors), Microsoft
Windows's libc streams (`HANDLE`s) and libusb streams (which can be disabled
@ -13,10 +13,13 @@ by passing `--no-libusb` to the configure script). Each stream must implement
a function to connect to the device using `p7_sinit`, and functions to read
and write, and eventually one to set communication settings from cross-platform
values defined by libp7. You should really check out `p7_sinit`'s manpage.
A placebo function is advised.
You should as well make up a constant like `P7_DISABLED_<your type of stream>`
(e.g. `P7_DISABLED_LIBUSB`, `P7_DISABLED_STREAMS`, `P7_DISABLED_WINDOWS`),
and define it in `libp7/stream.h` aside with the prototypes of your functions.
Once this is done, you will want to hook your stream to one of the libp7
standard initialization functions: `p7_init` or `p7_cominit`. In order to do
this, you should add your initialization function's prototype in
`include/libp7/internals.h` near the others, and add it to one of the functions'
content (see what's already there).
this, you should add it your functions to the content of at least one of these
two functions. Platform-specific things are preferred in your stream's source
file.

View File

@ -9,60 +9,22 @@
/* ************************************************************************** */
#ifndef LIBP7_H
# define LIBP7_H
# if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) \
&& !defined(__WINDOWS__)
# define __WINDOWS__
# endif
# include <libp7/config.h>
# include <libp7/types.h>
# include <stdio.h>
# include <stdint.h>
/* integer types */
# define PRIuP7SHORT PRIuFAST16
# define PRIxP7SHORT PRIxFAST16
typedef uint_fast16_t p7ushort_t;
# define PRIuP7INT PRIuFAST32
# define PRIxP7INT PRIxFAST32
typedef uint_fast32_t p7uint_t;
# include <libp7/buffer.h>
# include <inttypes.h> /* PRI*FAST* */
/* allocate handle in stack */
# ifdef __WINDOWS__
# include <malloc.h>
# else
# include <alloca.h>
# endif
# define p7_alloca_handle() (alloca(p7_handle_size))
# ifdef __cplusplus
extern "C" {
# endif
/* ************************************************************************** */
/* Types */
/* ************************************************************************** */
/* handles - from streams, include `libp7/stream.h` */
struct p7_handle_s;
typedef struct p7_handle_s p7_handle_t;
extern const size_t p7_handle_size;
# define p7_alloca_handle() (alloca(p7_handle_size))
/* A version ("xx.xx.xx" + type) */
typedef struct {
unsigned int major;
unsigned int minor;
unsigned int rev;
} p7_version_t;
/* CASIOWIN entry */
typedef struct {
/* version */
p7_version_t version;
/* syscall table address */
p7uint_t syscall_table_offset;
} p7_casiowin_entry_t;
/* ************************************************************************** */
/* libp7 errors */
/* ************************************************************************** */
@ -130,14 +92,6 @@ int p7_validate_dirname(const char *dirname);
int p7_init(p7_handle_t **handle, unsigned int flags);
int p7_cominit(p7_handle_t **handle, unsigned int flags, int com);
/* Testing initialization */
# ifndef P7_DISABLED_FILE
int p7_finit(p7_handle_t **handle, unsigned int flags,
FILE *readstream, FILE *writestream);
# endif
int p7_fdinit(p7_handle_t **handle, unsigned int flags,
const char *name, int readfd, int writefd);
/* De-initialization */
void p7_exit(p7_handle_t *handle);
/* ************************************************************************** */

View File

@ -9,6 +9,7 @@
/* ************************************************************************** */
#ifndef LIBP7_BUFFER_H
# define LIBP7_BUFFER_H
# include <libp7/types.h>
/* This file is there so it is possible to use a custom buffer for file
* transferring. There are two use cases:

View File

@ -16,24 +16,6 @@
# include <libp7/internals/endian.h>
# define DEFAULT_BAUDRATE P7_B9600
/* ************************************************************************** */
/* Macros and platform-specific functions */
/* ************************************************************************** */
/* MS-Windows <3 (srsly) */
# if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) \
&& !defined(__WINDOWS__)
# define __WINDOWS__
# endif
/* Some printf types */
# if defined(_WIN64)
# define PRIuSIZE "l64u"
# elif defined(_WIN32)
# define PRIuSIZE "u"
# else
# define PRIuSIZE "zu"
# endif
/* Macros */
# ifndef min
# define min(A, B) ((A) < (B) ? (A) : (B))
@ -148,11 +130,6 @@ struct p7_handle_s {
char _name[10];
};
/* Sub-initialization functions */
int p7_libusbinit(p7_handle_t **handle, unsigned int flags);
int p7_winit(p7_handle_t **handle, unsigned int flags, const char *path);
int p7_cinit(p7_handle_t **handle, unsigned int flags, const char *path);
/* sub-sub-init utils */
# ifndef P7_DISABLED_FILE
int _p7_finit(p7_handle_t **handle, unsigned int flags,

View File

@ -9,7 +9,7 @@
/* ************************************************************************** */
#ifndef LIBP7_PACKETIO_H
# define LIBP7_PACKETIO_H
# include <libp7.h>
# include <libp7/types.h>
# include <libp7/stream.h> /* for P7_B* */
# ifdef __cplusplus
extern "C" {

View File

@ -9,7 +9,7 @@
/* ************************************************************************** */
#ifndef LIBP7_STREAM_H
# define LIBP7_STREAM_H
# include <libp7.h>
# include <libp7/types.h>
# ifdef __cplusplus
extern "C" {
# endif
@ -24,7 +24,7 @@ extern "C" {
* These functions take the uncasted cookie and the required arguments for
* the actions (`timeout` is in milliseconds). They should return the libp7
* error code, or 0 if no error. There is no partial success: you manage to
* send the full buffer, or you do not.
* receive/send the full buffer, or you do not.
*
* some of the streams managed by default already have buffering, so this
* implementation doesn't add another layer of it.
@ -66,6 +66,46 @@ int p7_read(p7_stream_t *stream, void *dest, size_t size, unsigned int timeout);
int p7_write(p7_stream_t *stream, const void *data, size_t size);
int p7_setcomm(p7_stream_t *stream, int speed, int parity, int stopbits);
/* ************************************************************************** */
/* Built-in streams */
/* ************************************************************************** */
/* FILE stream */
# ifndef P7_DISABLED_FILE
int p7_finit(p7_handle_t **handle, unsigned int flags,
FILE *readstream, FILE *writestream);
# endif
/* STREAMS device */
# if defined(__linux__)
int p7_fdinit(p7_handle_t **handle, unsigned int flags,
const char *name, int readfd, int writefd);
int p7_fdcominit(p7_handle_t **handle, unsigned int flags, int com);
# else
# define P7_DISABLED_STREAMS
# endif
/* libusb initialization */
# ifndef P7_DISABLED_LIBUSB
int p7_libusbinit(p7_handle_t **handle, unsigned int flags);
# endif
/* Microsoft Windows initialization */
# ifdef __WINDOWS__
int p7_winit(p7_handle_t **handle, unsigned int flags, const char *path);
int p7_wcominit(p7_handle_t **handle, unsigned int flags, int com);
# else
# define P7_DISABLED_WINDOWS
# endif
/* Check if there is serial/usb on this platform */
# if defined(P7_DISABLED_STREAMS) && defined(P7_DISABLED_WINDOWS)
# define P7_NOSERIAL
# endif
# if defined(P7_DISABLED_LIBUSB) && defined(P7_DISABLED_STREAMS) \
&& defined(P7_DISABLED_WINDOWS)
# define P7_NOUSB
# endif
# ifdef __cplusplus
}
# endif

77
include/libp7/types.h Normal file
View File

@ -0,0 +1,77 @@
/* ************************************************************************** */
/* _____ _ */
/* libp7/types.h |_ _|__ _ _| |__ ___ _ _ */
/* | Project: libp7 | |/ _ \| | | | '_ \ / _ \ | | | */
/* | | (_) | |_| | | | | __/ |_| | */
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
/* Last updated: 2017/02/07 16:52:51 |___/ */
/* */
/* ************************************************************************** */
#ifndef LIBP7_TYPES_H
# define LIBP7_TYPES_H
# if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) \
&& !defined(__WINDOWS__)
# define __WINDOWS__
# endif
/* Main includes */
# include <stdlib.h>
# include <stdint.h>
# include <inttypes.h>
# ifdef __cplusplus
extern "C" {
# endif
/* ************************************************************************** */
/* Integer types */
/* ************************************************************************** */
/* integer types */
# define PRIuP7SHORT PRIuFAST16
# define PRIxP7SHORT PRIxFAST16
typedef uint_fast16_t p7ushort_t;
# define PRIuP7INT PRIuFAST32
# define PRIxP7INT PRIxFAST32
typedef uint_fast32_t p7uint_t;
/* Size_t-related printf format */
# ifndef PRIuSIZE
# if defined(_WIN64)
# define PRIuSIZE "l64u"
# elif defined(_WIN32)
# define PRIuSIZE "u"
# else
# define PRIuSIZE "zu"
# endif
# endif
/* ************************************************************************** */
/* Handles - these are actually private */
/* ************************************************************************** */
struct p7_handle_s;
typedef struct p7_handle_s p7_handle_t;
extern const size_t p7_handle_size;
/* ************************************************************************** */
/* Other types */
/* ************************************************************************** */
/* Version (xx.xx.xxxx) */
typedef struct {
unsigned int major;
unsigned int minor;
unsigned int rev;
} p7_version_t;
/* CASIOWIN entry - the OS entry the bootcode reads to run it */
typedef struct {
/* version */
p7_version_t version;
/* syscall table address */
p7uint_t syscall_table_offset;
} p7_casiowin_entry_t;
# ifdef __cplusplus
}
# endif
# include <libp7/buffer.h>
#endif /* LIBP7_TYPES_H */

View File

@ -22,6 +22,12 @@
int p7_init(p7_handle_t **handle, unsigned int flags)
{
#ifdef P7_NOUSB
(void)handle;
(void)flags;
return (p7_error_nocalc);
#else
int err = p7_error_nocalc;
int tries = INIT_TRIES;
int failed = 0;
@ -33,23 +39,22 @@ int p7_init(p7_handle_t **handle, unsigned int flags)
}
/* platform-specific communication methods */
#if defined(__linux__)
logr_info("Looking for specific Linux drivers");
err = p7_cinit(handle, flags, NULL);
#elif defined(__WINDOWS__)
logr_info("Looking for specific MS-Windows drivers");
# if !defined(P7_DISABLED_STREAMS)
err = p7_fdinit(handle, flags, NULL, -1, -1);
# elif !defined(P7_DISABLED_WINDOWS)
err = p7_winit(handle, flags, NULL);
#endif
# endif
/* check error */
if (err != p7_error_nocalc)
return (err);
/* libusb communication methods - more or less platform-independent */
# if !defined(P7_DISABLED_LIBUSB)
logr_info("Looking for general libusb devices");
err = p7_libusbinit(handle, flags);
if (err != p7_error_nocalc)
return (err);
# endif
/* wait a little */
logr_error("didn't find the calculator!");
@ -58,6 +63,7 @@ int p7_init(p7_handle_t **handle, unsigned int flags)
/* no found calc, by the look of it. */
return (p7_error_nocalc);
#endif
}
/**
@ -72,7 +78,7 @@ int p7_init(p7_handle_t **handle, unsigned int flags)
int p7_cominit(p7_handle_t **handle, unsigned int flags, int com)
{
#if !defined(__linux__) && !defined(__WINDOWS__)
#ifdef P7_NOSERIAL
(void)handle;
(void)active;
(void)check;
@ -93,17 +99,10 @@ int p7_cominit(p7_handle_t **handle, unsigned int flags, int com)
}
/* platform-specific communication methods */
# if defined(__linux__)
logr_info("Looking for specific Linux device");
char compath[20];
sprintf(compath, "/dev/ttyUSB%d", com - 1);
err = p7_cinit(handle, flags, compath);
# elif defined(__WINDOWS__)
logr_info("Looking for specific MS-Windows device");
char compath[20];
if (com <= 9) sprintf(compath, "COM%d", com);
else sprintf(compath, "\\\\?\\COM%d", com);
err = p7_winit(handle, flags, compath);
# if !defined(P7_DISABLED_STREAMS)
err = p7_fdcominit(handle, flags, com);
# elif !defined(P7_DISABLED_WINDOWS)
err = p7_wcominit(handle, flags, com);
# endif
/* check error */

View File

@ -8,10 +8,11 @@
/* */
/* ************************************************************************** */
#include <libp7/internals.h>
#include <stdlib.h>
#include <string.h>
#ifndef P7_DISABLED_LIBUSB
# include <libusb.h>
# include <stdlib.h>
# include <string.h>
/* ************************************************************************** */
/* Cookie structure */
/* ************************************************************************** */
@ -291,25 +292,4 @@ fail:
return (err);
}
/* ************************************************************************** */
/* Without libusb: placebos */
/* ************************************************************************** */
#else
/**
* p7_libusbinit:
* Initialize libp7 with USB device [not] using libusb. Placebo.
*
* @arg handle the handle to create.
* @arg flags the flags.
* @return the error code (0 if you're a knoop).
*/
int p7_libusbinit(p7_handle_t **handle, unsigned int flags)
{
(void)handle;
(void)flags;
return (p7_error_nocalc);
}
#endif

View File

@ -8,19 +8,70 @@
/* */
/* ************************************************************************** */
#include <libp7/internals.h>
#include <string.h>
#ifndef P7_DISABLED_STREAMS
# include <stdlib.h>
# include <string.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <termios.h>
# include <unistd.h>
# include <errno.h>
# ifdef __linux__
/* ************************************************************************** */
/* Serial devices on Linux */
/* ************************************************************************** */
/**
* p7_fdcominit:
* Initialize serial communication.
*
* @arg handle the link to the handle.
* @arg flags the flags.
* @arg com the com port.
* @return the error code (0 if ok)
*/
int p7_fdcominit(p7_handle_t **handle, unsigned int flags, int com)
{
/* prepare the path */
logr_info("Looking for specific Linux devices.");
char path[20]; sprintf(path, "/dev/ttyUSB%d", com - 1);
/* open the stream */
int fd = open(path, O_RDWR | O_NOCTTY);
if (fd < 0) switch (errno) {
/* no such device */
case ENODEV: case ENOENT: case ENXIO:
case EPIPE: case ESPIPE:
logr_error("couldn't open calculator");
return (p7_error_nocalc);
/* no access */
case EACCES:
logr_error("permission denied");
return (p7_error_noaccess);
/* default */
default:
logr_error("unknown error: %s (0x%X)", strerror(errno), errno);
return (p7_error_unknown);
}
/* check if we have got the thing */
if (fd < 0) switch (errno) {
case ENOENT: return (p7_error_nocalc);
case EACCES: return (p7_error_noaccess);
default: return (p7_error_nocalc);
}
/* init to real */
return (p7_fdinit(handle, flags, NULL, fd, fd));
}
# endif
/* ************************************************************************** */
/* *nix streams device initialization and callbacks */
/* ************************************************************************** */
#ifdef __linux__
# include <errno.h>
# include <stdlib.h>
# include <termios.h>
# include <unistd.h>
# include <fcntl.h>
# include <sys/stat.h>
/* the cookie */
# define BUFSIZE 2048
typedef struct {
@ -279,31 +330,4 @@ test_failed:
return (err);
}
/* ************************************************************************** */
/* Use a file descriptor on other systems (placebo) */
/* ************************************************************************** */
#else
/**
* p7_fdinit:
* Initialize libp7 with a file descriptor. Placebo.
*
* @arg handle the handle to create
* @arg flags the flags.
* @arg name the name of the handle.
* @arg readfd the read file descriptor.
* @arg writefd the write file descriptor.
* @return the error (0 if ok)
*/
int p7_fdinit(p7_handle_t **handle, unsigned int flags,
const char *name, int readfd, int writefd)
{
(void)handle;
(void)flags;
(void)name;
(void)readfd;
(void)writefd;
return (p7_error_nocalc);
}
#endif

View File

@ -1,93 +0,0 @@
/* ************************************************************************** */
/* _____ _ */
/* streams/tty.c |_ _|__ _ _| |__ ___ _ _ */
/* | Project: libp7 | |/ _ \| | | | '_ \ / _ \ | | | */
/* | | (_) | |_| | | | | __/ |_| | */
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
/* Last updated: 2017/01/04 15:01:48 |___/ */
/* */
/* ************************************************************************** */
#include <libp7/internals.h>
#include <string.h>
/* ************************************************************************** */
/* *nix serial device initialization and callbacks */
/* ************************************************************************** */
#ifdef __linux__
# include <fcntl.h>
# include <errno.h>
/**
* p7_cinit:
* Initialize libp7 with char device.
*
* @arg handle the handle to create
* @arg flags the flags.
* @arg path path to char device.
* @return the error (0 if ok)
*/
int p7_cinit(p7_handle_t **handle, unsigned int flags, const char *path)
{
int fd = -1;
/* if no path, as there are no native drivers, we're fucked */
if (!path) return (p7_error_nocalc);
/* open the stream */
fd = open(path, O_RDWR | O_NOCTTY);
if (fd < 0) switch (errno) {
/* no such device */
case ENODEV: case ENOENT: case ENXIO:
case EPIPE: case ESPIPE:
logr_error("couldn't open calculator");
return (p7_error_nocalc);
/* no access */
case EACCES:
logr_error("permission denied");
return (p7_error_noaccess);
/* default */
default:
logr_error("unknown error: %s (0x%X)", strerror(errno), errno);
return (p7_error_unknown);
}
/* check if we have got the thing */
if (!path) return (p7_error_nocalc);
if (fd < 0) switch (errno) {
case ENOENT: return (p7_error_nocalc);
case EACCES: return (p7_error_noaccess);
default: return (p7_error_nocalc);
}
/* init to real */
return (p7_fdinit(handle, flags, NULL, fd, fd));
}
/* ************************************************************************** */
/* Use a character device on other systems (placebo) */
/* ************************************************************************** */
#else
/**
* p7_cinit:
* Initialize libp7 with char device. Placebo.
*
* @arg handle the handle to create
* @arg flags the flags
* @arg path path to char device.
* @arg tries number of tries (0 means default).
* @return the error (0 if ok)
*/
int p7_cinit(p7_handle_t **handle, unsigned int flags,
const char *path)
{
(void)handle;
(void)flags;
(void)path;
return (p7_error_nocalc);
}
#endif

View File

@ -8,16 +8,40 @@
/* */
/* ************************************************************************** */
#include <libp7/internals.h>
/* ************************************************************************** */
/* Find devices on Microsoft Windows */
/* ************************************************************************** */
#ifdef __WINDOWS__
#ifndef P7_DISABLED_WINDOWS
# include <windows.h>
# include <setupapi.h>
# include <usbiodef.h>
# include <winerror.h>
/* ************************************************************************** */
/* Open a serial device */
/* ************************************************************************** */
/**
* p7_wcominit:
* Initialize using a MS-Windows serial device.
*
* @arg handle the handle to make.
* @arg flags the flags.
* @arg com the com port number.
* @return the error code (0 if ok).
*/
int p7_wcominit(p7_handle_t **handle, unsigned int flags, int com)
{
/* make up the serial device path */
logr_info("Looking for specific MS-Windows devices");
char path[20];
if (com <= 9) sprintf(path, "COM%d", com);
else sprintf(path, "\\\\?\\COM%d", com);
/* initialize */
return (p7_winit(handle, flags, path));
}
/* ************************************************************************** */
/* Find devices on Microsoft Windows */
/* ************************************************************************** */
/**
* wfind:
* Find the Microsoft Windows device path.
@ -384,27 +408,4 @@ int p7_winit(p7_handle_t **handle, unsigned int flags, const char *path)
free(p); return (err);
}
/* ************************************************************************** */
/* Not on windows: placebo */
/* ************************************************************************** */
#else
/**
* p7_winit:
* Initialize libp7 [not] using the Microsoft Windows API. Placebo.
*
* @arg handle the handle to create.
* @arg flags the flags.
* @arg path the MS-Windows device path.
* @return the error code (0 if you're a knoop).
*/
int p7_winit(p7_handle_t **handle, unsigned int flags, const char *path)
{
(void)handle;
(void)flags;
(void)path;
return (p7_error_nocalc);
}
#endif