/* **************************************************************************** * libcasio/stream.h -- libcasio stream definition. * 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 . * * The libcasio stream abstraction is there so that the core code can be more * platform-agnostic (althrough platform-specific helpers are built-in for * popular platforms like Microsoft Windows or GNU/Linux distributions). * A stream is basically what separates libcasio from the calculator. * When data is read from the stream, what is expected is what the calculator * has sent, and when data is written to the stream, it is what the calculator * shall receive. * ************************************************************************* */ #ifndef LIBCASIO_STREAM_H # define LIBCASIO_STREAM_H # include "cdefs.h" # include "iter.h" CASIO_BEGIN_NAMESPACE /* Forward structure declarations (don't mind). */ struct casio_stream_s; typedef struct casio_stream_s casio_stream_t; 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_scsi_s; typedef struct casio_scsi_s casio_scsi_t; /* --- * Stream. * --- */ /* The stream is a private structure that has more or less all of the features * that the libc FILE interface has, but has more and is cross-platform. * It is basically what libcasio uses to communicate with the calculator. * * Notice that in case of "partial success" (e.g. parts of the buffer were * written, but not all of it), you shall return an error, because there is * no partial success. * * An open mode represents the type of operations you will be able to * make with a stream. Available open mode flags are: * * `READ`: the stream is readable. * `WRITE`: the stream is writable. * `TRUNC`: the file will be truncated. * `APPEND`: will append to the file. * * `SEEK`: the stream is seekable. * `SERIAL`: serial operations are available. * `SCSI`: SCSI operations are available. * `USB`: USB operations are available. */ typedef unsigned int casio_openmode_t; # define CASIO_OPENMODE_READ 0x0001 # define CASIO_OPENMODE_WRITE 0x0002 # define CASIO_OPENMODE_TRUNC 0x0004 # define CASIO_OPENMODE_APPEND 0x0008 # define CASIO_OPENMODE_SEEK 0x0010 # define CASIO_OPENMODE_SERIAL 0x0020 # define CASIO_OPENMODE_SCSI 0x0040 # define CASIO_OPENMODE_USB 0x0080 /* Offset types, to move within a stream, are the following: * `SET`: set the current position to the offset. * `CUR`: add the offset to the current position. * `END`: set the current position to the end minus the offset. */ typedef long casio_off_t; typedef int casio_whence_t; # define CASIO_SEEK_SET 1 # define CASIO_SEEK_CUR 2 # define CASIO_SEEK_END 4 /* Here are the callback types: */ typedef int casio_stream_close_t OF((void *)); typedef int casio_stream_setattrs_t OF((void *, casio_streamattrs_t const *)); typedef int casio_stream_read_t OF((void *, unsigned char *, size_t, unsigned int /* total timeout in ms */)); typedef int casio_stream_write_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 { casio_stream_close_t *casio_streamfuncs_close; /* General read & write callbacks ("stream" origins). */ casio_stream_read_t *casio_streamfuncs_read; casio_stream_write_t *casio_streamfuncs_write; casio_stream_seek_t *casio_streamfuncs_seek; /* Serial callbacks. */ casio_stream_setattrs_t *casio_streamfuncs_setattrs; /* SCSI callbacks. */ 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; }; /* --- * Stream serial settings ad flags. * --- */ /* Here are the different baud speeds you can encounter, in bauds. * Note that one speed is not supported by all models. */ # define CASIO_B1200 1200 /* old models */ # define CASIO_B2400 2400 /* old models */ # define CASIO_B4800 4800 /* old models */ # define CASIO_B9600 9600 /* protocol seven default speed */ # define CASIO_B19200 19200 /* seven alternative speed */ # define CASIO_B38400 38400 /* algebrafx default speed */ # define CASIO_B57600 57600 /* seven alternative speed */ # define CASIO_B115200 115200 /* seven alternative speed */ /* Here are the control characters and other values you have in the * stream settings. */ # define CASIO_NCCS 0x02 /* number of control characters */ # define CASIO_XON 0x00 /* XON character: re-enable transm. */ # define CASIO_XOFF 0x01 /* XOFF character: disable transm. */ /* From here, those are all in the stream settings flags. * Here are the stop bits settings: */ # define CASIO_STOPBITSMASK 0x0001 # define CASIO_ONESTOPBIT 0x0000 /* one stop bit */ # define CASIO_TWOSTOPBITS 0x0001 /* two stop bits */ /* Here are the parity settings: */ # define CASIO_PARMASK 0x0006 # define CASIO_PARDIS 0x0000 /* disable parity checking */ # define CASIO_PARENB 0x0002 /* enable parity checking */ # define CASIO_PAREVEN 0x0000 /* even parity */ # define CASIO_PARODD 0x0004 /* odd parity */ /* Here are the DTR/RTS settings. * Notice that not all platforms implement this. Just do as you can. */ # define CASIO_DTRMASK 0x0018 # define CASIO_DTRCTL_DISABLE 0x0000 /* disable DTR */ # define CASIO_DTRCTL_ENABLE 0x0008 /* enable DTR */ # define CASIO_DTRCTL_HANDSHAKE 0x0010 /* enable DTR and handshake */ # define CASIO_RTSMASK 0x0060 # define CASIO_RTSCTL_DISABLE 0x0000 /* disable RTS */ # define CASIO_RTSCTL_ENABLE 0x0020 /* enable RTS */ # define CASIO_RTSCTL_HANDSHAKE 0x0040 /* enable RTS and handshake */ /* Here are the XON/XOFF software control settings. * XOFF disables the transmission temporarily, usually because the device at * the other end can't manage too much data too quickly. */ # define CASIO_XONMASK 0x0080 # define CASIO_XONCTL_DISABLE 0x0000 /* disable XON */ # define CASIO_XONCTL_ENABLE 0x0080 /* enable XON */ /* XON re-enables the transmission, probably because the device at the end * has finished processing the data you sent and is ready to process more. */ # define CASIO_XOFFMASK 0x0100 # define CASIO_XOFFCTL_DISABLE 0x0000 /* disable XOFF */ # define CASIO_XOFFCTL_ENABLE 0x0100 /* enable XOFF */ /* --- * Stream settings. * --- */ /* Here is the stream settings structure: */ struct casio_streamattrs_s { /* flags - see the above section */ unsigned int casio_streamattrs_flags; /* speed: one of the CASIO_B* constants */ unsigned int casio_streamattrs_speed; /* characters */ unsigned char casio_streamattrs_cc[CASIO_NCCS]; }; /* --- * SCSI requests. * --- */ /* CASIO's fx-CG devices, also known as Prizms or Graph 90+E, use SCSI along * with Protocol 7.00 to communicate with the PC for things like file * transferring or screenstreaming (which use vendor-specific command slots). * As systems usually have some standard methods for SCSI, it is worth it * to implement an SCSI interface into libcasio streams. * * This is libcasio's SCSI request structure, inspired from Linux's * `sg_io_hdr_t` structure, except this structure tries to be cross-platform * and is just there to fulfill the library's needs. * * Here is the different values for the data direction: * * `NONE`: no content. * `TO_DEV`: outgoing data. * `FROM_DEV`: incoming data. */ # define CASIO_SCSI_DIREC_NONE (-1) # define CASIO_SCSI_DIREC_TO_DEV (-2) # define CASIO_SCSI_DIREC_FROM_DEV (-3) /* And here is the request structure: * * `cmd` is the raw command buffer (of 6, 10, 12 or 16 bytes). * `cmd_len` is the command length (6, 10, 12 or 16). * `direction` is the data transfer direction. * `data` is the data to transfer (send or receive buffer). * `data_len` is the data length. * `status` is the status byte returned by the device. */ struct casio_scsi_s { void *casio_scsi_cmd; size_t casio_scsi_cmd_len; int casio_scsi_direction; void *casio_scsi_data; size_t casio_scsi_data_len; int casio_scsi_status; }; /* It will be sent to the `scsi` callback of the stream. */ /* --- * Public stream functions. * --- */ CASIO_BEGIN_DECLS /* Default stream serial settings utilities. */ CASIO_EXTERN int CASIO_EXPORT casio_make_attrs 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, 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)); /* Get stream various data. */ CASIO_EXTERN int CASIO_EXPORT casio_isreadable OF((casio_stream_t *casio__stream)); CASIO_EXTERN int CASIO_EXPORT casio_iswritable OF((casio_stream_t *casio__stream)); CASIO_EXTERN int CASIO_EXPORT casio_isseekable OF((casio_stream_t *casio__stream)); # define casio_isreadable(CASIO__STREAM) \ (casio_get_openmode(CASIO__STREAM) & CASIO_OPENMODE_READ) # define casio_iswritable(CASIO__STREAM) \ (casio_get_openmode(CASIO__STREAM) & CASIO_OPENMODE_WRITE) # define casio_isseekable(CASIO__STREAM) \ (casio_get_openmode(CASIO__STREAM) & CASIO_OPENMODE_SEEK) # define casio_is_readable(CASIO__STREAM) \ casio_isreadable(CASIO__STREAM) # define casio_is_writable(CASIO__STREAM) \ casio_iswritable(CASIO__STREAM) # define casio_is_seekable(CASIO__STREAM) \ casio_isseekable(CASIO__STREAM) CASIO_EXTERN casio_openmode_t CASIO_EXPORT casio_get_openmode OF((casio_stream_t *casio__stream)); 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 OF((casio_stream_t *casio__stream)); CASIO_EXTERN int CASIO_EXPORT casio_get_lasterr OF((casio_stream_t *casio__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, unsigned int casio__timeout)); CASIO_EXTERN int CASIO_EXPORT casio_write OF((casio_stream_t *casio__stream, 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, unsigned int casio__timeout)); /* Skip bytes from a stream. */ CASIO_EXTERN int CASIO_EXPORT casio_skip OF((casio_stream_t *casio__stream, size_t casio__size)); /* Set and get the attributes of a stream. */ CASIO_EXTERN int CASIO_EXPORT casio_init_attrs OF((casio_stream_t *stream)); CASIO_EXTERN int CASIO_EXPORT casio_set_attrs OF((casio_stream_t *casio__stream, const casio_streamattrs_t *casio__attrs)); CASIO_EXTERN int CASIO_EXPORT casio_get_attrs OF((casio_stream_t *casio__stream, casio_streamattrs_t *casio__attrs)); /* Set and get the timeouts of a stream. */ CASIO_EXTERN int CASIO_EXPORT casio_init_timeouts OF((casio_stream_t *casio__stream)); /* Move in a file. */ CASIO_EXTERN int CASIO_EXPORT casio_seek OF((casio_stream_t *casio__stream, casio_off_t casio__offset, casio_whence_t casio__whence)); CASIO_EXTERN casio_off_t CASIO_EXPORT casio_tell OF((casio_stream_t *casio__stream)); /* Make out the size of a file (shortcut for making out the size). */ CASIO_EXTERN int CASIO_EXPORT casio_getsize OF((casio_stream_t *casio__stream, casio_off_t *casio__size)); /* Make a SCSI request. */ CASIO_EXTERN int CASIO_EXPORT casio_scsi_request OF((casio_stream_t *casio__stream, casio_scsi_t *casio__request)); /* Make a stream out of memory. */ CASIO_EXTERN int CASIO_EXPORT casio_open_memory OF((casio_stream_t **casio__stream, void const *casio__memory, size_t casio__size)); /* Make a stream out of another, with a limit (and empty it). */ CASIO_EXTERN int CASIO_EXPORT casio_open_limited OF((casio_stream_t **casio__stream, casio_stream_t *casio__original, size_t casio__size)); CASIO_EXTERN int CASIO_EXPORT casio_empty_limited OF((casio_stream_t *casio__stream)); /* Make a stream out of another, while calculating a 32-bit checksum. */ CASIO_EXTERN int CASIO_EXPORT casio_open_csum32 OF((casio_stream_t **casio__stream, casio_stream_t *casio__original, casio_uint32_t *casio__csum)); /* --- * USB and serial stream utilities. * --- */ /* Make an iterator to list available serial ports. */ CASIO_EXTERN int CASIO_EXPORT casio_iter_serial OF((casio_iter_t **casio__iterp)); # define casio_next_serial(ITER, NEXTP) \ casio_next((ITER), (void **)(char const **)(NEXTP)) /* Replace the default function to list serial devices. */ typedef int CASIO_EXPORT casio_iter_serial_t OF((casio_iter_t **)); CASIO_EXTERN int CASIO_EXPORT casio_set_iter_serial_func OF((casio_iter_serial_t *casio__func)); /* Open a serial stream. */ 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_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 #endif /* LIBCASIO_STREAM_H */