diff options
Diffstat (limited to 'docs/user/link.rst')
-rw-r--r-- | docs/user/link.rst | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/docs/user/link.rst b/docs/user/link.rst new file mode 100644 index 0000000..fa2a3ed --- /dev/null +++ b/docs/user/link.rst @@ -0,0 +1,240 @@ +Calculator links +================ + +A link in libcasio represents a calculator over a stream, i.e. the application +level. It is an abstraction which proposes everything the protocols CASIO +calculator use offer, although some operations might not be implemented +behind. + +Links can take the following callbacks: + +.. c:type:: int casio_link_confirm_t(void *cookie) + + The process or the device on the other end requires a confirmation from + the user, for which such as function is called. It shall return ``0`` if + the user has not confirmed, or anything else if it is. + +.. c:type:: void casio_link_progress_t(void *cookie, unsigned int id, \ + unsigned int total) + + Is used for displaying the progress of an operation when it goes + further on. + +Managing a link +--------------- + +Only the library is able to implement link functions, in order to encourage +users to contribute in the library development. Use the following functions to +open and close a link: + +.. c:function:: int casio_open_link(casio_link_t **handlep, \ + unsigned long flags, tio_stream_t *stream) + + Open a link on the given stream. By default, uses the type of the stream + to find out what behaviour to adopt: + + - if the stream is a generic stream, it will try to communicate using P7. + - if the stream is a serial stream, it will try to communicate using CAS50, + and if that failed, it will try to communicate using P7. + - if the stream is a USB stream, it will get the vendor, product, + class, subclass and protocol identifiers: + + - if the protocol is found to be SCSI using the class/subclass/protocol, + then we shall try to communicate using SCSI. + - if the vendor identifier is ``0x07cf`` (“Casio Computer Co., Ltd”), + the product identifier is ``0x6101`` (“fx-9750gII”) and the device + protocol is ``0`` (vendor-specific), then we shall try to communicate + using protocol 7 (P7). + + All of these behaviours are tweakable through the following flags: + + .. c:macro:: CASIO_LINKFLAG_P7 + + We want to enforce protocol 7 on generic and serial streams (and skip + the CAS40 check). + + .. c:macro:: CASIO_LINKFLAG_CAS40 + + We want to speak CAS40 as we know it's an ancient calculator on the + other side (around 1990). + + .. c:macro:: CASIO_LINKFLAG_CAS50 + + We only want to try out CAS50, and not skip to protocol 7 if it + doesn't work. + + .. c:macro:: CASIO_LINKFLAG_CAS100 + + We want to speak CAS50 as we're guessing it's an AFX on the other + side. + + .. c:macro:: CASIO_LINKFLAG_SCSI + + We want to speak SCSI on all kind of devices, through bulk-only + transport on USB and plain SCSI writing on generic streams. + This flag will be ignored on serial streams. + + For protocol 7 streams, by default: + + - we start off as the active device, i.e. the one that will send commands + to the other one. + - we send a check then a discovery packet, in order to find out to what + device we're speaking to and trying to guess what commands are supported + or not. + - if the device is identified to be connected through USB, we shift + packets on data streams in order to go faster. + - we terminate the connection at the end. + + All of these behaviours are tweakable through the following flags: + + .. c:macro:: CASIO_LINKFLAG_PASSIVE + + We want to start out as the passive device (emulate a calculator). + + This will of course disable checks, discovery, packet shifting + and terminating connections as we depend on the other side to + make decisions. + + .. c:macro:: CASIO_LINKFLAG_NOCHECK + + We suppose the connection has already been made by a previous link + (possibly on a previous process) and do not issue the check. + + .. c:macro:: CASIO_LINKFLAG_NODISC + + We do not want to discover what kind of device we have on the other + side, and use fallbacks to guess what commands are supported. Notice + that you shall only use this flag for devices that do not support the + discovery command, as this can be made on an already established link. + + .. c:macro:: CASIO_LINKFLAG_NOSHIFT + + We do not want to do packet shifting on USB devices. This is usually + done for sensitive data packet exchanges, as packet shifting can + theoretically go really bad and make the link irrecoverable, but + that's yet to be seen in practice. + + Packet shifting is not enabled on serial devices because it doesn't + speed up the process at all. + + .. c:macro:: CASIO_LINKFLAG_TERM + + We want to terminate the connection when the link is closed. + +.. c:function:: int casio_open_serial(casio_link_t **handlep, \ + unsigned long flags, char const *name, tio_serial_attrs_t const *attrs) + + Open a serial port using :c:func:`tio_open_serial_port` and the + given serial attributes, and open a link onto it. + +.. c:function:: int casio_open_usb(casio_link_t **handlep, \ + unsigned long flags, int bus, int address) + + Open a USB device using :c:func:`tio_open_usb`, and open a link onto it. + +.. c:function:: void casio_close_link(casio_link_t *handle) + + Close the link and free all the related resources. + +Link-related operations +----------------------- + +In order to get the link information, you shall use the following function: + +.. c:function:: casio_link_info_t const \ + *casio_get_link_info(casio_link_t *handle) + + Get the link information, i.e. the information on the device on the + other side. This function will return generic information in case the + discovery has been disabled. + +For managing serial settings, the following function has your back: + +.. c:function:: int casio_setlink(casio_link_t *handle, \ + tio_serial_attrs_t const *attrs) + + Agrees on serial settings with the device and changes the stream serial + properties on the underlying stream. Not all properties will be read, + generally only the speed, stop bits and parity. + +Screenstreaming +--------------- + +The logic for screenstreaming management in libcasio is kind of an infinite +iterator, using the following function: + +.. c:function:: int casio_get_screen(casio_link_t *handle, \ + casio_picture_t **screenp) + + .. warning:: + + Initialize ``*screenp`` to either ``NULL`` or a valid picture + **before** calling this function! + + Get the next screen that the calculator has sent us. Depending on + ``*screenp``: + + - if it is ``NULL``, then the picture will be allocated and ``*screenp`` + will be set to the newly allocated picture. + - if it is not ``NULL``, then it points to a valid picture which is + either modified if the dimensions of the received screen are the same + as its dimensions, or reallocated if not. + +System-related operations +------------------------- + +CASIO calculators used to provide legit ways to backup different parts of the +system on flash and upload and run special executables using protocol 7, +although it has been removed on modern calculators. These functions implement +these procedures: + +.. c:function:: int casio_backup_rom(casio_link_t *handle, \ + tio_stream_t *buffer, casio_link_progress_t *progress, \ + void *progress_cookie) + + Backup the ROM into the given buffer. + +.. c:function:: int casio_upload_and_run(casio_link_t *handle, \ + tio_stream_t *buffer, unsigned long loadaddr, unsigned long straddr, \ + casio_link_progress_t *progress, void *progress_cookie) + + Upload and run an executable from a stream. The stream is expected to + be a generic stream where the size can be determined by using + :c:func:`tio_get_size`. + + ``loadaddr`` represents where in the calculator's memory the program + shall be loaded (e.g. ``0x88030000``), and ``straddr`` is where the + program shall be started (e.g. ``0x88030000``). Both should be on + 32-bits. + + This function is usually used for uploading code that replaces the + flash's content, but the uploaded code can also serve other purposes + such as simply installing programs, displaying the calculator's info + or run a program to back up the calculator's memory. It is not + dangerous in itself, it's the uploaded code which can be, so as usual, + be careful with what you run on the calculator. + +Main memory-related operations +------------------------------ + +All CASIO calculators have at least a main memory, whatever its format is (for +more about main memories, check out :ref:`mcs`). You can get the function that +manages it through the link using the following: + +.. c:function:: int casio_get_link_mcs(casio_link_t *handle, \ + casio_mcs_t **mcsp) + + Get the main memory management object for the given link. + +Protocol-specific functions +--------------------------- + +While libcasio offers you an abstract interface to any calculator whatever +protocol it is using, you can use the protocols directly for operations it +does not manage. For this, see the following pages: + +.. toctree:: + :maxdepth: 1 + + link/cas + link/seven |