diff --git a/include/libcasio.h b/include/libcasio.h index 2d3e4eb..39f8c99 100644 --- a/include/libcasio.h +++ b/include/libcasio.h @@ -24,6 +24,7 @@ # include "libcasio/log.h" # include "libcasio/number.h" +# include "libcasio/misc.h" # include "libcasio/link.h" # include "libcasio/file.h" diff --git a/include/libcasio/builtin.h b/include/libcasio/builtin.h deleted file mode 100644 index eb8bf1e..0000000 --- a/include/libcasio/builtin.h +++ /dev/null @@ -1,150 +0,0 @@ -/* **************************************************************************** - * libcasio/builtin.h -- libcasio built-in platform-specific things. - * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey - * - * This file is part of libcasio. - * libcasio 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.0 of the License, - * or (at your option) any later version. - * - * libcasio 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libcasio; if not, see . - * ************************************************************************* */ -#ifndef LIBCASIO_BUILTIN_H -# define LIBCASIO_BUILTIN_H -# include "cdefs.h" -# include "stream.h" -# include "fs.h" -# ifndef LIBCASIO_DISABLED_FILE -# include -# endif -CASIO_BEGIN_NAMESPACE -CASIO_BEGIN_DECLS - -/* --- - * Built-in streams. - * --- */ - -/* Make a stream using the standard FILE interface. */ - -# ifndef LIBCASIO_DISABLED_FILE -CASIO_EXTERN int CASIO_EXPORT casio_open_stream_file - OF((casio_stream_t **casio__stream, - FILE *casio__readstream, FILE *casio__writestream, - int casio__close_readstream, int casio__close_writestream)); -# endif - -/* Make a stream using the POSIX STREAMS interface. */ - -# if defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) -CASIO_EXTERN int CASIO_EXPORT casio_opencom_streams - OF((casio_stream_t **casio__stream, const char *casio__path)); - -CASIO_EXTERN int CASIO_EXPORT casio_open_stream_streams - OF((casio_stream_t **casio__stream, - const char *casio__path, casio_openmode_t casio__mode)); -CASIO_EXTERN int CASIO_EXPORT casio_open_stream_fd - OF((casio_stream_t **casio__stream, - int casio__readfd, int casio__writefd, - int casio__closeread, int casio__closewrite)); -# else -# define LIBCASIO_DISABLED_STREAMS -# endif - -/* Make a stream using libusb. */ - -# ifndef LIBCASIO_DISABLED_LIBUSB -CASIO_EXTERN int CASIO_EXPORT casio_openusb_libusb - OF((casio_stream_t **casio__stream, - int casio__bus, int casio__address)); -# endif - -/* Make a stream using the Microsoft Windows API. */ - -# if defined(_WIN16) || defined(_WIN32) || defined(_WIN64) \ - || defined(__WINDOWS__) -CASIO_EXTERN int CASIO_EXPORT casio_openusb_windows - OF((casio_stream_t **casio__stream, - int casio__bus, int casio__address)); -CASIO_EXTERN int CASIO_EXPORT casio_opencom_windows - OF((casio_stream_t **casio__stream, const char *casio__path)); -# else -# define LIBCASIO_DISABLED_WINDOWS -# endif - -/* --- - * Built-in filesystems. - * --- */ - -/* Make a POSIX filesystem interface. */ - -# if defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) -CASIO_EXTERN int CASIO_EXPORT casio_open_posix_fs - OF((casio_fs_t **casio__filesystem)); -# else -# define LIBCASIO_DISABLED_POSIX_FS 1 -# endif - -/* Make a Windows API filesystem interface. */ - -# ifndef LIBCASIO_DISABLED_WINDOWS -CASIO_EXTERN int CASIO_EXPORT casio_open_windows_fs - OF((casio_fs_t **casio__filesystem)); -# endif - -/* --- - * Built-in serial devices listing. - * --- */ - -/* List serial devices on Linux. */ - -# ifdef __linux__ -CASIO_EXTERN int CASIO_EXPORT casio_comlist_linux - OF((casio_list_com_t *casio__callback, void *casio__cookie)); -# endif - -/* List serial devices on MacOS/OS X. */ - -# if defined(__APPLE__) && defined(__MACH__) -CASIO_EXTERN int CASIO_EXPORT casio_comlist_macos - OF((casio_list_com_t *casio__callback, void *casio__cookie)); -# endif - -/* List serial devices on Microsoft Windows. */ - -# ifndef LIBCASIO_DISABLED_WINDOWS -CASIO_EXTERN int CASIO_EXPORT casio_comlist_windows - OF((casio_list_com_t *casio__callback, void *casio__cookie)); -# endif - -/* --- - * Built-in functions. - * --- */ - -/* As there is no portable sleep function, libcasio implements one. - * It takes a callback, of the following form: */ - -typedef void casio_sleep_t OF((unsigned long casio__ms)); - -CASIO_EXTERN void CASIO_EXPORT casio_set_sleep - OF((casio_sleep_t *casio__func)); -CASIO_EXTERN int CASIO_EXPORT casio_sleep - OF((unsigned long casio__ms)); - -/* And here are cross-platform allocation functions. - * They are defined just in case. */ - -CASIO_EXTERN void* CASIO_EXPORT casio_alloc - OF((size_t casio__num_elements, size_t casio__element_size)); -CASIO_EXTERN void CASIO_EXPORT casio_free - OF((void *casio__ptr)); - -CASIO_END_DECLS -CASIO_END_NAMESPACE -#endif /* LIBCASIO_BUILTIN_H */ diff --git a/include/libcasio/cdefs.h b/include/libcasio/cdefs.h index bcb505d..d00639b 100644 --- a/include/libcasio/cdefs.h +++ b/include/libcasio/cdefs.h @@ -66,6 +66,43 @@ # define CASIO_MSC_PREREQ(CASIO__MAJ, CASIO__MIN) 0 # endif +/* --- + * Check for subsystems. + * --- */ + +/* Macros defined by the `libcasio/config.h` header: + * - `LIBCASIO_DISABLED_FILE`: can we use the standard FILE operations? + * - `LIBCASIO_DISABLED_LIBUSB`: can we use libusb? */ + +/* Can we use the Linux and the MacOS/OS X listing? + * XXX: what about Linux distributions not using the Linux standard + * filesystem? */ + +# if defined(__linux__) +# else +# define LIBCASIO_DISABLED_LINUX_SERIAL +# endif + +# if defined(__APPLE__) && defined(__MACH__) +# else +# define LIBCASIO_DISABLED_MAC_SERIAL +# endif + +/* Can we use the POSIX (STREAMS) interface? */ + +# if defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) +# else +# define LIBCASIO_DISABLED_STREAMS +# endif + +/* Can we use the Windows (Win32/Win64) API? */ + +# if defined(_WIN16) || defined(_WIN32) || defined(_WIN64) \ + || defined(__WINDOWS__) +# else +# define LIBCASIO_DISABLED_WINDOWS +# endif + /* --- * Extern functions. * --- */ diff --git a/include/libcasio/date.h b/include/libcasio/date.h index c8db4b2..f8eb817 100644 --- a/include/libcasio/date.h +++ b/include/libcasio/date.h @@ -28,9 +28,9 @@ CASIO_BEGIN_NAMESPACE CASIO_BEGIN_DECLS CASIO_EXTERN int CASIO_EXPORT casio_decode_date - OF((time_t *casio__date, const char *casio__raw)); + OF((time_t *casio__date, char const *casio__raw)); CASIO_EXTERN int CASIO_EXPORT casio_encode_date - OF((char *casio__raw, const time_t *casio__date)); + OF((char *casio__raw, time_t const *casio__date)); CASIO_END_DECLS diff --git a/include/libcasio/error.h b/include/libcasio/error.h index f100da7..323d2da 100644 --- a/include/libcasio/error.h +++ b/include/libcasio/error.h @@ -61,9 +61,12 @@ typedef int casio_error_t; * stream has failed */ # define casio_error_noseek 0x13 /* (alias) */ # define casio_error_timeout 0x14 /* a timeout has occured. */ +# define casio_error_time 0x14 /* (alias) */ # define casio_error_access 0x15 /* could not access the device (perms) */ # define casio_error_noaccess 0x15 /* (alias) */ # define casio_error_eof 0x16 /* end of file */ +# define casio_error_scsi 0x17 /* a SCSI operation has failed. */ +# define casio_error_usb 0x18 /* a USB operation has failed. */ /* Link errors. */ @@ -101,9 +104,9 @@ typedef int casio_error_t; /* Get a string describing the error. */ -CASIO_EXTERN const char* CASIO_EXPORT casio_error_strings[]; +CASIO_EXTERN char const* CASIO_EXPORT casio_error_strings[]; -CASIO_EXTERN const char* CASIO_EXPORT casio_strerror +CASIO_EXTERN char const* CASIO_EXPORT casio_strerror OF((int casio__error)); # ifndef LIBCASIO_NO_STRERROR diff --git a/include/libcasio/file.h b/include/libcasio/file.h index b242af1..c8782c0 100644 --- a/include/libcasio/file.h +++ b/include/libcasio/file.h @@ -121,8 +121,8 @@ CASIO_EXTERN int CASIO_EXPORT casio_make_lang CASIO_EXTERN int CASIO_EXPORT casio_make_addin OF((casio_file_t **casio__handle, casio_filefor_t casio__for, size_t casio__size, - const char *casio__name, const char *casio__internal, - const casio_version_t *casio__version, const time_t *casio__created)); + char const *casio__name, char const *casio__internal, + casio_version_t const *casio__version, time_t const *casio__created)); /* Free a file. */ @@ -133,13 +133,13 @@ CASIO_EXTERN void CASIO_EXPORT casio_free_file CASIO_EXTERN int CASIO_EXPORT casio_decode OF((casio_file_t **casio__handle, - const char *casio__path, casio_stream_t *casio__buffer, + char const *casio__path, casio_stream_t *casio__buffer, casio_filetype_t casio__expected_types)); /* Open and decode a file. */ CASIO_EXTERN int CASIO_EXPORT casio_open_file OF((casio_file_t **casio__handle, - const char *casio__path, casio_filetype_t casio__expected_types)); + char const *casio__path, casio_filetype_t casio__expected_types)); #endif /* LIBCASIO_FILE_H */ diff --git a/include/libcasio/fs.h b/include/libcasio/fs.h index 084722d..77cbccc 100644 --- a/include/libcasio/fs.h +++ b/include/libcasio/fs.h @@ -80,61 +80,32 @@ struct casio_path_s { /* This structure defines file metadata. * Here are the flags: - * `CASIO_STAT_FLAG_PERM`: stat permissions are set; * `CASIO_STAT_FLAG_BTIME`: birth time is set; * `CASIO_STAT_FLAG_ATIME`: last accessed time is set; * `CASIO_STAT_FLAG_MTIME`: last modif. time is set. */ -# define CASIO_STAT_FLAG_PERM 0x0001 -# define CASIO_STAT_FLAG_BTIME 0x0002 -# define CASIO_STAT_FLAG_ATIME 0x0004 -# define CASIO_STAT_FLAG_MTIME 0x0008 - -/* Elements can have Unix-like permissions. Here they are: - * `CASIO_STAT_PERM_IRUSR`: user has read permission; - * `CASIO_STAT_PERM_IWUSR`: user has write permission; - * `CASIO_STAT_PERM_IXUSR`: user has exec permission; - * `CASIO_STAT_PERM_IRGRP`: group has read permission; - * `CASIO_STAT_PERM_IWGRP`: group has write permission; - * `CASIO_STAT_PERM_IXGRP`: group has exec permission; - * `CASIO_STAT_PERM_IROTH`: others have read permission; - * `CASIO_STAT_PERM_IWOTH`: others have write permission; - * `CASIO_STAT_PERM_IXOTH`: others have exec permission. */ - -# define CASIO_STAT_PERM_IRUSR 0x0001 -# define CASIO_STAT_PERM_IWUSR 0x0002 -# define CASIO_STAT_PERM_IXUSR 0x0004 -# define CASIO_STAT_PERM_IRGRP 0x0010 -# define CASIO_STAT_PERM_IWGRP 0x0020 -# define CASIO_STAT_PERM_IXGRP 0x0040 -# define CASIO_STAT_PERM_IROTH 0x0100 -# define CASIO_STAT_PERM_IWOTH 0x0200 -# define CASIO_STAT_PERM_IXOTH 0x0400 +# define CASIO_STAT_FLAG_BTIME 0x0001 +# define CASIO_STAT_FLAG_ATIME 0x0002 +# define CASIO_STAT_FLAG_MTIME 0x0004 /* And here are the "file" types ("file" is between quotes as on Windows, * directories are not files like on Unix) you can find: + * `CASIO_STAT_TYPE_OTH`: other type of file. * `CASIO_STAT_TYPE_REG`: regular file; - * `CASIO_STAT_TYPE_DIR`: directory; - * `CASIO_STAT_TYPE_LNK`: symbolic link; - * `CASIO_STAT_TYPE_CHAR`: character device; - * `CASIO_STAT_TYPE_BLK`: block device; - * `CASIO_STAT_TYPE_SOCK`: socket */ + * `CASIO_STAT_TYPE_DIR`: directory; */ +# define CASIO_STAT_TYPE_OTH 0x0000 # define CASIO_STAT_TYPE_REG 0x0001 # define CASIO_STAT_TYPE_DIR 0x0002 -# define CASIO_STAT_TYPE_LNK 0x0004 -# define CASIO_STAT_TYPE_CHAR 0x0008 -# define CASIO_STAT_TYPE_BLK 0x0010 -# define CASIO_STAT_TYPE_SOCK 0x0020 /* And here is the stat structure. The elements it contains at runtime depend * on the flags (useful for binary compatibility and filesystem metadata type). - * For example, if `~thestat.casio_stat_flags & CASIO_STAT_FLAG_PERM`, - * then you shouldn't try to read the permissions, as it might contain crap. + * For example, if `~thestat.casio_stat_flags & CASIO_STAT_FLAG_MTIME`, + * then you shouldn't try to read the last modification time, as it might + * contain crap. * * The elements are the following: * [ ] `casio_stat_type`: the file type (see the `CASIO_STAT_TYPE_*` macros); - * [X] `casio_stat_perm`: Unix-like permissions (see `CASIO_STAT_PERM_*`); * [X] `casio_stat_size`: the file size; * [X] `casio_stat_btime`: the file's birth time; * [X] `casio_stat_atime`: the file's last access time; @@ -150,8 +121,6 @@ struct casio_path_s { struct casio_stat_s { unsigned short casio_stat_flags; unsigned short casio_stat_type; - unsigned short casio_stat_perm; - unsigned short casio_stat__reserved; casio_off_t casio_stat_size; time_t casio_stat_btime; @@ -166,7 +135,7 @@ struct casio_stat_s { * `casio_duplicate_pathnode`! */ typedef void CASIO_EXPORT casio_fs_list_func_t OF((void *casio__cookie, - const casio_pathnode_t *casio__node, const casio_stat_t *casio__stat)); + casio_pathnode_t const *casio__node, casio_stat_t const *casio__stat)); /* --- * Filesystem description. @@ -203,7 +172,7 @@ typedef int CASIO_EXPORT casio_fs_stat_t # if defined(__STDC__) && __STDC__ typedef int CASIO_EXPORT casio_fs_make_t(void *casio__cookie, - void *casio__native_path, const casio_stat_t *casio__stat, ...); + void *casio__native_path, casio_stat_t const *casio__stat, ...); # else typedef int CASIO_EXPORT casio_fs_make_t(); # endif @@ -246,7 +215,7 @@ typedef int CASIO_EXPORT casio_fs_list_t * we're only considering this operation for CASIOWIN. */ typedef int CASIO_EXPORT casio_fs_optim_t - OF((void *casio__cookie, const char *device)); + OF((void *casio__cookie, char const *device)); /* And here is the structure with all of the functions. * It is the one used when you want to open a libcasio filesystem interface diff --git a/include/libcasio/iter.h b/include/libcasio/iter.h index a05d528..65087dd 100644 --- a/include/libcasio/iter.h +++ b/include/libcasio/iter.h @@ -77,11 +77,22 @@ CASIO_BEGIN_DECLS CASIO_EXTERN int CASIO_EXPORT casio_iter OF((casio_iter_t **casio__iterp, void *casio__cookie, casio_iter_funcs_t const *casio__funcs)); + CASIO_EXTERN int CASIO_EXPORT casio_next OF((casio_iter_t *casio__iter, void **casio__ptr)); + CASIO_EXTERN void CASIO_EXPORT casio_end OF((casio_iter_t *casio__iter)); +/* You can make a “super iterator” that makes an iterator out of two + * iterators! It will empty the first one, then the second one. + * It will also take care of closing them. */ + +CASIO_EXTERN int CASIO_EXPORT casio_combine_iterators + OF((casio_iter_t **casio__iterp, + casio_iter_t *casio__first, + casio_iter_t *casio__second)); + CASIO_END_DECLS CASIO_END_NAMESPACE diff --git a/include/libcasio/link.h b/include/libcasio/link.h index 362341f..d8b115a 100644 --- a/include/libcasio/link.h +++ b/include/libcasio/link.h @@ -24,6 +24,11 @@ # include "fs.h" # include "version.h" # include "picture.h" +# include "iter.h" +# ifndef LIBCASIO_DISABLED_FILE +# include +# endif + CASIO_BEGIN_NAMESPACE /* --- @@ -40,34 +45,41 @@ typedef struct casio_link_s casio_link_t; /* Link information. * This is basically the identification information sent by the calculator, * only in Protocol 7.00 (Graph 85 and following) and CAS100 (AFX, - * Graph 100). */ + * Graph 100). + * + * TODO: make flags for other information not available for AFX? */ -# define casio_link_info_wiped_preprog 0x0001 -# define casio_link_info_wiped_bootcode 0x0002 -# define casio_link_info_wiped_os 0x0004 +# define casio_link_info_flag_preprog 0x0001 +# define casio_link_info_flag_bootcode 0x0002 +# define casio_link_info_flag_os 0x0004 typedef struct casio_link_info_s { - unsigned int casio_link_info_wiped; + unsigned long casio_link_info_flags; + + /* Preprogrammed ROM information. */ - /* preprogrammed ROM information */ unsigned long casio_link_info_rom_capacity; casio_version_t casio_link_info_rom_version; - /* flash ROM and RAM information */ + /* Flash ROM and RAM information. */ + unsigned long casio_link_info_flash_rom_capacity; unsigned long casio_link_info_ram_capacity; - /* bootcode information */ + /* Bootcode information. */ + casio_version_t casio_link_info_bootcode_version; unsigned long casio_link_info_bootcode_offset; unsigned long casio_link_info_bootcode_size; - /* OS information */ + /* OS information. */ + casio_version_t casio_link_info_os_version; unsigned long casio_link_info_os_offset; unsigned long casio_link_info_os_size; - /* other information */ + /* Other information. */ + char casio_link_info_product_id[17]; char casio_link_info_username[17]; char casio_link_info_hwid[9]; @@ -95,7 +107,7 @@ typedef void CASIO_EXPORT casio_link_progress_t /* List files. */ typedef void CASIO_EXPORT casio_link_list_t - OF((void *casio__cookie, const char *casio__path, + OF((void *casio__cookie, char const *casio__path, const casio_stat_t *casio__stat)); /* --- @@ -118,12 +130,42 @@ typedef struct casio_screen_s { * Basic link handle operations. * --- */ -/* Initialization flags. - * `CASIO_LINKFLAG_ACTIVE`: start off as active; - * `CASIO_LINKFLAG_CHECK`: check (initial packet); - * `CASIO_LINKFLAG_TERM`: terminate; +/* Useful flags for when opening a link. + * + * Here are the various transport protocols, which isn't given by the available + * operations on the stream (as it could be USB but we may not be able + * to do USB operations because of drivers such as the CESG502 driver + * on Microsoft Windows): + * + * `CASIO_LINKFLAG_SERIAL`: serial connexion. + * `CASIO_LINKFLAG_USB`: USB. + * `CASIO_LINKFLAG_SCSI`: SCSI operations. + * + * These are read if the connexion is serial (which means that the + * protocol cannot be determined and that the user needs to say which one + * they want to use): + * + * `CASIO_LINKFLAG_CAS40`: CAS40 (very old protocol). + * `CASIO_LINKFLAG_CAS50`: CAS50 (old protocol). + * `CASIO_LINKFLAG_CAS100`: CAS100 (not so old protocol used on the AFX). + * `CASIO_LINKFLAG_P7`: protocol 7.00 (starting to get old but still there). + * + * These are read if the protocol is protocol 7.00: + * + * `CASIO_LINKFLAG_ACTIVE`: start off as active. + * `CASIO_LINKFLAG_CHECK`: check (initial packet). + * `CASIO_LINKFLAG_TERM`: terminate. * `CASIO_LINKFLAG_NODISC`: if we are checking, no environment discovery. */ +# define CASIO_LINKFLAG_SERIAL 0x00000000 +# define CASIO_LINKFLAG_USB 0x00001000 +# define CASIO_LINKFLAG_SCSI 0x00002000 + +# define CASIO_LINKFLAG_P7 0x00000000 +# define CASIO_LINKFLAG_CAS40 0x00000100 +# define CASIO_LINKFLAG_CAS50 0x00000200 +# define CASIO_LINKFLAG_CAS100 0x00000300 + # define CASIO_LINKFLAG_ACTIVE 0x00000001 # define CASIO_LINKFLAG_CHECK 0x00000002 # define CASIO_LINKFLAG_TERM 0x00000004 @@ -131,22 +173,26 @@ typedef struct casio_screen_s { CASIO_BEGIN_DECLS -/* Cross-platform initialization. */ +/* Open a serial link. */ -CASIO_EXTERN int CASIO_EXPORT casio_open_usb - OF((casio_link_t **casio__h, unsigned long casio__flags, - int casio__bus, int casio__address)); -CASIO_EXTERN int CASIO_EXPORT casio_open_com +CASIO_EXTERN int CASIO_EXPORT casio_open_serial OF((casio_link_t **casio__h, unsigned long casio__flags, char const *casio__path, casio_streamattrs_t const *casio__attributes)); -/* Initialize a handle using a custom stream. */ +/* Open a USB link. */ + +CASIO_EXTERN int CASIO_EXPORT casio_open_usb + OF((casio_link_t **casio__h, unsigned long casio__flags, + int casio__bus, int casio__address)); + +/* Initialize a handle using a custom stream. + * This function will check if the stream is a USB stream by looking + * at the open mode of the stream. */ CASIO_EXTERN int CASIO_EXPORT casio_open_link - OF((casio_link_t **casio__h, - unsigned long casio__flags, casio_stream_t *casio__stream, - casio_streamattrs_t const *casio__attributes)); + OF((casio_link_t **casio__h, unsigned long casio__flags, + casio_stream_t *casio__stream)); /* De-initialize. */ diff --git a/include/libcasio/log.h b/include/libcasio/log.h index 0ccce1d..d51c47b 100644 --- a/include/libcasio/log.h +++ b/include/libcasio/log.h @@ -27,13 +27,13 @@ CASIO_BEGIN_DECLS CASIO_EXTERN void CASIO_EXPORT casio_setlog OF((const char *casio__level)); -CASIO_EXTERN const char* CASIO_EXPORT casio_getlog +CASIO_EXTERN char const* CASIO_EXPORT casio_getlog OF((void)); /* List log levels (deprecated interface) */ typedef void casio_log_list_t OF((void *casio__cookie, - const char *casio__str)); + char const *casio__str)); CASIO_EXTERN CASIO_DEPRECATED void CASIO_EXPORT casio_listlog OF((casio_log_list_t *casio__callback, void *casio__cookie)); diff --git a/include/libcasio/mcs.h b/include/libcasio/mcs.h index 61e4344..fdef747 100644 --- a/include/libcasio/mcs.h +++ b/include/libcasio/mcs.h @@ -79,7 +79,7 @@ CASIO_BEGIN_DECLS CASIO_EXTERN int CASIO_EXPORT casio_open_mcs OF((casio_mcs_t **casio__mcs, void *casio__cookie, - const casio_mcsfuncs_t *casio__funcs)); + casio_mcsfuncs_t const *casio__funcs)); CASIO_EXTERN int CASIO_EXPORT casio_close_mcs OF((casio_mcs_t *casio__mcs)); @@ -108,7 +108,7 @@ CASIO_EXTERN int CASIO_EXPORT casio_delete_mcsfile /* List MCS files (the deprecated way). */ typedef void CASIO_EXPORT casio_mcslist_t - OF((void *casio__cookie, const casio_mcshead_t *casio__mcshead)); + OF((void *casio__cookie, casio_mcshead_t const *casio__mcshead)); CASIO_EXTERN CASIO_DEPRECATED int CASIO_EXPORT casio_list_mcsfiles OF((casio_mcs_t *casio__mcs, casio_mcslist_t *casio__mcslist, diff --git a/include/libcasio/mcsfile.h b/include/libcasio/mcsfile.h index 425dbbc..b92d3e1 100644 --- a/include/libcasio/mcsfile.h +++ b/include/libcasio/mcsfile.h @@ -261,9 +261,9 @@ CASIO_BEGIN_DECLS /* Make a main memory file, prepare it, and free it. */ CASIO_EXTERN int CASIO_EXPORT casio_make_mcsfile - OF((casio_mcsfile_t **casio__handle, const casio_mcshead_t *casio__head)); + OF((casio_mcsfile_t **casio__handle, casio_mcshead_t const *casio__head)); CASIO_EXTERN int CASIO_EXPORT casio_prepare_mcsfile - OF((casio_mcsfile_t *casio__handle, const casio_mcshead_t *casio__head)); + OF((casio_mcsfile_t *casio__handle, casio_mcshead_t const *casio__head)); CASIO_EXTERN void CASIO_EXPORT casio_free_mcsfile OF((casio_mcsfile_t *casio__handle)); @@ -278,19 +278,19 @@ CASIO_EXTERN int CASIO_EXPORT casio_copy_mcsfile CASIO_EXTERN int CASIO_EXPORT casio_decode_mcsfile_head OF((casio_mcshead_t *casio__head, int casio__raw_type, - const unsigned char *casio__groupname, - const unsigned char *casio__dirname, - const unsigned char *casio__filename, + unsigned char const *casio__groupname, + unsigned char const *casio__dirname, + unsigned char const *casio__filename, unsigned long casio__filesize)); CASIO_EXTERN int CASIO_EXPORT casio_decode_mcsfile OF((casio_mcsfile_t **casio__handle, - const casio_mcshead_t *casio__head, + casio_mcshead_t const *casio__head, casio_stream_t *casio__buffer)); CASIO_EXTERN int CASIO_EXPORT casio_decode_mcsfile_data OF((casio_mcsfile_t **casio__handle, - const casio_mcshead_t *casio__head, - const void *casio__data, size_t casio__size)); + casio_mcshead_t const *casio__head, + void const *casio__data, size_t casio__size)); CASIO_EXTERN int CASIO_EXPORT casio_encode_mcsfile OF((casio_mcsfile_t *casio__handle, casio_stream_t *casio__buffer)); diff --git a/include/libcasio/misc.h b/include/libcasio/misc.h new file mode 100644 index 0000000..fcfd0a2 --- /dev/null +++ b/include/libcasio/misc.h @@ -0,0 +1,81 @@ +/* **************************************************************************** + * libcasio/misc.h -- libcasio miscallaneous utilities. + * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey + * + * This file is part of libcasio. + * libcasio 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.0 of the License, + * or (at your option) any later version. + * + * libcasio 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libcasio; if not, see . + * ************************************************************************* */ +#ifndef LIBCASIO_MISC_H +# define LIBCASIO_MISC_H 2018051601 +# include "cdefs.h" +# include "stream.h" +# include "fs.h" + +CASIO_BEGIN_NAMESPACE +CASIO_BEGIN_DECLS + +/* As there is no portable sleep function, libcasio implements one. + * It takes a callback, of the following form: */ + +CASIO_EXTERN int CASIO_EXPORT casio_sleep + OF((unsigned long casio__ms)); + +/* If the default function is not good enough for you, just change it + * using the following function. */ + +typedef void casio_sleep_t OF((unsigned long casio__ms)); + +CASIO_EXTERN void CASIO_EXPORT casio_set_sleep_func + OF((casio_sleep_t *casio__func)); + +/* As for time and timeouts management, here are functions to time + * anything in libcasio. Times are expressed in milliseconds. */ + +struct casio_timer_s; +typedef struct casio_timer_s casio_timer_t; + +CASIO_EXTERN int CASIO_EXPORT casio_get_timer + OF((casio_timer_t **casio__timer)); +CASIO_EXTERN void CASIO_EXPORT casio_free_timer + OF((casio_timer_t *casio__timer)); + +CASIO_EXTERN int CASIO_EXPORT casio_get_spent_time + OF((casio_timer_t *casio__timer, unsigned long *casio__spent)); + +/* You can change these functions too! */ + +typedef int CASIO_EXPORT casio_get_timer_t + OF((casio_timer_t **casio__timer)); +typedef void CASIO_EXPORT casio_free_timer_t + OF((casio_timer_t *casio__timer)); +typedef int CASIO_EXPORT casio_get_spent_time_t + OF((casio_timer_t *casio__timer, unsigned long *casio__spent)); + +CASIO_EXTERN int CASIO_EXPORT casio_set_timer_funcs + OF((casio_get_timer_t *casio__get_timer, + casio_free_timer_t *casio__free_timer, + casio_get_spent_time_t *casio__get_spent_time)); + +/* And here are cross-platform allocation functions. + * They are defined just in case. */ + +CASIO_EXTERN void* CASIO_EXPORT casio_alloc + OF((size_t casio__num_elements, size_t casio__element_size)); +CASIO_EXTERN void CASIO_EXPORT casio_free + OF((void *casio__ptr)); + +CASIO_END_DECLS +CASIO_END_NAMESPACE + +#endif /* LIBCASIO_MISC_H */ diff --git a/include/libcasio/number.h b/include/libcasio/number.h index 73d3c47..4e179f5 100644 --- a/include/libcasio/number.h +++ b/include/libcasio/number.h @@ -124,28 +124,28 @@ CASIO_BEGIN_DECLS /* From and to MCS BCD. */ CASIO_EXTERN int CASIO_EXPORT casio_bcd_frommcs - OF((casio_bcd_t *casio__bcd, const casio_mcsbcd_t *casio__raw)); + OF((casio_bcd_t *casio__bcd, casio_mcsbcd_t const *casio__raw)); CASIO_EXTERN int CASIO_EXPORT casio_bcd_tomcs - OF((casio_mcsbcd_t *casio__raw, const casio_bcd_t *casio__bcd)); + OF((casio_mcsbcd_t *casio__raw, casio_bcd_t const *casio__bcd)); /* From and to CAS BCD. */ CASIO_EXTERN int CASIO_EXPORT casio_bcd_fromcas - OF((casio_bcd_t *casio__bcd, const casio_casbcd_t *casio__raw)); + OF((casio_bcd_t *casio__bcd, casio_casbcd_t const *casio__raw)); CASIO_EXTERN int CASIO_EXPORT casio_bcd_tocas - OF((casio_casbcd_t *casio__raw, const casio_bcd_t *casio__bcd)); + OF((casio_casbcd_t *casio__raw, casio_bcd_t const *casio__bcd)); /* From and to C-double */ CASIO_EXTERN void CASIO_EXPORT casio_bcd_fromdouble OF((casio_bcd_t *casio__bcd, double casio__raw)); CASIO_EXTERN double CASIO_EXPORT casio_bcd_todouble - OF((const casio_bcd_t *casio__bcd)); + OF((casio_bcd_t const *casio__bcd)); /* Make a string out of a BCD */ CASIO_EXTERN size_t CASIO_EXPORT casio_bcdtoa - OF((char *casio__buf, size_t casio__len, const casio_bcd_t *casio__bcd)); + OF((char *casio__buf, size_t casio__len, casio_bcd_t const *casio__bcd)); CASIO_END_DECLS CASIO_END_NAMESPACE diff --git a/include/libcasio/picture.h b/include/libcasio/picture.h index 8093ed3..26d6e7b 100644 --- a/include/libcasio/picture.h +++ b/include/libcasio/picture.h @@ -223,11 +223,11 @@ CASIO_EXTERN size_t CASIO_EXPORT casio_get_picture_size CASIO_EXTERN int CASIO_EXPORT casio_decode_picture OF((casio_pixel_t **casio__pixels, - const void *casio__raw, casio_pictureformat_t casio__format, + void const *casio__raw, casio_pictureformat_t casio__format, unsigned int casio__width, unsigned casio__height)); CASIO_EXTERN int CASIO_EXPORT casio_encode_picture - OF((void *casio__raw, const casio_pixel_t **casio__pixels, + OF((void *casio__raw, casio_pixel_t const * const *casio__pixels, casio_pictureformat_t casio__format, unsigned int casio__width, unsigned casio__height)); diff --git a/include/libcasio/protocol/seven.h b/include/libcasio/protocol/seven.h index 91f6cab..0566d50 100644 --- a/include/libcasio/protocol/seven.h +++ b/include/libcasio/protocol/seven.h @@ -320,15 +320,18 @@ CASIO_END_DECLS * are used depending on the packet type/code. */ typedef struct casio_seven_packet_s { - /* main info */ + /* Main info. */ + casio_seven_type_t casio_seven_packet_type; int casio_seven_packet_extended; - /* error, termination, check */ + /* Error, termination, check. */ + int casio_seven_packet_code; int casio_seven_packet_initial; - /* commands */ + /* Commands. */ + int casio_seven_packet_ow; int casio_seven_packet_mcstype; unsigned long casio_seven_packet_filesize; @@ -337,20 +340,24 @@ typedef struct casio_seven_packet_s { unsigned long casio_seven_packet_loadaddr; unsigned long casio_seven_packet_straddr; - /* data */ + /* Data. */ + unsigned int casio_seven_packet_id; unsigned int casio_seven_packet_total; unsigned int casio_seven_packet_data_size; - /* server information */ + /* Server information. */ + casio_link_info_t casio_seven_packet_info; - /* screen */ + /* Screen. */ + casio_pictureformat_t casio_seven_packet_pictype; unsigned int casio_seven_packet_height; unsigned int casio_seven_packet_width; - /* big things */ + /* Big things. */ + unsigned char casio_seven_packet_data[CASIO_SEVEN_MAX_RAWDATA_SIZE]; char casio_seven_packet__argsdata[6][CASIO_SEVEN_MAX_CMDARG_SIZE + 1]; char casio_seven_packet_vram[CASIO_SEVEN_MAX_VRAM_SIZE]; diff --git a/include/libcasio/setup.h b/include/libcasio/setup.h index 44d9bcc..206eb13 100644 --- a/include/libcasio/setup.h +++ b/include/libcasio/setup.h @@ -92,7 +92,8 @@ CASIO_BEGIN_NAMESPACE # define casio_drawtype_con 0 # define casio_drawtype_plot 1 -/* Main structure */ +/* Main structure. */ + typedef struct casio_setup_s { unsigned int casio_setup_iflags; unsigned int casio_setup_wflags; @@ -114,7 +115,7 @@ CASIO_EXTERN void CASIO_EXPORT casio_init_setup /* Feed the structure. */ CASIO_EXTERN int CASIO_EXPORT casio_feed_setup_seven - OF((casio_setup_t *casio__setup, const char *casio__name, int casio__val)); + OF((casio_setup_t *casio__setup, char const *casio__name, int casio__val)); CASIO_EXTERN int CASIO_EXPORT casio_feed_setup_mcs OF((casio_setup_t *casio__setup, int casio__id, int casio__val)); diff --git a/include/libcasio/stream.h b/include/libcasio/stream.h index 5a94c05..e9ff9e1 100644 --- a/include/libcasio/stream.h +++ b/include/libcasio/stream.h @@ -27,6 +27,7 @@ #ifndef LIBCASIO_STREAM_H # define LIBCASIO_STREAM_H # include "cdefs.h" +# include "iter.h" CASIO_BEGIN_NAMESPACE /* Forward structure declarations (don't mind). */ @@ -37,8 +38,6 @@ struct casio_streamfuncs_s; typedef struct casio_streamfuncs_s casio_streamfuncs_t; struct casio_streamattrs_s; typedef struct casio_streamattrs_s casio_streamattrs_t; -struct casio_timeouts_s; -typedef struct casio_timeouts_s casio_timeouts_t; struct casio_scsi_s; typedef struct casio_scsi_s casio_scsi_t; @@ -96,33 +95,35 @@ typedef int casio_whence_t; typedef int casio_stream_close_t OF((void *)); typedef int casio_stream_setattrs_t - OF((void *, const casio_streamattrs_t *)); -typedef int casio_stream_settm_t - OF((void *, const casio_timeouts_t *)); + OF((void *, casio_streamattrs_t const *)); typedef int casio_stream_read_t - OF((void *, unsigned char *, size_t)); + OF((void *, unsigned char *, size_t, + unsigned int /* total timeout in ms */)); typedef int casio_stream_write_t - OF((void *, const unsigned char *, size_t)); + OF((void *, unsigned char const *, size_t, + unsigned int /* total timeout in ms */)); typedef int casio_stream_seek_t OF((void *, casio_off_t *, casio_whence_t)); typedef int casio_stream_scsi_t OF((void *, casio_scsi_t*)); +typedef int casio_stream_usb_send_bulk_t + OF((void *, unsigned char const *, size_t, int /* timeout */)); +typedef int casio_stream_usb_recv_bulk_t + OF((void *, unsigned char *, size_t, int /* timeout */)); + /* Here is the callbacks structure: */ struct casio_streamfuncs_s { - /* Main callbacks. */ + casio_stream_close_t *casio_streamfuncs_close; - casio_stream_close_t *casio_streamfuncs_close; - casio_stream_settm_t *casio_streamfuncs_settm; + /* General read & write callbacks ("stream" origins). */ - /* Read & Write callbacks. */ - - casio_stream_read_t *casio_streamfuncs_read; - casio_stream_write_t *casio_streamfuncs_write; - casio_stream_seek_t *casio_streamfuncs_seek; + casio_stream_read_t *casio_streamfuncs_read; + casio_stream_write_t *casio_streamfuncs_write; + casio_stream_seek_t *casio_streamfuncs_seek; /* Serial callbacks. */ @@ -130,27 +131,14 @@ struct casio_streamfuncs_s { /* SCSI callbacks. */ - casio_stream_scsi_t *casio_streamfuncs_scsi; + casio_stream_scsi_t *casio_streamfuncs_scsi; + + /* USB callbacks. */ + + casio_stream_usb_send_bulk_t *casio_streamfuncs_usb_send_bulk; + casio_stream_usb_recv_bulk_t *casio_streamfuncs_usb_recv_bulk; }; -/* And here are some macros, for better API compatibility */ - -# define casio_stream_callbacks_for_serial(CASIO__CLOSE, CASIO__SETCOMM, \ - CASIO__SETTM, CASIO__READ, CASIO__WRITE) \ -{(casio_stream_close_t*)(CASIO__CLOSE), \ - (casio_stream_settm_t*)(CASIO__SETTM), \ - (casio_stream_read_t*)(CASIO__READ), \ - (casio_stream_write_t*)(CASIO__WRITE), NULL, \ - (casio_stream_setattrs_t*)(CASIO__SETCOMM), \ - NULL} - -# define casio_stream_callbacks_for_virtual(CASIO__CLOSE, \ - CASIO__READ, CASIO__WRITE, CASIO__SEEK) \ -{(casio_stream_close_t*)(CASIO__CLOSE), NULL, \ - (casio_stream_read_t*)(CASIO__READ), \ - (casio_stream_write_t*)(CASIO__WRITE), \ - (casio_stream_seek_t*)(CASIO__SEEK), NULL, NULL} - /* --- * Stream serial settings ad flags. * --- */ @@ -234,24 +222,6 @@ struct casio_streamattrs_s { unsigned char casio_streamattrs_cc[CASIO_NCCS]; }; -/* This structure will be sent to your `setcomm` callback to set serial - * communication settings. - * And here is the stream timeouts structure: */ - -struct casio_timeouts_s { - /* Initial read timeout */ - unsigned int casio_timeouts_read; - - /* In-between bytes read timeout */ - unsigned int casio_timeouts_read_bw; - - /* Total write timeout */ - unsigned int casio_timeouts_write; -}; - -/* This structure will be sent to your `settm` callback, usually after a state - * change in the communication. Also, all timeouts are in milliseconds (ms). */ - /* --- * SCSI requests. * --- */ @@ -305,21 +275,13 @@ CASIO_BEGIN_DECLS /* Default stream serial settings utilities. */ CASIO_EXTERN int CASIO_EXPORT casio_make_attrs - OF((casio_streamattrs_t *casio__attrs, const char *casio__raw)); - -/* List serial devices (platform agnostic). */ - -typedef void CASIO_EXPORT casio_list_com_t - OF((void *casio__cookie, const char *casio__str)); - -CASIO_EXTERN int CASIO_EXPORT casio_comlist - OF((casio_list_com_t *casio__callback, void *casio__cookie)); + OF((casio_streamattrs_t *casio__attrs, char const *casio__raw)); /* Open and close a stream. */ CASIO_EXTERN int CASIO_EXPORT casio_open_stream OF((casio_stream_t **casio__stream, casio_openmode_t mode, - void *casio__cookie, const casio_streamfuncs_t *casio__callbacks, + void *casio__cookie, casio_streamfuncs_t const *casio__callbacks, casio_off_t casio__initial_offset)); CASIO_EXTERN int CASIO_EXPORT casio_close OF((casio_stream_t *casio__stream)); @@ -349,7 +311,7 @@ CASIO_EXTERN int CASIO_EXPORT casio_isseekable CASIO_EXTERN casio_openmode_t CASIO_EXPORT casio_get_openmode OF((casio_stream_t *casio__stream)); -CASIO_EXTERN const casio_streamfuncs_t* CASIO_EXPORT casio_get_streamfuncs +CASIO_EXTERN casio_streamfuncs_t const* CASIO_EXPORT casio_get_streamfuncs OF((casio_stream_t *casio__stream)); CASIO_EXTERN void* CASIO_EXPORT casio_get_cookie @@ -357,17 +319,21 @@ CASIO_EXTERN void* CASIO_EXPORT casio_get_cookie CASIO_EXTERN int CASIO_EXPORT casio_get_lasterr OF((casio_stream_t *casio__stream)); -/* Read and write data from and to a stream. */ +/* Read and write data from and to a stream. + * Timeouts are in milliseconds (ms). */ CASIO_EXTERN int CASIO_EXPORT casio_read OF((casio_stream_t *casio__stream, - void *casio__dest, size_t casio__size)); + void *casio__dest, size_t casio__size, + unsigned int casio__timeout)); CASIO_EXTERN int CASIO_EXPORT casio_write OF((casio_stream_t *casio__stream, - const void *casio__data, size_t casio__size)); + void const *casio__data, size_t casio__size, + unsigned int casio__timeout)); CASIO_EXTERN int CASIO_EXPORT casio_write_char - OF((casio_stream_t *casio__stream, int casio__char)); + OF((casio_stream_t *casio__stream, int casio__char, + unsigned int casio__timeout)); /* Skip bytes from a stream. */ @@ -388,11 +354,6 @@ CASIO_EXTERN int CASIO_EXPORT casio_get_attrs CASIO_EXTERN int CASIO_EXPORT casio_init_timeouts OF((casio_stream_t *casio__stream)); -CASIO_EXTERN int CASIO_EXPORT casio_set_timeouts - OF((casio_stream_t *casio__stream, - const casio_timeouts_t *casio__timeouts)); -CASIO_EXTERN int CASIO_EXPORT casio_get_timeouts - OF((casio_stream_t *casio__stream, casio_timeouts_t *casio__timeouts)); /* Move in a file. */ @@ -416,7 +377,7 @@ CASIO_EXTERN int CASIO_EXPORT casio_scsi_request CASIO_EXTERN int CASIO_EXPORT casio_open_memory OF((casio_stream_t **casio__stream, - const void *casio__memory, size_t casio__size)); + void const *casio__memory, size_t casio__size)); /* Make a stream out of another, with a limit (and empty it). */ @@ -436,46 +397,71 @@ CASIO_EXTERN int CASIO_EXPORT casio_open_csum32 * USB and serial stream utilities. * --- */ -/* For platforms whose the utilities aren't built-in, here is a way to add - * your defaults, that will be used with the default functions! - * - * Communication port listing. */ +/* Make an iterator to list available serial ports. */ -typedef int CASIO_EXPORT casio_comlist_t - OF((casio_list_com_t *casio__callback, void *casio__cookie)); +CASIO_EXTERN int CASIO_EXPORT casio_iter_serial + OF((casio_iter_t **casio__iterp)); -CASIO_EXTERN int CASIO_EXPORT casio_add_default_comlist - OF((casio_comlist_t *casio__function)); +# define casio_next_serial(ITER, NEXTP) \ + casio_next((ITER), (void **)(char const **)(NEXTP)) -/* Serial communication stream opening. */ +/* Replace the default function to list serial devices. */ -typedef int casio_opencomstream_t - OF((casio_stream_t **casio__stream, const char *casio__path)); +typedef int CASIO_EXPORT casio_iter_serial_t + OF((casio_iter_t **)); -CASIO_EXTERN int CASIO_EXPORT casio_add_default_com_stream - OF((casio_opencomstream_t *casio__function)); -CASIO_EXTERN int CASIO_EXPORT casio_open_com_stream - OF((casio_stream_t **casio__stream, - const char *casio__path)); +CASIO_EXTERN int CASIO_EXPORT casio_set_iter_serial_func + OF((casio_iter_serial_t *casio__func)); -/* USB stream opening. - * The `bus` argument is set to -1 if we ought to find the first appropriate - * argument. - * The `address` argument is set to -1 if we ought to find any device on - * the given bus. */ +/* Open a serial stream. */ -typedef int CASIO_EXPORT casio_openusbstream_t - OF((casio_stream_t **casio__stream, - int casio__bus, int casio__address)); +CASIO_EXTERN int CASIO_EXPORT casio_open_serial_stream + OF((casio_stream_t **casio__stream, char const *casio__path, + casio_streamattrs_t const *casio__attributes)); + +/* Replace the default function to open a serial stream. */ + +typedef int CASIO_EXPORT casio_open_serial_stream_t + OF((casio_stream_t **casio__stream, char const *casio__path, + casio_streamattrs_t const *casio__attributes)); + +CASIO_EXTERN int CASIO_EXPORT casio_set_open_serial_stream_func + OF((casio_open_serial_stream_t *casio__func)); + +/* Make an iterator to list available USB devices. */ + +# define CASIO_USB_TYPE_UNKNOWN 0 /* Unknown type (not a calculator?) */ +# define CASIO_USB_TYPE_LEGACY 1 /* Protocol 7.00 over bulk transfers */ +# define CASIO_USB_TYPE_SCSI 2 /* Bulk-Only Transport (SCSI) and + * “Protocol 7.00” over commands C0 to C2 */ + +typedef struct casio_usb_entry_s { + int casio_usb_entry_type; /* one of `CASIO_USB_TYPE_*` */ + int casio_usb_entry_bus; + int casio_usb_entry_address; +} casio_usb_entry_t; + +CASIO_EXTERN int CASIO_EXPORT casio_iter_usb + OF((casio_iter_t **casio__iterp)); + +# define casio_next_usb(ITER, NEXTP) \ + casio_next((ITER), (void **)(casio_usb_entry_t **)(NEXTP)) + +/* Open a USB device. */ -CASIO_EXTERN int CASIO_EXPORT casio_add_default_usb_stream - OF((casio_openusbstream_t *casio__function)); CASIO_EXTERN int CASIO_EXPORT casio_open_usb_stream OF((casio_stream_t **casio__stream, int casio__bus, int casio__address)); +/* Replace the default function to open a USB stream. */ + +typedef int CASIO_EXPORT casio_open_usb_stream_t + OF((casio_stream_t **casio__stream, int casio__bus, int casio__addr)); + +CASIO_EXTERN int CASIO_EXPORT casio_set_open_usb_stream_func + OF((casio_open_usb_stream_t *casio__func)); + CASIO_END_DECLS CASIO_END_NAMESPACE -# include "builtin.h" #endif /* LIBCASIO_STREAM_H */ diff --git a/include/libcasio/version.h b/include/libcasio/version.h index 3700ba3..d779d7b 100644 --- a/include/libcasio/version.h +++ b/include/libcasio/version.h @@ -73,11 +73,11 @@ CASIO_BEGIN_DECLS * and to decode/encode a version. */ CASIO_EXTERN int CASIO_EXPORT casio_check_version - OF((const char *casio__raw)); + OF((char const *casio__raw)); CASIO_EXTERN int CASIO_EXPORT casio_decode_version - OF((casio_version_t *casio__version, const char *casio__raw)); + OF((casio_version_t *casio__version, char const *casio__raw)); CASIO_EXTERN int CASIO_EXPORT casio_encode_version - OF((char *casio__raw, const casio_version_t *casio__version)); + OF((char *casio__raw, casio_version_t const *casio__version)); CASIO_END_DECLS CASIO_END_NAMESPACE diff --git a/lib/comlist/builtin/linux.c b/lib/comlist/builtin/linux.c deleted file mode 100644 index d15b92c..0000000 --- a/lib/comlist/builtin/linux.c +++ /dev/null @@ -1,78 +0,0 @@ -/* **************************************************************************** - * comlist/builtin/linux.c -- find out Linux serial devices. - * Copyright (C) 2016-2017 Thomas "Cakeisalie5" Touhey - * - * This file is part of libcasio. - * libcasio 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.0 of the License, - * or (at your option) any later version. - * - * libcasio 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libcasio; if not, see . - * ************************************************************************* */ -#include "../../internals.h" -#ifdef __linux__ -# include -# include -# include -# include -# include - -/** - * casio_comlist_linux: - * List serial devices under Linux. - * - * Links in the /dev/serial/by-id/ should resolve to relative paths, but - * I also managed absolute paths, in case. - * - * @arg callback the callback. - * @arg cookie the cookie. - * @return the error. - */ - -int CASIO_EXPORT casio_comlist_linux(casio_list_com_t *callback, void *cookie) -{ - char path[PATH_MAX + 1], devname[PATH_MAX + 1], *f, *p; - DIR *d; struct dirent *dr; struct stat st; - ssize_t rl; - - /* open the thing */ - strcpy(path, "/dev/serial/by-id/"); - d = opendir(path); if (!d) return (casio_error_unknown); - - /* prepare */ - f = strchr(path, 0); - - /* read the entries */ - while ((dr = readdir(d))) { - /* check type */ - strcpy(f, dr->d_name); - if (lstat(path, &st) || (st.st_mode & S_IFMT) != S_IFLNK) - continue; - - /* get destination path and send it */ - rl = readlink(path, devname, PATH_MAX + 1); - if (rl < 0) continue; - devname[rl] = 0; - if (devname[0] == '/') - (*callback)(cookie, devname); - else { - strcpy(f, devname); - p = realpath(path, devname); - if (!p) continue; - (*callback)(cookie, p); - } - } - - /* close the dir and we're done listing */ - closedir(d); - return (0); -} - -# endif /* __linux__ */ diff --git a/lib/comlist/builtin/macos.c b/lib/comlist/builtin/macos.c deleted file mode 100644 index cb05262..0000000 --- a/lib/comlist/builtin/macos.c +++ /dev/null @@ -1,61 +0,0 @@ -/* **************************************************************************** - * comlist/builtin/macos.c -- find out MacOS/OS X serial devices. - * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey - * - * This file is part of libcasio. - * libcasio 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.0 of the License, - * or (at your option) any later version. - * - * libcasio 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libcasio; if not, see . - * ************************************************************************* */ -#include "../../internals.h" -#if defined(__APPLE__) && defined(__MACH__) -# include - -/** - * casio_comlist_macos: - * List serial devices under MacOS/OS X. - * - * @arg callback the callback. - * @arg cookie the cookie. - * @return the error. - */ - -int CASIO_EXPORT casio_comlist_macos(casio_list_com_t *callback, void *cookie) -{ - char path[PATH_MAX + 1], *f; DIR *d; - struct dirent *dr; - - /* prepare the folder */ - strcpy(path, "/dev/"); - f = strchr(path, 0); - - /* open the directory */ - d = opendir(path); - if (!d) return (casio_error_unknown); - - /* read the entries */ - while ((dr = readdir(d))) { - /* check name */ - if (strncmp(dr->d_name, "cu.", 3)) - continue; - - /* copy and set to the user */ - strcpy(f, dr->d_name); - (*callback)(cookie, path); - } - - /* close the dir and we're done listing */ - closedir(d); - return (0); -} - -#endif /* __APPLE__, __MACH__ */ diff --git a/lib/comlist/builtin/windows.c b/lib/comlist/builtin/windows.c deleted file mode 100644 index 203ba25..0000000 --- a/lib/comlist/builtin/windows.c +++ /dev/null @@ -1,92 +0,0 @@ -/* **************************************************************************** - * comlist/builtin/windows.c -- find out serial devices on MS-Windows. - * Copyright (C) 2016-2017 Thomas "Cakeisalie5" Touhey - * - * This file is part of libcasio. - * libcasio 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.0 of the License, - * or (at your option) any later version. - * - * libcasio 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libcasio; if not, see . - * ************************************************************************* */ -#include "../../internals.h" -#ifdef __WINDOWS__ -/* only works because I redefined the version at the beginning - * of `internals.h`! */ -# include -# include -# include -# include - -/** - * casio_comlist_windows: - * List serial devices under MS-Windows. - * - * I'm using the source from Python 3.x's winreg module source and the MSDN - * documentation. - * - * @arg callback the callback to which to send the path. - * @arg cookie the cookie to pass to the callback. - * @return the error code (0 if ok). - */ - -int CASIO_EXPORT casio_comlist_windows(casio_list_com_t callback, void *cookie) -{ - DWORD werr, i, type, valsize, curval, datasize, curdata; - HKEY hkey; int hkey_open = 0; - char *value = NULL, *data = NULL; - - /* read the registry key */ - msg((ll_info, - "Opening HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM")); - werr = RegOpenKey(HKEY_LOCAL_MACHINE, - "HARDWARE\\DEVICEMAP\\SERIALCOMM", &hkey); - if (werr) goto fail; - hkey_open = 1; - - /* prepare */ - msg((ll_info, "Allocating enough space")); - valsize = 1024; datasize = 1024; /* I DON'T CARE IT WORKS LALALA */ - if (!(value = casio_alloc(valsize, 1)) - || !(data = casio_alloc(datasize, 1))) - goto fail; - - /* enumerate values */ - msg((ll_info, "Enumerating values")); - curval = valsize; - curdata = datasize; - for (i = 0; (werr = RegEnumValue(hkey, i, value, &curval, NULL, - &type, (BYTE*)data, &curdata)) != ERROR_NO_MORE_ITEMS; i++) { - if (type != REG_SZ) - continue; - if (werr == ERROR_MORE_DATA) { - msg((ll_error, "data not big enough, o shit waddap")); - goto fail; - } - - (*callback)(cookie, data); - curval = valsize; - curdata = datasize; - } - - /* error is `ERROR_MORE_DATA`, o ship shaddap */ - werr = 0; -fail: - ifmsg(werr, (ll_error, "Got error %08lu", werr)) - - /* Free, close the key and return ! */ - casio_free(value); - casio_free(data); - if (hkey_open) - RegCloseKey(hkey); - return (werr ? casio_error_unknown : 0); -} - -#endif /* __WINDOWS__ */ diff --git a/lib/comlist/comlist.c b/lib/comlist/comlist.c deleted file mode 100644 index ef699d2..0000000 --- a/lib/comlist/comlist.c +++ /dev/null @@ -1,84 +0,0 @@ -/* **************************************************************************** - * comlist/builtin.c -- find out serial devices. - * Copyright (C) 2016-2017 Thomas "Cakeisalie5" Touhey - * - * This file is part of libcasio. - * libcasio 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.0 of the License, - * or (at your option) any later version. - * - * libcasio 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libcasio; if not, see . - * ************************************************************************* */ -#include "../internals.h" -#define NUM 5 - -/* Correspondance type. */ -struct corresp { - int _valid; - casio_comlist_t *_comlist; -}; - -/* List of com listing functions. */ -CASIO_LOCAL struct corresp comlists[NUM + 1] = { -#if defined(__linux__) - {1, casio_comlist_linux}, -#elif defined(__WINDOWS__) - {1, casio_comlist_windows}, -#elif defined(__APPLE__) && defined(__MACH__) - {1, casio_comlist_macos}, -#endif - {0, NULL} -}; - -/** - * casio_add_default_comlist: - * Add a default `comlist` function. - * - * @arg callback the callback. - * @return the error code (0 if ok). - */ - -int CASIO_EXPORT casio_add_default_comlist(casio_comlist_t *function) -{ - struct corresp *c; int num; - - for (c = comlists, num = NUM; c->_valid && num; c++, num--); - if (!num) return (casio_error_op); - - c->_valid = 1; - c->_comlist = function; - return (0); -} - -/** - * casio_comlist: - * List the communication ports. - * - * @arg callback the callback. - * @arg cookie the cookie. - * @return the error (if any). - */ - -int CASIO_EXPORT casio_comlist(casio_list_com_t callback, void *cookie) -{ - int err; struct corresp *c = comlists; - - if (!c->_valid) - return (casio_error_op); - for (; c->_valid; c++) { - err = (*c->_comlist)(callback, cookie); - - if (!err) return (0); - if (err != casio_error_nocalc) - return (err); - } - - return (casio_error_nocalc); -} diff --git a/lib/errors.c b/lib/errors.c index 928f696..fd565f8 100644 --- a/lib/errors.c +++ b/lib/errors.c @@ -39,7 +39,9 @@ const char* CASIO_EXPORT casio_error_strings[128] = { "a timeout has occurred", "could not get access to the device", "an end of file event has occured", - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "a SCSI operation on the stream has failed", + "a USB operation on the stream has failed", + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/lib/file/file.h b/lib/file/file.h index f818d3d..0cfc56f 100644 --- a/lib/file/file.h +++ b/lib/file/file.h @@ -28,12 +28,12 @@ /* Read from a stream. */ # define READ(CASIO__TO, CASIO__SZ) /* normal read */ { \ - int READ_err = casio_read(buffer, (CASIO__TO), (CASIO__SZ)); \ + int READ_err = casio_read(buffer, (CASIO__TO), (CASIO__SZ), 0); \ if (READ_err) return (READ_err); } # define FREAD(CASIO__TO, CASIO__SZ) /* fail-less read */ \ - err = casio_read(buffer, (CASIO__TO), (CASIO__SZ)); + err = casio_read(buffer, (CASIO__TO), (CASIO__SZ), 0); # define GREAD(CASIO__TO, CASIO__SZ) /* read with goto fail */ \ - if ((err = casio_read(buffer, (CASIO__TO), (CASIO__SZ)))) \ + if ((err = casio_read(buffer, (CASIO__TO), (CASIO__SZ), 0))) \ goto fail; /* Read using size of the object. */ diff --git a/lib/internals.h b/lib/internals.h index 2823301..717db44 100644 --- a/lib/internals.h +++ b/lib/internals.h @@ -17,7 +17,7 @@ * along with libcasio; if not, see . * ************************************************************************* */ #ifndef LOCAL_INTERNALS_H -# define LOCAL_INTERNALS_H 1 +# define LOCAL_INTERNALS_H 2018051701 # define _DEFAULT_SOURCE /* XXX: glibc hacking */ # define _POSIX_C_SOURCE 199309L # include @@ -29,13 +29,19 @@ # include "utils/endian.h" # include "log/log.h" +/* --- + * Platform-specific stuff. + * --- */ + /* MS-Windows stuff */ + # if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) \ && !defined(__WINDOWS__) # define __WINDOWS__ # endif /* Standard library macros. */ + # ifndef min # define min(CASIO__A, CASIO__B) \ ((CASIO__A) < (CASIO__B) ? (CASIO__A) : (CASIO__B)) @@ -49,6 +55,41 @@ ((CASIO__A) < 0 ? -(CASIO__A) : (CASIO__A)) # endif +/* --- + * Built-in streams. + * --- */ + +/* Make a stream using the standard FILE interface. */ + +# ifndef LIBCASIO_DISABLED_FILE +CASIO_EXTERN int CASIO_EXPORT casio_open_stream_file + OF((casio_stream_t **casio__stream, + FILE *casio__readstream, FILE *casio__writestream, + int casio__close_readstream, int casio__close_writestream)); +# endif + +/* --- + * Built-in filesystems. + * --- */ + +/* Make a POSIX filesystem interface. */ + +# ifndef LIBCASIO_DISABLED_STREAMS +CASIO_EXTERN int CASIO_EXPORT casio_open_posix_fs + OF((casio_fs_t **casio__filesystem)); +# endif + +/* Make a Windows API filesystem interface. */ + +# ifndef LIBCASIO_DISABLED_WINDOWS +CASIO_EXTERN int CASIO_EXPORT casio_open_windows_fs + OF((casio_fs_t **casio__filesystem)); +# endif + +/* --- + * Various. + * --- */ + /* Checksum. */ extern int casio_checksum_cas OF((void *casio__mem, diff --git a/lib/utils/iter.c b/lib/iter/iter.c similarity index 97% rename from lib/utils/iter.c rename to lib/iter/iter.c index 7054bce..5e83de0 100644 --- a/lib/utils/iter.c +++ b/lib/iter/iter.c @@ -1,5 +1,5 @@ /* **************************************************************************** - * utils/iter.c -- iterator internals. + * iter/iter.c -- iterator internals. * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey * * This file is part of libcasio. @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with libcasio; if not, see . * ************************************************************************* */ -#include +#include "../internals.h" /* Internal structure of an iterator. */ diff --git a/lib/iter/super.c b/lib/iter/super.c new file mode 100644 index 0000000..57c8742 --- /dev/null +++ b/lib/iter/super.c @@ -0,0 +1,96 @@ +/* **************************************************************************** + * iter/super.c -- super-iterator, for super-iterating. + * Copyright (C) 2018 Thomas "Cakeisalie5" Touhey + * + * This file is part of libcasio. + * libcasio 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.0 of the License, + * or (at your option) any later version. + * + * libcasio 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libcasio; if not, see . + * ************************************************************************* */ +#include "../internals.h" + +typedef struct { + int i, len; + casio_iter_t *its[2]; +} supercookie_t; + +/* `next_super()`: next element from the super iterator. */ + +CASIO_LOCAL int next_super(supercookie_t *cookie, void **ptr) +{ + int err; + + if (cookie->i == cookie->len) + return (casio_error_iter); + + while (cookie->i < cookie->len - 1) { + if ((err = casio_next(cookie->its[cookie->i], ptr)) + != casio_error_iter) + return (err); + + casio_end(cookie->its[cookie->i++]); + } + + if ((err = casio_next(cookie->its[cookie->i], ptr)) != casio_error_iter) + return (err); + + casio_end(cookie->its[cookie->i++]); + return (casio_error_iter); +} + +/* `end_super()`: end the super-iterator. */ + +CASIO_LOCAL void end_super(supercookie_t *cookie) +{ + int i; + + for (i = cookie->i; i < cookie->len; i++) + casio_end(cookie->its[i]); + free(cookie); +} + +/* Callbacks. */ + +CASIO_LOCAL casio_iter_funcs_t const super_funcs = { + (casio_next_t *)next_super, + NULL, + (casio_end_t *)end_super +}; + +/** + * casio_combine_iterator: + * Make a super iterator. + * + * @arg iterp the super-iterator to create. + * @arg first the first iterator to put into the super-iterator. + * @arg second the second one. + * @return the error code (0 if ok). + */ + +int CASIO_EXPORT casio_combine_iterators(casio_iter_t **iterp, + casio_iter_t *first, casio_iter_t *second) +{ + supercookie_t *cookie; + + if (!(cookie = malloc(sizeof(supercookie_t)))) { + casio_end(first); + casio_end(second); + return (casio_error_alloc); + } + + cookie->len = 2; + cookie->i = 0; + cookie->its[0] = first; + cookie->its[1] = second; + + return (casio_iter(iterp, cookie, &super_funcs)); +} diff --git a/lib/link/open.c b/lib/link/open.c index d95bdbe..105b69b 100644 --- a/lib/link/open.c +++ b/lib/link/open.c @@ -30,12 +30,11 @@ * @arg h the handle to create * @arg flags the flags. * @arg stream the stream to use. - * @arg settings the stream settings to use. * @return the error (0 if ok) */ int CASIO_EXPORT casio_open_link(casio_link_t **h, unsigned long flags, - casio_stream_t *stream, const casio_streamattrs_t *settings) + casio_stream_t *stream) { int err = 0; casio_link_t *handle; @@ -77,14 +76,6 @@ int CASIO_EXPORT casio_open_link(casio_link_t **h, unsigned long flags, msg((ll_info, "[Options] Terminate: %s", flags & CASIO_LINKFLAG_TERM ? "yes" : "no")); - /* Set communication properties. */ - - msg((ll_info, "Initializing stream settings.")); - if (!settings) - casio_init_attrs(handle->casio_link_stream); - else - casio_set_attrs(handle->casio_link_stream, settings); - /* If active, start. */ err = casio_seven_start(handle); diff --git a/lib/link/open/com.c b/lib/link/open/com.c index 5522f55..6d7db84 100644 --- a/lib/link/open/com.c +++ b/lib/link/open/com.c @@ -19,7 +19,7 @@ #include "../link.h" /** - * casio_open_com: + * casio_open_serial: * Open a serial communication. * * @arg handle the link handle to make. @@ -29,8 +29,8 @@ * @return the error code (0 if ok). */ -int CASIO_EXPORT casio_open_com(casio_link_t **handle, unsigned long flags, - const char *path, const casio_streamattrs_t *attrs) +int CASIO_EXPORT casio_open_serial(casio_link_t **handle, unsigned long flags, + char const *path, casio_streamattrs_t const *attrs) { int err, failed = 0, tries = 3; casio_stream_t *stream; @@ -43,7 +43,7 @@ int CASIO_EXPORT casio_open_com(casio_link_t **handle, unsigned long flags, casio_sleep(1000); } - err = casio_open_com_stream(&stream, path); + err = casio_open_serial_stream(&stream, path, attrs); if (err == casio_error_op) return (casio_error_nocalc); if (!err) @@ -57,7 +57,7 @@ int CASIO_EXPORT casio_open_com(casio_link_t **handle, unsigned long flags, failed = 1; } - err = casio_open_link(handle, flags, stream, attrs); + err = casio_open_link(handle, flags, stream); if (err) return (err); diff --git a/lib/link/open/usb.c b/lib/link/open/usb.c index e5bb101..c1cbc74 100644 --- a/lib/link/open/usb.c +++ b/lib/link/open/usb.c @@ -77,9 +77,5 @@ int CASIO_EXPORT casio_open_usb(casio_link_t **handle, unsigned long flags, /* Open the link based on the stream. */ - err = casio_open_link(handle, flags, stream, NULL); - if (err) - return (err); - - return (0); + return (casio_open_link(handle, flags, stream)); } diff --git a/lib/link/seven/dataflow.c b/lib/link/seven/dataflow.c index 3286976..fb80714 100644 --- a/lib/link/seven/dataflow.c +++ b/lib/link/seven/dataflow.c @@ -64,8 +64,8 @@ int CASIO_EXPORT casio_seven_send_buffer(casio_link_t *handle, /* Read the big block. */ toread = min(BUFSIZE, size); - err = casio_read(buffer, buf + 8, toread); - if (err) return (casio_error_noread); + if ((err = casio_read(buffer, buf + 8, toread, 0))) + return (casio_error_noread); size -= toread; /* Send each block. */ @@ -165,11 +165,15 @@ int CASIO_EXPORT casio_seven_get_buffer(casio_link_t *handle, msg((ll_info, "buffer too full, should be emptied")); /* Empty the buffer in the stream. */ - buf_err = casio_write(buffer, buf, ps); - if (buf_err) { err = casio_error_nowrite; goto fail; } + + if ((buf_err = casio_write(buffer, buf, ps, 0))) { + err = casio_error_nowrite; + goto fail; + } /* Reset the pointer. */ - p = buf; ps = 0; + p = buf; + ps = 0; } } diff --git a/lib/link/seven/datastream.c b/lib/link/seven/datastream.c index 2ffc850..760b830 100644 --- a/lib/link/seven/datastream.c +++ b/lib/link/seven/datastream.c @@ -51,16 +51,19 @@ typedef struct { * @arg cookie the cookie. * @arg data the data to read. * @arg size the size of the data to read. + * @arg timeout the timeout (ignored). * @return the error code (0 if ok). */ CASIO_LOCAL int casio_seven_data_read(seven_data_cookie_t *cookie, - unsigned char *data, size_t size) + unsigned char *data, size_t size, unsigned int timeout) { int err; size_t tocopy; casio_link_t *handle = cookie->_link; unsigned int lastsize; + (void)timeout; + /* Check if the stream is faulty. */ if (cookie->_faulty) return (casio_error_noread); @@ -139,15 +142,18 @@ fail: * @arg cookie the cookie. * @arg data the data to write. * @arg size the size of the data to write. + * @arg timeout the timeout (ignored). * @return the error code (0 if ok). */ CASIO_LOCAL int casio_seven_data_write(seven_data_cookie_t *cookie, - const unsigned char *data, size_t size) + const unsigned char *data, size_t size, unsigned int timeout) { int err; size_t tocopy, lastlimit; casio_link_t *handle = cookie->_link; + (void)timeout; + /* Check if the stream is faulty, or if we have already finished. */ if (cookie->_faulty) return (casio_error_nowrite); @@ -279,11 +285,11 @@ CASIO_LOCAL int casio_seven_data_close(seven_data_cookie_t *cookie) * go directly to the end. */ memset(zeroes, 0, BUFSIZE); for (; left >= BUFSIZE; left -= BUFSIZE) { - if ((err = casio_seven_data_write(cookie, zeroes, BUFSIZE))) + if ((err = casio_seven_data_write(cookie, zeroes, BUFSIZE, 0))) goto fail; } - err = casio_seven_data_write(cookie, zeroes, left); + err = casio_seven_data_write(cookie, zeroes, left, 0); } err = 0; @@ -296,9 +302,13 @@ fail: * Opening functions. * --- */ -CASIO_LOCAL const casio_streamfuncs_t seven_data_callbacks = -casio_stream_callbacks_for_virtual(casio_seven_data_close, - casio_seven_data_read, casio_seven_data_write, NULL); +CASIO_LOCAL const casio_streamfuncs_t seven_data_callbacks = { + (casio_stream_close_t *)casio_seven_data_close, + (casio_stream_read_t *)casio_seven_data_read, + (casio_stream_write_t *)casio_seven_data_write, + + NULL, NULL, NULL, NULL, NULL +}; /** * casio_seven_open_data_stream: diff --git a/lib/link/seven/eack.c b/lib/link/seven/eack.c index afbb6fd..dc3ed9a 100644 --- a/lib/link/seven/eack.c +++ b/lib/link/seven/eack.c @@ -23,41 +23,45 @@ * Raw layout of an extended ack data. * --- */ +/* `hwid`: hardware identifier (ASCII); + * `cpuid`: processor identifier (ASCII); + * + * `preprog_rom_capacity`: preprogrammed ROM capacity (ASCII-DEC, KiB); + * `flash_rom_capacity`: flash ROM capacity (ASCII-DEC, KiB); + * `ram_capacity`: RAM capacity (ASCII-DEC, KiB); + * + * `preprog_rom_version`: preprogrammed ROM version. + * `bootcode_version`: bootcode version. + * `bootcode_offset`: bootcode offset (ASCII-HEX); + * `bootcode_size`: bootcode size (ASCII-HEX, KiB); + * `os_version`: OS version; + * `os_offset`: OS offset; + * `os_size`: OS size (ASCII-HEX, KiB); + * + * `protocol_version`: protocol version (x.xx, generally "7.00"); + * `product_id`: product ID; + * `username`: name set by the user in SYSTEM (Oxffs if in exam mode). + * + * Versions are coded as "xx.xx.xxxx" + 0xff bytes. */ + typedef struct { - /* hardware identifier - ASCII */ unsigned char hwid[8]; - /* processor identifier - ASCII */ unsigned char cpuid[16]; - /* preprogrammed ROM capacity - ASCII-dec (Ko) */ unsigned char preprog_rom_capacity[8]; - /* flash ROM capacity - ASCII-dec (Ko) */ unsigned char flash_rom_capacity[8]; - /* RAM capacity - ASCII-dec (Ko) */ unsigned char ram_capacity[8]; - /* preprogrammed ROM version - "xx.xx.xxxx" + 0xff bytes */ unsigned char preprog_rom_version[16]; - - /* bootcode version - "xx.xx.xxxx" + 0xff bytes */ unsigned char bootcode_version[16]; - /* bootcode offset - ASCII-hex */ unsigned char bootcode_offset[8]; - /* bootcode size - ASCII-hex (Ko) */ unsigned char bootcode_size[8]; - - /* OS version - "xx.xx.xxxx" + 0xff bytes */ unsigned char os_version[16]; - /* OS offset - ASCII-hex */ unsigned char os_offset[8]; - /* OS size - ASCII-hex (Ko) */ unsigned char os_size[8]; - /* protocol version - "x.xx" */ unsigned char protocol_version[4]; - /* product ID */ unsigned char product_id[16]; - /* name set by user in SYSTEM (if not in exam mode) */ unsigned char username[16]; } packetdata_ackext_t; @@ -75,7 +79,8 @@ typedef struct { * @arg data the raw version data ("xx.xx.xx" + type) */ -CASIO_LOCAL void version_of_string(casio_version_t *ver, const unsigned char *data) +CASIO_LOCAL void version_of_string(casio_version_t *ver, + unsigned char const *data) { casio_decode_version(ver, (const char*)data); } @@ -89,9 +94,9 @@ CASIO_LOCAL void version_of_string(casio_version_t *ver, const unsigned char *da */ CASIO_LOCAL void string_of_version(unsigned char *data, - const casio_version_t *ver) + casio_version_t const *ver) { - casio_encode_version((char*)data, ver); + casio_encode_version((char *)data, ver); memset(&data[10], '\xFF', 6); } @@ -113,16 +118,18 @@ int CASIO_EXPORT casio_seven_send_eack(casio_link_t *handle, { packetdata_ackext_t raw; - /* initialize the structure with 0xFFs */ + /* Initialize the structure with 0xFFs. */ + memset(&raw, 0xFF, sizeof(packetdata_ackext_t)); - /* put in the structure */ + /* Put in the structure. */ + memcpy(raw.hwid, info->casio_link_info_hwid, strnlen(info->casio_link_info_hwid, 8)); memcpy(raw.cpuid, info->casio_link_info_cpuid, strnlen(info->casio_link_info_cpuid, 16)); - if (!(info->casio_link_info_wiped & casio_link_info_wiped_preprog)) { + if (info->casio_link_info_flags & casio_link_info_flag_preprog) { casio_putascii(raw.preprog_rom_capacity, info->casio_link_info_rom_capacity, 8); string_of_version(raw.preprog_rom_version, @@ -134,7 +141,7 @@ int CASIO_EXPORT casio_seven_send_eack(casio_link_t *handle, casio_putascii(raw.ram_capacity, casio_gethex(info->casio_link_info_ram_capacity / 1024), 8); - if (!(info->casio_link_info_wiped & casio_link_info_wiped_bootcode)) { + if (info->casio_link_info_flags & casio_link_info_flag_bootcode) { string_of_version(raw.bootcode_version, &info->casio_link_info_bootcode_version); casio_putascii(raw.bootcode_offset, @@ -143,7 +150,7 @@ int CASIO_EXPORT casio_seven_send_eack(casio_link_t *handle, casio_gethex(info->casio_link_info_bootcode_size / 1024), 8); } - if (!(info->casio_link_info_wiped & casio_link_info_wiped_os)) { + if (info->casio_link_info_flags & casio_link_info_flag_os) { string_of_version(raw.os_version, &info->casio_link_info_os_version); casio_putascii(raw.os_offset, info->casio_link_info_os_offset, 8); casio_putascii(raw.os_size, @@ -156,7 +163,8 @@ int CASIO_EXPORT casio_seven_send_eack(casio_link_t *handle, memcpy(raw.username, info->casio_link_info_username, strnlen(info->casio_link_info_username, 16)); - /* send the packet */ + /* Send the packet. */ + return (casio_seven_send_ext(handle, casio_seven_type_ack, 0x02, &raw, sizeof(packetdata_ackext_t), 1)); } @@ -201,94 +209,97 @@ int CASIO_EXPORT casio_seven_decode_ack(casio_link_t *handle, casio_link_info_t *info = &packet->casio_seven_packet_info; const packetdata_ackext_t *d = (const void*)data; - /* check the data size */ - if (data_size != sizeof(packetdata_ackext_t)) return (1); - info->casio_link_info_wiped = 0; + /* Check the data size. */ - /* log */ msg((ll_info, "ack packet is extended")); - /* hardware identifier */ + if (data_size != sizeof(packetdata_ackext_t)) { + msg((ll_warn, "eack extension is of invalid size?")); + return (1); + } + + info->casio_link_info_flags = 0; + + /* Hardware identifier, processor identifier. */ + cpy_string(info->casio_link_info_hwid, (const char*)d->hwid, 8); - msg((ll_info, "hardware identifier is '%s'", info->casio_link_info_hwid)); - /* processor identifier */ cpy_string(info->casio_link_info_cpuid, (const char*)d->cpuid, 16); + + msg((ll_info, "hardware identifier is '%s'", info->casio_link_info_hwid)); msg((ll_info, "cpu identifier is '%s'", info->casio_link_info_cpuid)); - /* preprogrammed ROM information is wiped */ - if (d->preprog_rom_version[2] == 0xFF) - info->casio_link_info_wiped |= casio_link_info_wiped_preprog; - ifmsg(info->casio_link_info_wiped & casio_link_info_wiped_preprog, - (ll_info, "Preprogrammed ROM information looks wiped out!")) - elsemsg((ll_info, "Preprogrammed ROM version is %.10s", - d->preprog_rom_version)) + /* Preprogrammed ROM information (valid, capacity, version). */ - /* preprogrammed ROM capacity */ info->casio_link_info_rom_capacity = casio_getascii(d->preprog_rom_capacity, 8) * 1000; - msg((ll_info, "preprogrammed ROM capacity is %luo", - info->casio_link_info_rom_capacity)); - /* preprogrammed ROM version */ version_of_string(&info->casio_link_info_rom_version, d->preprog_rom_version); - /* flash ROM capacity */ + if (d->preprog_rom_version[2] != 0xFF) { + info->casio_link_info_flags |= casio_link_info_flag_preprog; + + msg((ll_info, "preprogrammed ROM capacity is %luo", + info->casio_link_info_rom_capacity)); + msg((ll_info, "Preprogrammed ROM version is %.10s", + d->preprog_rom_version)); + } elsemsg((ll_info, "Preprogrammed ROM information looks wiped out!")) + + /* Flash ROM and RAM capacities. */ + info->casio_link_info_flash_rom_capacity = casio_getdec(casio_getascii(d->flash_rom_capacity, 8)) * 1024; - msg((ll_info, "flash ROM capacity is %luKiB", - info->casio_link_info_flash_rom_capacity / 1024)); - /* RAM capacity */ info->casio_link_info_ram_capacity = casio_getdec(casio_getascii(d->ram_capacity, 8)) * 1024; + + msg((ll_info, "flash ROM capacity is %luKiB", + info->casio_link_info_flash_rom_capacity / 1024)); msg((ll_info, "RAM capacity is %luKiB", info->casio_link_info_ram_capacity / 1024)); - /* bootcode information is wiped */ - if (d->bootcode_version[2] == 0xFF) - info->casio_link_info_wiped |= casio_link_info_wiped_bootcode; - ifmsg(info->casio_link_info_wiped & casio_link_info_wiped_bootcode, - (ll_info, "Bootcode information looks wiped out!")) - elsemsg((ll_info, "Bootcode version is %.10s", d->bootcode_version)) + /* Bootcode information (valid, offset, size, version). */ - /* bootcode version */ version_of_string(&info->casio_link_info_bootcode_version, d->bootcode_version); - /* bootcode offset */ info->casio_link_info_bootcode_offset = casio_getascii(d->bootcode_offset, 8); - msg((ll_info, "bootcode offset is 0x%08lX", - info->casio_link_info_bootcode_offset)); - /* bootcode size */ info->casio_link_info_bootcode_size = casio_getdec(casio_getascii(d->bootcode_size, 8)) * 1024; - msg((ll_info, "bootcode size is %luKiB", - info->casio_link_info_bootcode_size / 1024)); - /* OS information is wiped */ - if (d->os_version[2] == 0xFF) - info->casio_link_info_wiped |= casio_link_info_wiped_os; - ifmsg(info->casio_link_info_wiped & casio_link_info_wiped_os, - (ll_info, "OS information looks wiped out!")) - elsemsg((ll_info, "OS version is %.10s", d->os_version)) + if (d->bootcode_version[2] != 0xFF) { + info->casio_link_info_flags |= casio_link_info_flag_bootcode; + + msg((ll_info, "Bootcode version is %.10s", d->bootcode_version)); + msg((ll_info, "bootcode offset is 0x%08lX", + info->casio_link_info_bootcode_offset)); + msg((ll_info, "bootcode size is %luKiB", + info->casio_link_info_bootcode_size / 1024)); + } elsemsg((ll_info, "Bootcode information looks wiped out!")) + + /* OS information (valid, offset, size, version). */ - /* OS version */ version_of_string(&info->casio_link_info_os_version, d->os_version); - /* OS offset */ info->casio_link_info_os_offset = casio_getascii(d->os_offset, 8); - msg((ll_info, "OS offset is 0x%08lX" , info->casio_link_info_os_offset)); - /* OS size */ info->casio_link_info_os_size = casio_getdec(casio_getascii(d->os_size, 8)) * 1024; - msg((ll_info, "OS size is %luKiB", info->casio_link_info_os_size / 1024)); - /* product ID */ + if (d->os_version[2] != 0xFF) { + info->casio_link_info_flags |= casio_link_info_flag_os; + + msg((ll_info, "OS version is %.10s", d->os_version)); + msg((ll_info, "OS offset is 0x%08lX" , + info->casio_link_info_os_offset)); + msg((ll_info, "OS size is %luKiB", + info->casio_link_info_os_size / 1024)); + } elsemsg((ll_info, "OS information looks wiped out!")) + + /* Product ID and username. */ + cpy_string(info->casio_link_info_product_id, (const char*)d->product_id, 16); - msg((ll_info, "product ID is %s", info->casio_link_info_product_id)); - /* username */ cpy_string(info->casio_link_info_username, (const char*)d->username, 16); + + msg((ll_info, "product ID is %s", info->casio_link_info_product_id)); msg((ll_info, "username is %s", info->casio_link_info_username)); - /* no error */ return (0); } diff --git a/lib/link/seven/receive.c b/lib/link/seven/receive.c index 109bf19..855dd0d 100644 --- a/lib/link/seven/receive.c +++ b/lib/link/seven/receive.c @@ -176,7 +176,7 @@ CASIO_LOCAL const char *gettermstring(casio_seven_term_t code) #define buffer handle->casio_link_recv_buffer #define COMPLETE_PACKET(N) { \ int COMP_PACKET_err = casio_read(handle->casio_link_stream, \ - &buffer[received], (size_t)(N)); \ + &buffer[received], (size_t)(N), 0); \ received += (N); if (COMP_PACKET_err) return (COMP_PACKET_err); } CASIO_LOCAL int casio_seven_decode(casio_link_t *handle, int scralign) diff --git a/lib/link/seven/scsi.c b/lib/link/seven/scsi.c index fd3dfff..c017f6c 100644 --- a/lib/link/seven/scsi.c +++ b/lib/link/seven/scsi.c @@ -84,10 +84,14 @@ typedef struct { * --- */ CASIO_LOCAL int seven_scsi_read(seven_scsi_cookie_t *cookie, - unsigned char *buffer, size_t size) + unsigned char *buffer, size_t size, unsigned int timeout) { casio_scsi_t scsi; int err; + /* FIXME: use the timeout! */ + + (void)timeout; + /* Empty what's already in the buffer. */ if (cookie->left) { @@ -197,74 +201,105 @@ CASIO_LOCAL int seven_scsi_read(seven_scsi_cookie_t *cookie, } CASIO_LOCAL int seven_scsi_write(seven_scsi_cookie_t *cookie, - unsigned char const *buffer, size_t size) + unsigned char const *buffer, size_t size, unsigned int timeout) { casio_scsi_t scsi; + casio_timer_t *timer = NULL; + unsigned long spent; int err; - do { - casio_uint16_t activity; + if (timeout) { + if ((err = casio_get_timer(&timer))) + return (err); + } - /* Polling loop. */ + while (size) { + do { + casio_uint16_t activity; + casio_uint16_t to_send; - while (1) { - casio_uint8_t poll_command[16] = {0xC0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - casio_uint8_t poll_data[16]; + /* Polling loop. */ - msg((ll_info, "Polling the activity using command C0...")); + while (1) { + casio_uint8_t poll_command[16] = {0xC0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + casio_uint8_t poll_data[16]; - /* Poll to check the activity. */ + msg((ll_info, "Polling the activity using command C0...")); - scsi.casio_scsi_cmd = poll_command; - scsi.casio_scsi_cmd_len = 16; - scsi.casio_scsi_direction = CASIO_SCSI_DIREC_FROM_DEV; - scsi.casio_scsi_data = poll_data; - scsi.casio_scsi_data_len = 16; + /* Poll to check the activity. */ - if ((err = casio_scsi_request(cookie->stream, &scsi))) - return (err); + scsi.casio_scsi_cmd = poll_command; + scsi.casio_scsi_cmd_len = 16; + scsi.casio_scsi_direction = CASIO_SCSI_DIREC_FROM_DEV; + scsi.casio_scsi_data = poll_data; + scsi.casio_scsi_data_len = 16; -#if 0 - activity = (poll_data[10] << 8) | poll_data[11]; + if ((err = casio_scsi_request(cookie->stream, &scsi))) { + casio_free_timer(timer); + return (err); + } - if (activity == 0x1000) { - /* The calculator is busy. - * FIXME: delay and check the timeout!! */ + /* Get the number of bytes left on the receiving buffer + * on the calculator. */ - continue; + activity = (poll_data[10] << 8) | poll_data[11]; + if (!activity) { + /* The calculator is busy. + * We ought to check the timeout and delay. */ + + if (timeout) { + if (!casio_get_spent_time(timer, &spent) + || spent > (unsigned long)timeout) { + casio_free_timer(timer); + return (casio_error_time); + } + + spent = (unsigned long)timeout - spent; + if (spent > 500) + spent = 500; + } else + spent = 500; + + casio_sleep(spent); + continue; + } + + to_send = (size_t)activity; + if ((size_t)to_send > size) + to_send = (casio_uint16_t)size; + break; } -#endif - break; - } + /* Actually send the data. */ - /* Actually send some of the data. */ + { + casio_uint8_t send_command[16] = {0xC2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - { - casio_uint16_t to_send = (size > 0xFFFF) ? 0xFFFF : size; - casio_uint8_t send_command[16] = {0xC2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + msg((ll_info, "Sending the data using command C2...")); - msg((ll_info, "Sending the data using command C2...")); + send_command[6] = (to_send >> 8) & 0xFF; + send_command[7] = to_send & 0xFF; - send_command[6] = (to_send >> 8) & 0xFF; - send_command[7] = to_send & 0xFF; + scsi.casio_scsi_cmd = send_command; + scsi.casio_scsi_cmd_len = 16; + scsi.casio_scsi_direction = CASIO_SCSI_DIREC_TO_DEV; + scsi.casio_scsi_data = (casio_uint8_t *)buffer; + scsi.casio_scsi_data_len = to_send; - scsi.casio_scsi_cmd = send_command; - scsi.casio_scsi_cmd_len = 16; - scsi.casio_scsi_direction = CASIO_SCSI_DIREC_TO_DEV; - scsi.casio_scsi_data = (casio_uint8_t *)buffer; - scsi.casio_scsi_data_len = to_send; + if ((err = casio_scsi_request(cookie->stream, &scsi))) { + casio_free_timer(timer); + return (err); + } - if ((err = casio_scsi_request(cookie->stream, &scsi))) - return (err); - - buffer += to_send; - size -= to_send; - } - } while (size); + buffer += to_send; + size -= to_send; + } + } while (size); + } + casio_free_timer(timer); return (0); } @@ -293,12 +328,11 @@ CASIO_LOCAL int seven_scsi_close(seven_scsi_cookie_t *cookie) CASIO_LOCAL casio_streamfuncs_t seven_scsi_funcs = { (casio_stream_close_t *)seven_scsi_close, - NULL, (casio_stream_read_t *)seven_scsi_read, (casio_stream_write_t *)seven_scsi_write, - NULL, - NULL, - (casio_stream_scsi_t *)seven_scsi_request + NULL, NULL, + (casio_stream_scsi_t *)seven_scsi_request, + NULL, NULL }; int CASIO_EXPORT casio_open_seven_scsi(casio_stream_t **streamp, diff --git a/lib/link/seven/send.c b/lib/link/seven/send.c index 9eb4892..ee13221 100644 --- a/lib/link/seven/send.c +++ b/lib/link/seven/send.c @@ -25,6 +25,7 @@ casio_checksum_sub(&((char*)(BUF))[1], (SIZE) - 3, 0) /* Internal macros. */ + #define buffer \ handle->casio_link_send_buffers[handle->casio_link_flags \ & casio_linkflag_sendalt] @@ -91,7 +92,7 @@ CASIO_LOCAL int casio_seven_send_buf(casio_link_t *handle, } /* send prepared packet */ - err = casio_write(handle->casio_link_stream, buf, bufsize); + err = casio_write(handle->casio_link_stream, buf, bufsize, 0); if (err) return (err); /* set wasreset for logging */ diff --git a/lib/log/iter.c b/lib/log/iter.c index f594b68..e78466e 100644 --- a/lib/log/iter.c +++ b/lib/log/iter.c @@ -42,10 +42,9 @@ CASIO_LOCAL int CASIO_EXPORT next_log(const char ***cookie, const char **level) /* `end_log_iter()`: end the iteration log. */ -CASIO_LOCAL int CASIO_EXPORT end_log_iter(const char ***cookie) +CASIO_LOCAL void CASIO_EXPORT end_log_iter(char const ***cookie) { free(cookie); - return (0); } /* Functions. */ diff --git a/lib/mcsfile/mcsfile.h b/lib/mcsfile/mcsfile.h index 336751f..1c7c99d 100644 --- a/lib/mcsfile/mcsfile.h +++ b/lib/mcsfile/mcsfile.h @@ -27,12 +27,12 @@ /* Read from a stream. */ # define READ(CASIO__TO, CASIO__SZ) /* normal read */ { \ - int READ_err = casio_read(buffer, (CASIO__TO), (CASIO__SZ)); \ + int READ_err = casio_read(buffer, (CASIO__TO), (CASIO__SZ), 0); \ if (READ_err) return (READ_err); } # define FREAD(CASIO__TO, CASIO__SZ) /* fail-less read */ \ - err = casio_read(buffer, (CASIO__TO), (CASIO__SZ)); + err = casio_read(buffer, (CASIO__TO), (CASIO__SZ), 0); # define GREAD(CASIO__TO, CASIO__SZ) /* read with goto fail */ \ - if ((err = casio_read(buffer, (CASIO__TO), (CASIO__SZ)))) \ + if ((err = casio_read(buffer, (CASIO__TO), (CASIO__SZ), 0))) \ goto fail; /* Read using size of the object. */ @@ -54,7 +54,7 @@ /* Write. */ # define WRITE(CASIO__BUF, CASIO__SZ) { \ - int WRITE_err = casio_write(buffer, (CASIO__BUF), (CASIO__SZ)); \ + int WRITE_err = casio_write(buffer, (CASIO__BUF), (CASIO__SZ), 0); \ if (WRITE_err) return (WRITE_err); } # define DWRITE(CASIO__OBJECT) \ WRITE(&(CASIO__OBJECT), sizeof(CASIO__OBJECT)) diff --git a/lib/picture/encode.c b/lib/picture/encode.c index 5908921..2e91e8a 100644 --- a/lib/picture/encode.c +++ b/lib/picture/encode.c @@ -30,7 +30,7 @@ */ int CASIO_EXPORT casio_encode_picture(void *vraw, - const casio_pixel_t **pixels, casio_pictureformat_t format, + casio_pixel_t const * const *pixels, casio_pictureformat_t format, unsigned int width, unsigned int height) { int msk; diff --git a/lib/stream/attrs.c b/lib/stream/attrs.c index 5659f10..44295fb 100644 --- a/lib/stream/attrs.c +++ b/lib/stream/attrs.c @@ -33,9 +33,12 @@ int CASIO_EXPORT casio_make_attrs(casio_streamattrs_t *attrs, const char *raw) { - unsigned int speed; char par; int stop; + unsigned int speed; + char par; + int stop; + + /* Check if we just want to initialize. */ - /* check if we just want to initialize */ if (!raw) { memset(attrs, 0, sizeof(casio_streamattrs_t)); /* ABI XXX */ attrs->casio_streamattrs_flags = @@ -44,7 +47,8 @@ int CASIO_EXPORT casio_make_attrs(casio_streamattrs_t *attrs, const char *raw) return (0); } - /* extract data from the string */ + /* Extract data from the string. */ + if (sscanf(raw, "%u%c%d", &speed, &par, &stop) < 3 || (par != 'N' && par != 'E' && par != 'O') || (stop != 1 && stop != 2)) { @@ -52,22 +56,40 @@ int CASIO_EXPORT casio_make_attrs(casio_streamattrs_t *attrs, const char *raw) return (casio_error_op); } - /* get the speed */ + /* Get the speed. */ + switch (speed) { - case 1200: speed = CASIO_B1200; break; - case 2400: speed = CASIO_B2400; break; - case 4800: speed = CASIO_B4800; break; - case 9600: speed = CASIO_B9600; break; - case 19200: speed = CASIO_B19200; break; - case 38400: speed = CASIO_B38400; break; - case 57600: speed = CASIO_B57600; break; - case 115200: speed = CASIO_B115200; break; + case 1200: + speed = CASIO_B1200; + break; + case 2400: + speed = CASIO_B2400; + break; + case 4800: + speed = CASIO_B4800; + break; + case 9600: + speed = CASIO_B9600; + break; + case 19200: + speed = CASIO_B19200; + break; + case 38400: + speed = CASIO_B38400; + break; + case 57600: + speed = CASIO_B57600; + break; + case 115200: + speed = CASIO_B115200; + break; default: msg((ll_error, "%u isn't a valid speed!", speed)); return (casio_error_op); } - /* set the settings */ + /* Set the settings. */ + casio_make_attrs(attrs, NULL); attrs->casio_streamattrs_speed = speed; attrs->casio_streamattrs_flags &= ~(CASIO_TWOSTOPBITS | CASIO_PARMASK); @@ -76,6 +98,7 @@ int CASIO_EXPORT casio_make_attrs(casio_streamattrs_t *attrs, const char *raw) attrs->casio_streamattrs_flags |= par == 'N' ? CASIO_PARDIS : par == 'E' ? CASIO_PARENB | CASIO_PAREVEN : CASIO_PARENB | CASIO_PARODD; + return (0); } @@ -93,18 +116,24 @@ int CASIO_EXPORT casio_make_attrs(casio_streamattrs_t *attrs, const char *raw) int CASIO_EXPORT casio_init_attrs(casio_stream_t *stream) { - int err; casio_stream_setattrs_t *s; + int err; + casio_stream_setattrs_t *s; casio_streamattrs_t attrs; - if (!stream) return (casio_error_op); - s = getcb(stream, setattrs); - if (!s) return (casio_error_op); + if (!stream + || !(s = stream->casio_stream_callbacks.casio_streamfuncs_setattrs)) + return (casio_error_op); + casio_make_attrs(&attrs, NULL); - err = (*s)(stream->casio_stream_cookie, &attrs); - if (err) return (err); + if ((err = (*s)(stream->casio_stream_cookie, &attrs))) { + stream->casio_stream_lasterr = err; + return (err); + } memcpy(&stream->casio_stream_attrs, &attrs, sizeof(casio_streamattrs_t)); + + stream->casio_stream_lasterr = 0; return (0); } @@ -122,17 +151,22 @@ int CASIO_EXPORT casio_set_attrs(casio_stream_t *stream, { int err; casio_stream_setattrs_t *s; - /* check if the attributes aren't valid */ - if (!attrs) return (casio_error_invalid); + /* Check if the attributes aren't valid. */ - /* check if the callback exists */ - if (!stream) return (casio_error_op); - s = getcb(stream, setattrs); - failure(!s, casio_error_op) + if (!attrs) + return (casio_error_invalid); - /* call it */ - err = (*s)(stream->casio_stream_cookie, attrs); - failure(err, err) + /* Check if the callback exists. */ + + if (!stream + || !(s = stream->casio_stream_callbacks.casio_streamfuncs_setattrs)) { + err = casio_error_op; + goto fail; + } + + /* Call it. */ + if ((err = (*s)(stream->casio_stream_cookie, attrs))) + goto fail; memcpy(&stream->casio_stream_attrs, attrs, sizeof(casio_streamattrs_t)); err = 0; diff --git a/lib/stream/builtin/builtin.h b/lib/stream/builtin/builtin.h new file mode 100644 index 0000000..6da3bb4 --- /dev/null +++ b/lib/stream/builtin/builtin.h @@ -0,0 +1,78 @@ +/* **************************************************************************** + * stream/builtin/builtin.h -- stream builtins. + * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey + * + * This file is part of libcasio. + * libcasio 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.0 of the License, + * or (at your option) any later version. + * + * libcasio 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libcasio; if not, see . + * ************************************************************************* */ +#ifndef LOCAL_STREAM_BUILTIN_H +# define LOCAL_STREAM_BUILTIN_H 2018051601 +# include "../../internals.h" + +/* --- + * List serial devices. + * --- */ + +/* List serial devices on Linux. */ + +# ifndef LIBCASIO_DISABLED_LINUX_SERIAL +CASIO_EXTERN int CASIO_EXPORT casio_iter_linux_serial + OF((casio_iter_t **casio__iterp)); +# endif + +/* List serial devices on MacOS/OS X. */ + +# ifndef LIBCASIO_DISABLED_MAC_SERIAL +CASIO_EXTERN int CASIO_EXPORT casio_iter_mac_serial + OF((casio_iter_t **casio__iterp)); +# endif + +/* List serial devices on Microsoft Windows. */ + +# ifndef LIBCASIO_DISABLED_WINDOWS +CASIO_EXTERN int CASIO_EXPORT casio_iter_windows_serial + OF((casio_iter_t **casio__iterp)); +# endif + +/* --- + * Open a serial stream. + * --- */ + +/* Open a serial stream using the STREAMS interface. */ + +# ifndef LIBCASIO_DISABLED_STREAMS +CASIO_EXTERN int CASIO_EXPORT casio_open_streams_serial + OF((casio_stream_t **casio__streamp, char const *casio__path, + casio_streamattrs_t const *casio__attrs)); +# endif + +/* --- + * Open a USB stream. + * --- */ + +/* Open a USB stream using libusb. */ + +# ifndef LIBCASIO_DISABLED_LIBUSB +CASIO_EXTERN int CASIO_EXPORT casio_open_libusb_usb + OF((casio_stream_t **casio__streamp, int casio__bus, int casio__address)); +# endif + +/* Open a USB stream using the Windows API. */ + +# ifndef LIBCASIO_DISABLED_WINDOWS +CASIO_EXTERN int CASIO_EXPORT casio_open_windows_usb + OF((casio_stream_t **casio__streamp, int casio__bus, int casio__address)); +# endif + +#endif /* LOCAL_STREAM_BUILTIN_H */ diff --git a/lib/stream/builtin/csum32.c b/lib/stream/builtin/csum32.c index a071582..b89121e 100644 --- a/lib/stream/builtin/csum32.c +++ b/lib/stream/builtin/csum32.c @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with libcasio; if not, see . * ************************************************************************* */ -#include "../../internals.h" +#include "builtin.h" /* --- * Cookie structure. @@ -38,17 +38,18 @@ struct thecookie { * @arg cookie the cookie. * @arg data the data pointer. * @arg size the data size. + * @arg timeout the timeout. * @return the error code (0 if ok). */ CASIO_LOCAL int csum32_read(struct thecookie *cookie, - unsigned char *dest, size_t size) + unsigned char *dest, size_t size, unsigned int timeout) { int err; /* Make the call. */ - err = casio_read(cookie->_stream, dest, size); + err = casio_read(cookie->_stream, dest, size, timeout); if (err) return (err); /* Make the checksum. */ @@ -72,9 +73,13 @@ CASIO_LOCAL int csum32_close(struct thecookie *cookie) } /* Callbacks. */ -CASIO_LOCAL const casio_streamfuncs_t csum32_callbacks = -casio_stream_callbacks_for_virtual(csum32_close, - csum32_read, NULL, NULL); + +CASIO_LOCAL casio_streamfuncs_t const csum32_callbacks = { + (casio_stream_close_t *)csum32_close, + (casio_stream_read_t *)csum32_read, + NULL, NULL, + NULL, NULL, NULL, NULL +}; /* --- * Main functions. diff --git a/lib/stream/builtin/file.c b/lib/stream/builtin/file.c index 50c9188..43be750 100644 --- a/lib/stream/builtin/file.c +++ b/lib/stream/builtin/file.c @@ -1,6 +1,6 @@ /* **************************************************************************** * stream/builtin/file.c -- built-in FILE stream. - * Copyright (C) 2016-2017 Thomas "Cakeisalie5" Touhey + * Copyright (C) 2016-2018 Thomas "Cakeisalie5" Touhey * * This file is part of libcasio. * libcasio is free software; you can redistribute it and/or modify it @@ -16,11 +16,12 @@ * You should have received a copy of the GNU Lesser General Public License * along with libcasio; if not, see . * ************************************************************************* */ -#include "../../internals.h" +#include "builtin.h" #ifndef LIBCASIO_DISABLED_FILE # include # include # include + # if defined(__linux__) # include # else @@ -46,14 +47,19 @@ typedef struct { * @arg cookie the cookie. * @arg data the data pointer * @arg size the data size. + * @arg timeout the timeout. * @return the error code (0 if ok). */ CASIO_LOCAL int casio_file_read(file_cookie_t *cookie, - unsigned char *dest, size_t size) + unsigned char *dest, size_t size, unsigned int timeout) { size_t recv; + /* TODO: is there a way to set a timeout on this sort of read? */ + + (void)timeout; + /* Main receiving loop. */ recv = 0; @@ -124,14 +130,19 @@ CASIO_LOCAL int casio_file_read(file_cookie_t *cookie, * @arg cookie the cookie. * @arg data the source * @arg size the source size + * @arg timeout the timeout. * @return the error code (0 if ok) */ CASIO_LOCAL int casio_file_write(file_cookie_t *cookie, - const unsigned char *data, size_t size) + const unsigned char *data, size_t size, unsigned int timeout) { size_t sent; + /* TODO: is there a way to set a timeout on this sort of read? */ + + (void)timeout; + /* Main sending. */ sent = fwrite(data, size, 1, cookie->_wstream); @@ -221,9 +232,14 @@ CASIO_LOCAL int casio_file_close(file_cookie_t *cookie) * Opening functions. * --- */ -CASIO_LOCAL const casio_streamfuncs_t casio_file_callbacks = -casio_stream_callbacks_for_virtual(casio_file_close, casio_file_read, - casio_file_write, casio_file_seek); +CASIO_LOCAL casio_streamfuncs_t const casio_file_callbacks = { + (casio_stream_close_t *)casio_file_close, + (casio_stream_read_t *)casio_file_read, + (casio_stream_write_t *)casio_file_write, + (casio_stream_seek_t *)casio_file_seek, + + NULL, NULL, NULL, NULL +}; /** * casio_open_stream_file: diff --git a/lib/stream/builtin/libusb/libusb.h b/lib/stream/builtin/libusb/libusb.h index b3cad60..ac51714 100644 --- a/lib/stream/builtin/libusb/libusb.h +++ b/lib/stream/builtin/libusb/libusb.h @@ -17,7 +17,7 @@ * along with libcasio; if not, see . * ************************************************************************* */ #ifndef LOCAL_STREAM_BUILTIN_LIBUSB_H -# include "../../../internals.h" +# include "../builtin.h" # ifndef LIBCASIO_DISABLED_LIBUSB # include diff --git a/lib/stream/builtin/limited.c b/lib/stream/builtin/limited.c index 6b847bf..5fb05ec 100644 --- a/lib/stream/builtin/limited.c +++ b/lib/stream/builtin/limited.c @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with libcasio; if not, see . * ************************************************************************* */ -#include "../../internals.h" +#include "builtin.h" /* Cookie structure. */ @@ -37,11 +37,12 @@ typedef struct { * @arg vcookie the cookie (uncasted). * @arg data the data pointer. * @arg size the data size. + * @arg timeout the timeout (in ms). * @return the error code (0 if ok). */ CASIO_LOCAL int casio_limited_read(void *vcookie, unsigned char *dest, - size_t size) + size_t size, unsigned int timeout) { int err; limited_cookie_t *cookie = (void*)vcookie; size_t left; @@ -60,7 +61,7 @@ CASIO_LOCAL int casio_limited_read(void *vcookie, unsigned char *dest, return (casio_error_eof); } - if ((err = casio_read(cookie->_stream, dest, size))) { + if ((err = casio_read(cookie->_stream, dest, size, timeout))) { cookie->_left = 0; /* XXX: depends on the error? */ return (err); } @@ -84,9 +85,12 @@ CASIO_LOCAL int casio_limited_close(void *vcookie) /* Callbacks. */ -CASIO_LOCAL const casio_streamfuncs_t casio_limited_callbacks = -casio_stream_callbacks_for_virtual(casio_limited_close, - casio_limited_read, NULL, NULL); +CASIO_LOCAL const casio_streamfuncs_t casio_limited_callbacks = { + (casio_stream_close_t *)casio_limited_close, + (casio_stream_read_t *)casio_limited_read, + NULL, NULL, + NULL, NULL, NULL, NULL +}; /* --- * Main functions. diff --git a/lib/stream/builtin/linux/list_serial.c b/lib/stream/builtin/linux/list_serial.c new file mode 100644 index 0000000..e332efc --- /dev/null +++ b/lib/stream/builtin/linux/list_serial.c @@ -0,0 +1,163 @@ +/* **************************************************************************** + * comlist/builtin/linux.c -- find out Linux serial devices. + * Copyright (C) 2016-2017 Thomas "Cakeisalie5" Touhey + * + * This file is part of libcasio. + * libcasio 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.0 of the License, + * or (at your option) any later version. + * + * libcasio 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libcasio; if not, see . + * ************************************************************************* */ +#include "../builtin.h" +#ifndef LIBCASIO_DISABLED_LINUX_SERIAL +# include +# include +# include +# include +# include + +typedef struct lincookie { + char *path; + char *devname; + size_t path_max; + DIR *dp; + char *start; +} lincookie_t; + +/** + * next_serial_port: + * Get the next serial port. + * + * @arg cookie the lincookie. + * @arg ptr the pointer to the next path. + * @return the error code (0 if ok). + */ + +CASIO_LOCAL int CASIO_EXPORT next_serial_port(lincookie_t *cookie, + char const **ptr) +{ + struct dirent *dr; + struct stat st; + ssize_t rl; + char *res; + + while (1) { + /* Get the next entry. */ + + if (!(dr = readdir(cookie->dp))) + return (casio_error_iter); + + /* Copy that into the path and check the type. */ + + strcpy(cookie->start, dr->d_name); + if (lstat(cookie->path, &st) || (st.st_mode & S_IFMT) != S_IFLNK) + continue; + + /* Get the destination path. */ + + rl = readlink(cookie->path, cookie->devname, PATH_MAX + 1); + if (rl < 0) + continue; + cookie->devname[rl] = 0; + + /* If the path is a relative one, adapt it. */ + + if (cookie->devname[0] != '/') { + strcpy(cookie->start, cookie->devname); + if (!(res = realpath(cookie->path, cookie->devname))) + continue; + } + + break; + } + + *ptr = cookie->devname; + return (0); +} + +/** + * end_iter: + * End the iterator by freeing all related allocated resources. + * + * @arg cookie the cookie. + */ + +CASIO_LOCAL void CASIO_EXPORT end_iter(lincookie_t *cookie) +{ + closedir(cookie->dp); + casio_free(cookie); +} + +/* Functions. */ + +CASIO_LOCAL casio_iter_funcs_t linux_serial_functions = { + (casio_next_t *)&next_serial_port, + NULL, + (casio_end_t *)&end_iter +}; + +/** + * casio_iter_linux_serial: + * List serial ports under Linux. + * + * Links in the /dev/serial/by-id/ should resolve to relative paths, but + * I also managed absolute paths, in case. + * + * @arg iterp the iterator to create. + * @return the error. + */ + +int CASIO_EXPORT casio_iter_linux_serial(casio_iter_t **iterp) +{ + lincookie_t *cookie; + size_t path_max; + + /* Get the maximum path size. + * Snippet found in `man 3 realpath`, glibc version. */ + +#ifdef PATH_MAX + path_max = PATH_MAX; +#else + path_max = pathconf(path, _PC_PATH_MAX); + if (path_max <= 0) + path_max = 4096; +#endif + ++path_max; + + /* Create the cookie. */ + + if (!(cookie = casio_alloc(sizeof(*cookie) + path_max + path_max, 1))) + return (casio_error_alloc); + + cookie->path = (char *)(void *)&cookie[1]; + cookie->devname = cookie->path + path_max; + + /* Open the directory stream. */ + + strcpy(cookie->path, "/dev/serial/by-id/"); + if (!(cookie->dp = opendir(cookie->path))) { + casio_free(cookie); + + /* TODO: check errno */ + return (casio_error_unknown); + } + + /* Prepare what's left to prepare in the cookie. */ + + cookie->start = strchr(cookie->path, '\0'); + cookie->path_max = path_max; + + /* Create the iterator. */ + + return (casio_iter(iterp, cookie, linux_serial_functions)); +} + +# endif /* __linux__ */ diff --git a/lib/stream/builtin/macos/list_serial.c b/lib/stream/builtin/macos/list_serial.c new file mode 100644 index 0000000..7124647 --- /dev/null +++ b/lib/stream/builtin/macos/list_serial.c @@ -0,0 +1,122 @@ +/* **************************************************************************** + * comlist/builtin/macos.c -- find out MacOS/OS X serial devices. + * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey + * + * This file is part of libcasio. + * libcasio 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.0 of the License, + * or (at your option) any later version. + * + * libcasio 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libcasio; if not, see . + * ************************************************************************* */ +#include "../builtin.h" +#ifndef LIBCASIO_DISABLED_MAC_SERIAL +# include + +typedef struct { + char *path; + DIR *dp; + char *start; +} icookie_t; + +/** + * next_serial_port: + * Get the next serial port. + * + * @arg cookie the iCookie. + * @arg ptr the pointer to the next path. + * @return the error code (0 if ok). + */ + +CASIO_LOCAL int CASIO_EXPORT next_serial_port(icookie_t *cookie, + char const **ptr) +{ + struct dirent *dr; + + while (1) { + /* Get the next entry. */ + + if (!(dr = readdir(cookie->dp))) + return (casio_error_iter); + + /* Check the name. */ + + if (strncmp(dr->d_name, "cu.", 3)) + continue; + + /* We have found a serial port! + * Just copy it into our buffer and return it. */ + + strcpy(cookie->start, dr->d_name); + break; + } + + *ptr = cookie->path; + return (0); +} + +/** + * end_iter: + * End the iterator by freeing all related allocated resources. + * + * @arg cookie the iCookie. + */ + +CASIO_LOCAL void CASIO_EXPORT end_iter(icookie_t *cookie) +{ + closedir(d); + casio_free(cookie); +} + +/* Functions. */ + +CASIO_LOCAL casio_iter_funcs_t mac_serial_functions = { + (casio_next_t *)&next_serial_port, + NULL, + (casio_end_t *)&end_iter +}; + +/** + * casio_iter_mac_serial: + * Iterate on serial devices under MacOS/OS X. + * + * @arg iterp the iterator to create. + * @return the error. + */ + +int CASIO_EXPORT casio_iter_mac_serial(casio_iter_t **iterp) +{ + icookie_t *cookie; + + /* Create the cookie. */ + + if (!(cookie = casio_alloc(1, sizeof(icookie_t) + PATH_MAX + 1))) + return (casio_error_alloc); + + cookie->path = (char *)(void *)&cookie[1]; + + /* Prepare the path and open the directory stream. */ + + strcpy(cookie->path, "/dev/"); + cookie->start = strchr(cookie->path, '\0'); + + if (!(cookie->dp = opendir(cookie->path))) { + casio_free(cookie); + + /* TODO: check errno */ + return (casio_error_unknown); + } + + /* Create the iterator. */ + + return (casio_iter(iterp, cookie, mac_serial_functions)); +} + +#endif /* LIBCASIO_DISABLED_MAC_SERIAL */ diff --git a/lib/stream/builtin/memory.c b/lib/stream/builtin/memory.c index ea4936c..82cbe81 100644 --- a/lib/stream/builtin/memory.c +++ b/lib/stream/builtin/memory.c @@ -16,9 +16,10 @@ * You should have received a copy of the GNU Lesser General Public License * along with libcasio; if not, see . * ************************************************************************* */ -#include "../../internals.h" +#include "builtin.h" + +/* Cookie structure. */ -/* cookie structure */ typedef struct { unsigned char *_memory; casio_off_t _size, _offset; @@ -35,13 +36,20 @@ typedef struct { * @arg vcookie the cookie (uncasted) * @arg data the data pointer. * @arg size the data size. + * @arg timeout the timeout (in ms). * @return the error code (0 if ok). */ -CASIO_LOCAL int casio_memory_read(void *vcookie, unsigned char *dest, size_t size) +CASIO_LOCAL int casio_memory_read(void *vcookie, unsigned char *dest, + size_t size, unsigned int timeout) { memory_cookie_t *cookie = (void*)vcookie; + /* Timeouts while reading memory? Are you serious? + * Going quicker is impossible! */ + + (void)timeout; + if (((size_t)-1 - cookie->_offset) < size) /* overflow */ return (casio_error_read); if (cookie->_offset + (casio_off_t)size > cookie->_size) { @@ -62,14 +70,20 @@ CASIO_LOCAL int casio_memory_read(void *vcookie, unsigned char *dest, size_t siz * @arg vcookie the cookie (uncasted). * @arg data the data pointer. * @arg size the data size. + * @arg timeout the timeout (in ms). * @return the error code (0 if ok). */ CASIO_LOCAL int casio_memory_write(void *vcookie, const unsigned char *data, - size_t size) + size_t size, unsigned int timeout) { memory_cookie_t *cookie = (void*)vcookie; + /* Timeouts while reading memory? Are you serious? + * Going quicker is impossible! */ + + (void)timeout; + if (((size_t)-1 - cookie->_offset) < size) /* overflow */ return (casio_error_write); if (cookie->_offset + (casio_off_t)size > cookie->_size) { @@ -142,9 +156,14 @@ CASIO_LOCAL int casio_memory_close(void *vcookie) } /* Callbacks. */ -CASIO_LOCAL const casio_streamfuncs_t casio_memory_callbacks = -casio_stream_callbacks_for_virtual(casio_memory_close, - casio_memory_read, casio_memory_write, casio_memory_seek); +CASIO_LOCAL casio_streamfuncs_t const casio_memory_callbacks = { + (casio_stream_close_t *)casio_memory_close, + (casio_stream_read_t *)casio_memory_read, + (casio_stream_write_t *)casio_memory_write, + (casio_stream_seek_t *)casio_memory_seek, + + NULL, NULL, NULL, NULL +}; /* --- * Opening functions. diff --git a/lib/stream/builtin/streams/streams.h b/lib/stream/builtin/streams/streams.h index d04b078..adcced6 100644 --- a/lib/stream/builtin/streams/streams.h +++ b/lib/stream/builtin/streams/streams.h @@ -18,7 +18,7 @@ * ************************************************************************* */ #ifndef LOCAL_STREAM_BUILTIN_STREAMS_H # define LOCAL_STREAM_BUILTIN_STREAMS_H 1 -# include "../../../internals.h" +# include "../builtin.h" # ifndef LIBCASIO_DISABLED_STREAMS # include # include diff --git a/lib/stream/builtin/windows/list_serial.c b/lib/stream/builtin/windows/list_serial.c new file mode 100644 index 0000000..5265fd3 --- /dev/null +++ b/lib/stream/builtin/windows/list_serial.c @@ -0,0 +1,183 @@ +/* **************************************************************************** + * comlist/builtin/windows.c -- find out serial devices on MS-Windows. + * Copyright (C) 2016-2017 Thomas "Cakeisalie5" Touhey + * + * This file is part of libcasio. + * libcasio 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.0 of the License, + * or (at your option) any later version. + * + * libcasio 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libcasio; if not, see . + * ************************************************************************* */ +#include "../../internals.h" +#ifndef LIBCASIO_DISABLED_WINDOWS + +/* These headers only work because I've redefined the version at the + * beginning of `internals.h`! */ + +# include +# include +# include +# include + +/* The cookie structure. */ + +typedef struct { + HKEY hkey; + char *value; + char *data; + int erroneous; + DWORD i; /* index of the key to read */ + DWORD value_size; + DWORD data_size; +} cookie_t, *PSP_COOKIE; + +/** + * next_serial_port: + * Get the next serial port. + * + * @arg cookie the cookie. + * @arg ptr the pointer to the next path. + * @return the error code (0 if ok). + */ + +CASIO_LOCAL int CASIO_EXPORT next_serial_port(cookie_t *cookie, + char const **ptr) +{ + DWORD werr; + DWORD curval, datasize, type; + + if (cookie->erroneous) + return (casio_error_unknown); + + while (1) { + /* Get the next iteration from the original function. */ + + curval = cookie->value_size; + curdata = cookie->data_size; + switch ((werr = RegEnumValue(hkey, cookie->i++, value, &curval, NULL, + &type, (BYTE *)data, &curdata))) { + case 0: + /* Nothing wrong, check what's next. */ + + break; + + case ERROR_NO_MORE_ITEMS: + /* We've arrived at the end of the original iterator. */ + + return (casio_error_iter); + + case ERROR_MORE_DATA: + /* Our buffers weren't big enough. Tough luck! + * Let's go to the next entry and just ignore this one. */ + + continue; + + default: + /* Any error could have happened, and put the original iterator + * in an erroneous state. So we're going to be in an erroneous + * state too. */ + + msg((ll_error, "Error %08lu occurred, switching to erroneous " + "state.")); + cookie->erroneous = 1; + return (casio_error_unknown); + } + + /* Check the type. */ + + if (type != REG_SZ) { + /* Not the kind of register we were expecting. + * Never mind, let's carry on. */ + + continue; + } + + break; + } + + /* The key is useless to us, we just read it because we're obliged to. + * What is interesting is the register entry data. */ + + *ptr = cookie->data; + return (0); +} + +/** + * end_iter: + * End the iterator by freeing all related allocated resources. + * + * @arg cookie the cookie. + */ + +CASIO_LOCAL void CASIO_EXPORT end_iter(cookie_t *cookie) +{ + RegCloseKey(cookie->hkey); + casio_free(cookie); +} + +/* Functions to use for the iterator. */ + +CASIO_LOCAL casio_iter_funcs_t windows_serial_functions = { + (casio_next_t *)&next_serial_port, + NULL, + (casio_end_t *)&end_iter +}; + +/** + * casio_iter_windows_serial: + * Iterate on serial devices under MS-Windows. + * + * What I'm doing here is based on the source from Python 3.x's winreg + * module source and the MSDN documentation. + * + * @arg iterp the iterator to create. + * @return the error code (0 if ok). + */ + +# define SERIAL_COMM_HKEY "HARDWARE\\DEVICEMAP\\SERIALCOMM" + +int CASIO_EXPORT casio_iter_windows_serial(casio_iter_t **iterp) +{ + cookie_t *cookie; + DWORD werr, value_size, data_size; + + /* Create the cookie. + * 1024 should be enough for most cases (until a driver comes and + * makes up a name which is longer…). */ + + value_size = 1024; + data_size = 1024; + if (!(cookie = casio_alloc(1, sizeof(*cookie) + value_size + data_size))) + return (casio_error_alloc); + + cookie->value = (char *)(void *)&cookie[1]; + cookie->data = cookie->value + value_size; + cookie->value_size = value_size; + cookie->data_size = data_size; + cookie->erroneous = 0; + cookie->i = 0; + + /* Opening the registry key. */ + + msg((ll_info, "Opening HKEY_LOCAL_MACHINE\\" SERIAL_COMM_HKEY)); + if ((werr = RegOpenKey(HKEY_LOCAL_MACHINE, SERIAL_COMM_HKEY, + &cookie->hkey))) { + msg((ll_error, "Encountered error %08lu while opening registry.", + werr)); + + casio_free(cookie); + return (casio_error_unknown); + } + + return (casio_iter(iterp, cookie, &windows_serial_functions)); +} + +#endif diff --git a/lib/stream/builtin/windows/windows.h b/lib/stream/builtin/windows/windows.h index 34402a9..51dc0d0 100644 --- a/lib/stream/builtin/windows/windows.h +++ b/lib/stream/builtin/windows/windows.h @@ -18,7 +18,7 @@ * ************************************************************************* */ #ifndef LOCAL_STREAM_BUILTIN_WINDOWS_H # define LOCAL_STREAM_BUILTIN_WINDOWS_H 1 -# include "../../../internals.h" +# include "../builtin.h" # ifndef LIBCASIO_DISABLED_WINDOWS # include # include diff --git a/lib/stream/get.c b/lib/stream/get.c index afe7f76..9c34925 100644 --- a/lib/stream/get.c +++ b/lib/stream/get.c @@ -100,26 +100,16 @@ int CASIO_EXPORT casio_get_lasterr(casio_stream_t *stream) int CASIO_EXPORT casio_get_attrs(casio_stream_t *stream, casio_streamattrs_t *attrs) { - if (!getcb(stream, setattrs)) return (casio_error_op); + casio_stream_setattrs_t *st; + + /* Check that attributes have a meaning here. */ + + if (!(st = stream->casio_stream_callbacks.casio_streamfuncs_setattrs)) + return (casio_error_op); + + /* Return the attributes. */ + memcpy(attrs, &stream->casio_stream_attrs, sizeof(casio_streamattrs_t)); /* DANGEROUS: ABI COMPAT XXX */ return (0); } - -/** - * casio_get_timeouts: - * Get the timeouts of a libcasio stream. - * - * @arg stream the stream to get the timeouts of. - * @arg timeouts the timeouts to get. - * @return the error code (0 if ok). - */ - -int CASIO_EXPORT casio_get_timeouts(casio_stream_t *stream, - casio_timeouts_t *timeouts) -{ - if (!getcb(stream, settm)) return (casio_error_op); - memcpy(timeouts, &stream->casio_stream_timeouts, - sizeof(casio_timeouts_t)); /* DANGEROUS: ABI COMPAT XXX */ - return (0); -} diff --git a/lib/stream/list.c b/lib/stream/list.c new file mode 100644 index 0000000..513bee6 --- /dev/null +++ b/lib/stream/list.c @@ -0,0 +1,60 @@ +/* **************************************************************************** + * stream/list.c -- find out serial devices. + * Copyright (C) 2016-2018 Thomas "Cakeisalie5" Touhey + * + * This file is part of libcasio. + * libcasio 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.0 of the License, + * or (at your option) any later version. + * + * libcasio 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libcasio; if not, see . + * ************************************************************************* */ +#include "stream.h" + +#if !defined(LIBCASIO_DISABLED_LINUX_SERIAL) +# define ISF &casio_iter_linux_serial +#elif !defined(LIBCASIO_DISABLED_WINDOWS) +# define ISF &casio_iter_windows_serial +#elif !defined(LIBCASIO_DISABLED_MAC_SERIAL) +# define ISF &casio_iter_mac_serial +#else +# define ISF NULL +#endif + +CASIO_LOCAL casio_iter_serial_t *iter_serial_func = ISF; + +/** + * casio_set_iter_serial_func: + * Set the function to iterate on serial devices. + * + * @arg func the function. + * @return the error code (0 if ok). + */ + +int CASIO_EXPORT casio_set_iter_serial_func(casio_iter_serial_t *func) +{ + iter_serial_func = func ? func : ISF; + return (0); +} + +/** + * casio_iter_serial: + * Get available serial ports. + * + * @arg iterp the iterator to make. + * @return the error (if any). + */ + +int CASIO_EXPORT casio_iter_serial(casio_iter_t **iterp) +{ + if (!iter_serial_func) + return (casio_error_op); + return ((*iter_serial_func)(iterp)); +} diff --git a/lib/stream/open.c b/lib/stream/open.c index db09f2a..268e8d9 100644 --- a/lib/stream/open.c +++ b/lib/stream/open.c @@ -50,28 +50,50 @@ int CASIO_EXPORT casio_open_stream(casio_stream_t **pstream, stream->casio_stream_mode = 0; c = &stream->casio_stream_callbacks; - memset(c, 0, sizeof(casio_streamfuncs_t)); + c->casio_streamfuncs_close = callbacks->casio_streamfuncs_close; - c->casio_streamfuncs_settm = callbacks->casio_streamfuncs_settm; + if ((mode & CASIO_OPENMODE_READ) && callbacks->casio_streamfuncs_read) { stream->casio_stream_mode |= CASIO_OPENMODE_READ; - c->casio_streamfuncs_read = callbacks->casio_streamfuncs_read; - } + c->casio_streamfuncs_read = callbacks->casio_streamfuncs_read; + } else + c->casio_streamfuncs_read = NULL; + if ((mode & CASIO_OPENMODE_WRITE) && callbacks->casio_streamfuncs_write) { stream->casio_stream_mode |= CASIO_OPENMODE_WRITE; c->casio_streamfuncs_write = callbacks->casio_streamfuncs_write; - } + } else + c->casio_streamfuncs_write = NULL; + if (mode & (CASIO_OPENMODE_READ | CASIO_OPENMODE_WRITE)) - c->casio_streamfuncs_seek = callbacks->casio_streamfuncs_seek; + c->casio_streamfuncs_seek = callbacks->casio_streamfuncs_seek; + else + c->casio_streamfuncs_seek = NULL; if ((mode & CASIO_OPENMODE_SERIAL) && callbacks->casio_streamfuncs_setattrs) { stream->casio_stream_mode |= CASIO_OPENMODE_SERIAL; c->casio_streamfuncs_setattrs = callbacks->casio_streamfuncs_setattrs; - } + } else + c->casio_streamfuncs_setattrs = NULL; + if ((mode & CASIO_OPENMODE_SCSI) && callbacks->casio_streamfuncs_scsi) { stream->casio_stream_mode |= CASIO_OPENMODE_SCSI; c->casio_streamfuncs_scsi = callbacks->casio_streamfuncs_scsi; + } else + c->casio_streamfuncs_scsi = NULL; + + if ((mode & CASIO_OPENMODE_USB) + && callbacks->casio_streamfuncs_usb_send_bulk + && callbacks->casio_streamfuncs_usb_recv_bulk) { + stream->casio_stream_mode |= CASIO_OPENMODE_USB; + c->casio_streamfuncs_usb_send_bulk = + callbacks->casio_streamfuncs_usb_send_bulk; + c->casio_streamfuncs_usb_recv_bulk = + callbacks->casio_streamfuncs_usb_recv_bulk; + } else { + c->casio_streamfuncs_usb_send_bulk = NULL; + c->casio_streamfuncs_usb_recv_bulk = NULL; } /* Initialize the stream properties. */ @@ -80,7 +102,6 @@ int CASIO_EXPORT casio_open_stream(casio_stream_t **pstream, stream->casio_stream_offset = ioff; stream->casio_stream_lasterr = 0; casio_init_attrs(stream); - casio_init_timeouts(stream); err = 0; fail: @@ -101,11 +122,14 @@ fail: int CASIO_EXPORT casio_close(casio_stream_t *stream) { - casio_stream_close_t *c; + casio_stream_close_t *cl; - if (!stream) return (0); - c = getcb(stream, close); - if (c) (*c)(stream->casio_stream_cookie); + if (!stream) + return (0); + + if ((cl = stream->casio_stream_callbacks.casio_streamfuncs_close)) + (*cl)(stream->casio_stream_cookie); casio_free(stream); + return (0); } diff --git a/lib/stream/open/com.c b/lib/stream/open/com.c deleted file mode 100644 index 6576139..0000000 --- a/lib/stream/open/com.c +++ /dev/null @@ -1,84 +0,0 @@ -/* **************************************************************************** - * stream/open/com.c -- open a COM stream. - * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey - * - * This file is part of libcasio. - * libcasio 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.0 of the License, - * or (at your option) any later version. - * - * libcasio 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libcasio; if not, see . - * ************************************************************************* */ -#include "../stream.h" -#define NUM 5 - -/* Correspondance type. */ -struct corresp { - int _valid; - casio_opencomstream_t *_opencom; -}; - -/* List of streams. */ -CASIO_LOCAL struct corresp opencoms[NUM + 1] = { -#if !defined(LIBCASIO_DISABLED_STREAMS) - {1, casio_opencom_streams}, -#endif -#if !defined(LIBCASIO_DISABLED_WINDOWS) - {1, casio_opencom_windows}, -#endif - {0, NULL} -}; - -/** - * casio_add_default_com_stream: - * Add a serial stream opener. - * - * @arg function the function pointer to add. - * @return the error code (0 if ok). - */ - -int CASIO_EXPORT casio_add_default_com_stream(casio_opencomstream_t *function) -{ - struct corresp *c; int num; - - for (c = opencoms, num = NUM; c->_valid && num; c++, num--); - if (!num) return (casio_error_op); - - c->_valid = 1; - c->_opencom = function; - return (0); -} - -/** - * casio_open_com_stream: - * Open the serial stream. - * - * @arg stream the stream to make. - * @arg path the serial device path. - * @return the error code (0 if ok). - */ - -int CASIO_EXPORT casio_open_com_stream(casio_stream_t **stream, - const char *path) -{ - int err; struct corresp *c = opencoms; - - if (!c->_valid) - return (casio_error_op); - for (; c->_valid; c++) { - err = (*c->_opencom)(stream, path); - - if (!err) return (0); - if (err != casio_error_nocalc) - return (err); - } - - return (casio_error_nocalc); -} diff --git a/lib/stream/open_serial.c b/lib/stream/open_serial.c new file mode 100644 index 0000000..986861e --- /dev/null +++ b/lib/stream/open_serial.c @@ -0,0 +1,65 @@ +/* **************************************************************************** + * stream/open_serial.c -- open a serial stream. + * Copyright (C) 2017-2018 Thomas "Cakeisalie5" Touhey + * + * This file is part of libcasio. + * libcasio 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.0 of the License, + * or (at your option) any later version. + * + * libcasio 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libcasio; if not, see . + * ************************************************************************* */ +#include "stream.h" + +#if !defined(LIBCASIO_DISABLED_STREAMS) +# define OSF &casio_open_streams_serial +#elif !defined(LIBCASIO_DISABLED_WINDOWS) +# define OSF &casio_open_windows_serial +#else +# define OSF NULL +#endif + +CASIO_LOCAL casio_open_serial_stream_t *open_serial_stream_func = OSF; + +/** + * casio_set_open_serial_stream_func: + * Set the serial streams opener. + * + * NULL resets the function to its default. + * + * @arg function the function pointer to set. + * @return the error code (0 if ok). + */ + +int CASIO_EXPORT casio_set_open_serial_stream_func( + casio_open_serial_stream_t *func) +{ + open_serial_stream_func = func ? func : OSF; + return (0); +} + +/** + * casio_open_serial_stream: + * Open the serial stream. + * + * @arg streamp the stream to make. + * @arg path the serial device path. + * @arg attrs the serial attributes. + * @return the error code (0 if ok). + */ + +int CASIO_EXPORT casio_open_serial_stream(casio_stream_t **streamp, + char const *path, casio_streamattrs_t const *attrs) +{ + if (!open_serial_stream_func) + return (casio_error_op); + + return ((*open_serial_stream_func)(streamp, path, attrs)); +} diff --git a/lib/stream/open/usb.c b/lib/stream/open_usb.c similarity index 59% rename from lib/stream/open/usb.c rename to lib/stream/open_usb.c index 7bbd688..0cf86b1 100644 --- a/lib/stream/open/usb.c +++ b/lib/stream/open_usb.c @@ -1,5 +1,5 @@ /* **************************************************************************** - * stream/open/usb.c -- open a USB stream. + * stream/open_usb.c -- open a USB stream. * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey * * This file is part of libcasio. @@ -16,44 +16,31 @@ * You should have received a copy of the GNU Lesser General Public License * along with libcasio; if not, see . * ************************************************************************* */ -#include "../stream.h" -#define NUM 5 +#include "stream.h" -/* Correspondance type. */ -struct corresp { - int _valid; - casio_openusbstream_t *_openusb; -}; - -/* List of streams. */ -CASIO_LOCAL struct corresp openusbs[NUM + 1] = { #if !defined(LIBCASIO_DISABLED_LIBUSB) - {1, casio_openusb_libusb}, +# define OUF &casio_open_libusb_usb +#elif !defined(LIBCASIO_DISABLED_WINDOWS) +# define OUF &casio_open_windows_usb +#else +# define OUF NULL #endif -#if !defined(LIBCASIO_DISABLED_WINDOWS) - {1, casio_openusb_windows}, -#endif - {0, NULL} -}; + +CASIO_LOCAL casio_open_usb_stream_t *open_usb_stream_func = OUF; /** - * casio_add_default_usb_stream: - * Add a USB stream opener. + * casio_set_open_usb_stream_func: + * Set the USB streams opener. * - * @arg function the function pointer to add. + * NULL rests the function to its default. + * + * @arg function the function pointer to set. * @return the error code (0 if ok). */ -int CASIO_EXPORT casio_add_default_usb_stream(casio_openusbstream_t *function) +int CASIO_EXPORT casio_set_open_usb_stream_func(casio_open_usb_stream_t *func) { - struct corresp *c; int num; - - for (c = openusbs, num = NUM; c->_valid && num; c++, num--); - if (!num) - return (casio_error_op); - - c->_valid = 1; - c->_openusb = function; + open_usb_stream_func = func ? func : OUF; return (0); } @@ -69,24 +56,13 @@ int CASIO_EXPORT casio_add_default_usb_stream(casio_openusbstream_t *function) * @return the error code (0 if ok). */ -int CASIO_EXPORT casio_open_usb_stream(casio_stream_t **stream, +int CASIO_EXPORT casio_open_usb_stream(casio_stream_t **streamp, int bus, int address) { - int err; struct corresp *c = openusbs; - if (bus < -1 || bus > 255 || address < -1 || address > 255) return (casio_error_op); - if (!c->_valid) + if (!open_usb_stream_func) return (casio_error_op); - for (; c->_valid; c++) { - err = (*c->_openusb)(stream, bus, address); - - if (!err) - return (0); - if (err != casio_error_nocalc) - return (err); - } - - return (casio_error_nocalc); + return ((*open_usb_stream_func)(streamp, bus, address)); } diff --git a/lib/stream/read.c b/lib/stream/read.c index 42b5fd6..e5dc853 100644 --- a/lib/stream/read.c +++ b/lib/stream/read.c @@ -25,20 +25,29 @@ * @arg stream the stream to read from. * @arg dest the destination buffer. * @arg size the amount of bytes to read. + * @arg timeout the timeout for the entire read. * @return the error code (0 if ok). */ -int CASIO_EXPORT casio_read(casio_stream_t *stream, void *dest, size_t size) +int CASIO_EXPORT casio_read(casio_stream_t *stream, void *dest, size_t size, + unsigned int timeout) { int err; + casio_stream_read_t *rd; - /* check if we can read */ - failure(~stream->casio_stream_mode & CASIO_OPENMODE_READ, casio_error_read) + /* Check if we can read. */ - /* read */ - if (!size) return (0); - err = (*getcb(stream, read))(stream->casio_stream_cookie, dest, size); - if (err) { + if (~stream->casio_stream_mode & CASIO_OPENMODE_READ + || !(rd = stream->casio_stream_callbacks.casio_streamfuncs_read)) { + err = casio_error_read; + goto fail; + } + + /* Read. */ + + if (!size) + return (0); + if ((err = (*rd)(stream->casio_stream_cookie, dest, size, timeout))) { msg((ll_error, "Stream reading failure: %s", casio_strerror(err))); goto fail; } diff --git a/lib/stream/scsi.c b/lib/stream/scsi.c index 270d8da..3b36c80 100644 --- a/lib/stream/scsi.c +++ b/lib/stream/scsi.c @@ -33,12 +33,10 @@ int CASIO_EXPORT casio_scsi_request(casio_stream_t *stream, int err; casio_stream_scsi_t *s; - s = getcb(stream, scsi); - if (!s) - return (casio_error_op); - - err = (*s)(stream->casio_stream_cookie, request); - failure(err, err) + if (!(s = stream->casio_stream_callbacks.casio_streamfuncs_scsi)) + return (casio_error_scsi); + if ((err = (*s)(stream->casio_stream_cookie, request))) + goto fail; err = 0; fail: diff --git a/lib/stream/seek.c b/lib/stream/seek.c index 376221c..69e902f 100644 --- a/lib/stream/seek.c +++ b/lib/stream/seek.c @@ -31,10 +31,14 @@ int CASIO_EXPORT casio_seek(casio_stream_t *stream, casio_off_t offset, casio_whence_t whence) { - int err; casio_stream_seek_t *s; + int err; + casio_stream_seek_t *s; - failure(whence != CASIO_SEEK_SET && whence != CASIO_SEEK_CUR - && whence != CASIO_SEEK_END, casio_error_op) + if (whence != CASIO_SEEK_SET && whence != CASIO_SEEK_CUR + && whence != CASIO_SEEK_END) { + err = casio_error_op; + goto fail; + } /* Check if the job isn't already done. */ @@ -44,12 +48,11 @@ int CASIO_EXPORT casio_seek(casio_stream_t *stream, casio_off_t offset, /* Try to seek using the dedicated function. */ - s = getcb(stream, seek); - if (s) { + if ((s = stream->casio_stream_callbacks.casio_streamfuncs_seek)) { /* The callback exists, let's use it! */ - err = (*s)(stream->casio_stream_cookie, &offset, whence); - failure(err, err) + if ((err = (*s)(stream->casio_stream_cookie, &offset, whence))) + goto fail; } else if (whence == CASIO_SEEK_CUR && offset > 0 && stream->casio_stream_mode & CASIO_OPENMODE_READ) { /* Fallback mehod for skipping bytes: read until N bytes have @@ -64,7 +67,7 @@ int CASIO_EXPORT casio_seek(casio_stream_t *stream, casio_off_t offset, /* Read that much from the stream. */ - if ((err = casio_read(stream, buf, rd))) + if ((err = casio_read(stream, buf, rd, 0))) goto fail; to_skip -= rd; diff --git a/lib/stream/stream.h b/lib/stream/stream.h index 16e53be..a0f8bbe 100644 --- a/lib/stream/stream.h +++ b/lib/stream/stream.h @@ -17,31 +17,28 @@ * along with libcasio; if not, see . * ************************************************************************* */ #ifndef LOCAL_STREAM_H -# define LOCAL_STREAM_H 1 +# define LOCAL_STREAM_H 2018051701 # include "../internals.h" -# define failure(CASIO__COND, CASIO__ERR) \ - if (CASIO__COND) { err = CASIO__ERR; goto fail; } /* Pretty much everything about this structure is discussed * in `libcasio/stream.h`. */ struct casio_stream_s { - /* stream information */ + /* Stream information. */ + casio_openmode_t casio_stream_mode; void *casio_stream_cookie; int casio_stream_lasterr; - /* private properties (do not modify these!) */ + /* Private properties (do not modify these!). */ + casio_off_t casio_stream_offset; casio_streamattrs_t casio_stream_attrs; - casio_timeouts_t casio_stream_timeouts; - /* callbacks */ + /* Callbacks. */ + casio_streamfuncs_t casio_stream_callbacks; }; -/* Get a callback. */ -#define getcb(CASIO__S, CASIO__NAME) \ - ((CASIO__S)->casio_stream_callbacks.casio_streamfuncs_ ## CASIO__NAME) - +# include "builtin/builtin.h" #endif diff --git a/lib/stream/timeouts.c b/lib/stream/timeouts.c deleted file mode 100644 index c5b91ef..0000000 --- a/lib/stream/timeouts.c +++ /dev/null @@ -1,67 +0,0 @@ -/* **************************************************************************** - * stream/timeouts.c -- set the timeouts. - * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey - * - * This file is part of libcasio. - * libcasio 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.0 of the License, - * or (at your option) any later version. - * - * libcasio 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libcasio; if not, see . - * ************************************************************************* */ -#include "stream.h" - -/** - * casio_init_timeouts: - * Initialize the timeouts of a libcasio stream. - * - * @arg stream the stream to initialize the timeouts of. - * @arg timeouts the timeouts to set. - * @return the error code (0 if ok). - */ - -int CASIO_EXPORT casio_init_timeouts(casio_stream_t *stream) -{ - static const casio_timeouts_t timeouts = {0, 0, 0}; - - return (casio_set_timeouts(stream, &timeouts)); -} - -/** - * casio_set_timeouts: - * Set the timeouts of a libcasio stream. - * - * @arg stream the stream to set the timeouts of. - * @arg timeouts the timeouts to set. - * @return the error code (0 if ok). - */ - -int CASIO_EXPORT casio_set_timeouts(casio_stream_t *stream, - const casio_timeouts_t *timeouts) -{ - int err; casio_stream_settm_t *s; - - /* check if the callback exists */ - if (!stream) return (casio_error_op); - s = getcb(stream, settm); - failure(!s, casio_error_op) - - /* call it */ - err = (*s)(stream->casio_stream_cookie, timeouts); - failure(err, err) - - /* copy timeouts */ - memcpy(&stream->casio_stream_timeouts, timeouts, - sizeof(casio_timeouts_t)); /* ABI XXX */ - err = 0; -fail: - stream->casio_stream_lasterr = err; - return (err); -} diff --git a/lib/stream/write.c b/lib/stream/write.c index 128a8ed..b1474f2 100644 --- a/lib/stream/write.c +++ b/lib/stream/write.c @@ -25,27 +25,38 @@ * @arg stream the stream to write to. * @arg data the data to write. * @arg size the amount of bytes to write. + * @arg timeout timeout for the entire write (in ms). * @return the error code (0 if ok). */ int CASIO_EXPORT casio_write(casio_stream_t *stream, - const void *data, size_t size) + const void *data, size_t size, unsigned int timeout) { int err; + casio_stream_write_t *wr; /* check if we can write */ - failure(~stream->casio_stream_mode & CASIO_OPENMODE_WRITE, - casio_error_write) - /* write */ - if (!size) return (0); - err = (*getcb(stream, write))(stream->casio_stream_cookie, data, size); - if (err) { + if (~stream->casio_stream_mode & CASIO_OPENMODE_WRITE + || !(wr = stream->casio_stream_callbacks.casio_streamfuncs_write)) { + err = casio_error_write; + goto fail; + } + + /* Check that the job isn't already done. */ + + if (!size) + return (0); + + /* Write the goddamn thing. */ + + if ((err = (*wr)(stream->casio_stream_cookie, data, size, timeout))) { msg((ll_error, "Stream writing failure: %s", casio_strerror(err))); goto fail; } - /* move the cursor and return */ + /* Move the cursor and return. */ + stream->casio_stream_offset += size; err = 0; fail: @@ -59,12 +70,14 @@ fail: * * @arg stream the stream to write to. * @arg car the character to write. + * @arg timeout the timeout to write it. * @return the error code (0 if ok). */ -int CASIO_EXPORT casio_write_char(casio_stream_t *stream, int car) +int CASIO_EXPORT casio_write_char(casio_stream_t *stream, int car, + unsigned int timeout) { - unsigned char ccar = car; + char ccar = (char)car; - return (casio_write(stream, &ccar, 1)); + return (casio_write(stream, &ccar, 1, timeout)); } diff --git a/lib/utils/sleep.c b/lib/utils/sleep.c index bdb6457..97a2f17 100644 --- a/lib/utils/sleep.c +++ b/lib/utils/sleep.c @@ -60,13 +60,13 @@ CASIO_LOCAL void casio_unixsleep(unsigned long ms) CASIO_LOCAL casio_sleep_t *casio_sleep_callback = default_callback; /** - * casio_set_sleep: + * casio_set_sleep_func: * Set the sleep function. * * @arg func the function to set. */ -void CASIO_EXPORT casio_set_sleep(casio_sleep_t *func) +void CASIO_EXPORT casio_set_sleep_func(casio_sleep_t *func) { casio_sleep_callback = func; } diff --git a/lib/utils/timer.c b/lib/utils/timer.c new file mode 100644 index 0000000..f6612ce --- /dev/null +++ b/lib/utils/timer.c @@ -0,0 +1,115 @@ +/* **************************************************************************** + * utils/timer.c -- timer internals. + * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey + * + * This file is part of libcasio. + * libcasio 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.0 of the License, + * or (at your option) any later version. + * + * libcasio 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libcasio; if not, see . + * ************************************************************************* */ +#include "../internals.h" + +/* --- + * Default functions for UNIX. + * --- */ + +#if _POSIX_C_SOURCE >= 199309L +# include + +struct casio_timer_s { + clockid_t clk_id; + struct timespec initial; +}; + +CASIO_LOCAL int default_get_timer(casio_timer_t **timerp) +{ + casio_timer_t *timer; + + if (!(timer = casio_alloc(sizeof(*timer), 1))) + return (casio_error_alloc); + +#ifdef __linux__ + timer->clk_id = CLOCK_MONOTONIC_COARSE; +#else + timer->clk_id = CLOCK_MONOTONIC; +#endif + + if (clock_gettime(timer->clk_id, &timer->initial) < 0) { + casio_free(timer); + return (casio_error_unknown); + } + + *timerp = timer; + return (0); +} + +CASIO_LOCAL void default_free_timer(casio_timer_t *timer) +{ + casio_free(timer); +} + +CASIO_LOCAL int default_get_spent_time(casio_timer_t *timer, + unsigned long *spent) +{ + struct timespec ts; + + if (clock_gettime(timer->clk_id, &ts) < 0) + return (casio_error_unknown); + + *spent = (ts.tv_sec - timer->initial.tv_sec) * 1000 + + (ts.tv_nsec - timer->initial.tv_nsec) / 1000000; + return (0); +} + +#else +# define NO_DEFAULTS 1 +#endif + +/* --- + * Public API functions. + * --- */ + +#if NO_DEFAULTS +CASIO_LOCAL casio_get_timer_t *gettimer = NULL; +CASIO_LOCAL casio_get_spent_time_t *getspenttime = NULL; +#else +CASIO_LOCAL casio_get_timer_t *gettimer = &default_get_timer; +CASIO_LOCAL casio_get_spent_time_t *getspenttime = &default_get_spent_time; +#endif + +#if NO_DEFAULTS || NO_TIMERFREE +CASIO_LOCAL casio_free_timer_t *freetimer = NULL; +#else +CASIO_LOCAL casio_free_timer_t *freetimer = &default_free_timer; +#endif + +int CASIO_EXPORT casio_get_timer(casio_timer_t **timerp) +{ + if (!gettimer) + return (casio_error_op); + return ((*gettimer)(timerp)); +} + +void CASIO_EXPORT casio_free_timer(casio_timer_t *timer) +{ + if (!freetimer) + return ; + (*freetimer)(timer); +} + +int CASIO_EXPORT casio_get_spent_time(casio_timer_t *timer, + unsigned long *spent) +{ + if (!getspenttime) + return (casio_error_op); + return ((*getspenttime)(timer, spent)); +}