Contents Menu Expand Light mode Dark mode Auto light/dark, in light mode Auto light/dark, in dark mode Skip to content
Cahute 0.6
Logo
Cahute 0.6
  • Installation guides
    • Installing Cahute on Linux distributions
    • Installing Cahute on macOS / OS X
    • Installing Cahute on Microsoft Windows
    • Installing Cahute on AmigaOS
  • Build from source guides
    • Building Cahute for Linux distributions
    • Building Cahute for macOS / OS X
    • Building Cahute for Microsoft Windows
    • Building Cahute for AmigaOS
  • Contribution guides
    • Contributing to Cahute
    • Reporting a bug or vulnerability
    • Requesting a feature
    • Packaging Cahute
    • Creating a merge request
  • Command line user guides
    • Getting information regarding a calculator
    • Sending a file to a calculator’s storage memory
    • Getting a file from the calculator’s storage memory
    • Displaying the screen from a calculator
  • Developer guides
    • Building with the Cahute library
    • Using device detection
      • Listing calculators connected by USB
      • Listing available serial ports
    • Using links
      • Opening a link to a calculator connected by USB
      • Opening a generic link to a calculator connected by serial
    • Reading and writing files
      • Guessing the type of a file
    • Using text conversion utilities
      • Converting text from an encoding to another
  • Miscellaneous guides
    • Getting started with Cahute in Visual Studio
    • Capturing USB communications on Windows using Wireshark
  • Data formats
    • Number formats
    • Picture formats
    • Text encodings
    • File formats
      • fx-CG add-ins
      • fx-9860G add-ins
      • Calculator Text Format (CTF)
      • CASIOLINK archives
      • casrc configuration file
      • Catalog files (CAT)
      • e-Activity files
      • fx-CG f-key files
      • fx-9860G f-key files
      • FX Program (FXP)
      • GraphCard file format
      • fx-CG language files
      • fx-9860G language files
      • Main memory archives
      • fx-CG picture
      • fx-CP picture
  • Communication protocols
    • Rationales behind the communication protocols
    • Transport medium and protocols
    • USB detection for CASIO calculators
    • CASIOLINK protocols – Serial protocols used by pre fx-9860G calculators
    • CAS40 protocol – Serial protocol used by pre-1996 calculators
      • CAS40 packet format
      • CAS40 data types
      • CAS40 flows
    • CAS50 protocol – Serial protocol used by calculators from 1996 to 2004
      • CAS50 packet format
      • CAS50 data types
      • CAS50 flows
    • CAS100 protocol – Serial protocol used by AFX / Graph 100
      • CAS100 packet format
      • CAS100 data types
      • CAS100 flows
    • CAS300 – Serial and USB protocol used by Classpad 300 / 330 (+)
      • CAS300 packet format
      • CAS300 commands
      • CAS300 flows
    • Protocol 7.00 – Serial and USB protocol used by post fx-9860G calculators
      • Specific formats for Protocol 7.00
      • Protocol 7.00 packet format
      • Protocol 7.00 communication flows
      • Known Protocol 7.00 commands by CASIO
      • Known Protocol 7.00 command extensions in fxRemote
      • Protocol 7.00 use cases
      • Known hardware identifiers for Protocol 7.00
    • Protocol 7.00 Screenstreaming – fx-9860G and fx-CG screenstreaming
      • Protocol 7.00 Screenstreaming packet format
      • Protocol 7.00 Screenstreaming communication flows
    • USB Mass Storage (UMS)
  • Cahute features
    • System compatibility
    • Contexts
    • Links and mediums
    • Files
    • Main memory data
    • Logging facilities
  • Cahute internals
    • Internal compatibility utilities
    • Links and medium internals
    • File internals
    • Characters, encodings and conversions
  • Command line reference
    • CaS command-line reference
    • p7 command line reference
    • p7os command line reference
    • p7screen command line reference
    • xfer9860 command line reference
  • Header reference
    • <cahute.h> – Main header for Cahute
      • <cahute/cdefs.h> – Basic definitions for Cahute
      • <cahute/config.h> – Cahute configuration details
      • <cahute/context.h> – Context management for Cahute
      • <cahute/data.h> – Calculator data resource and methods for Cahute
      • <cahute/detection.h> – Device detection for Cahute
      • <cahute/error.h> – Error definitions for Cahute
      • <cahute/file.h> – File related utilities for Cahute
      • <cahute/link.h> – Calculator link resource and methods for Cahute
      • <cahute/logging.h> – Logging control for Cahute
      • <cahute/path.h> – Path related utilities for Cahute
      • <cahute/picture.h> – Picture format related utilities for Cahute
      • <cahute/text.h> – Text encoding related utilities for Cahute
  • CMake setting reference
  • Project management
    • Project governance
    • Git and release versioning
    • Community feedback
    • Contribution style
    • Coding style
Back to top

Links and medium internals¶

This document describes the internals behind links and mediums; see Links and mediums for more information.

A link only requires one memory allocation (except for system resources that are allocated / opened using different functions), and the medium and the protocol are initialized together using link opening functions.

Mediums¶

Mediums define a common set of interfaces that can be used by protocols to communicate with the device or host.

A medium is represented by the following type:

struct cahute_link_medium¶

Link medium representation.

This structure is usually directly allocated with the link, i.e. cahute_link instance, and is accessed through link->medium.

Medium interface¶

Most mediums support a stream-like interface with the following functions:

int cahute_receive_on_link_medium(cahute_link_medium *medium, cahute_u8 *buf, size_t size, unsigned long first_timeout, unsigned long next_timeout)¶

Read exactly size bytes of data into the buffer.

This function uses the medium read buffer to store any incoming excess data, for it to be processed first next time before using the underlying buffer to read more data.

Warning

This function does not provide the number of bytes that have been read in case of error (with the exception of CAHUTE_ERROR_TIMEOUT_START, which implies that no bytes have been read).

This is to simplify as much as possible protocol implementations, but it also means that the medium should be considered irrecoverable in such cases.

Errors to be expected from this function are the following:

CAHUTE_ERROR_TIMEOUT_START

The first byte was not received in a timely manner. This can only occur if first_timeout was not set to 0.

CAHUTE_ERROR_TIMEOUT

A byte past the first one was not received in a timely manner. This can only occur if next_timeout was not set to 0.

CAHUTE_ERROR_GONE

The device is no longer present, usually either because the USB cable has been unplugged on one end or the other, or the serial adapter has been unplugged from the host.

CAHUTE_ERROR_UNKNOWN

The medium-specific operations have yielded an error code that Cahute did not interpret. Some details can usually be found in the logs.

Parameters:
  • medium – Link medium to receive data from.

  • buf – Buffer in which to write the received data.

  • size – Size of the data to write to the buffer.

  • first_timeout – Maximum delay to wait before the first byte of the data, in milliseconds. If this is set to 0, the first byte will be awaited indefinitely.

  • next_timeout – Maximum delay to wait between two bytes of the data, or before the last byte, in milliseconds. If this is set to 0, next bytes will be awaited indefinitely.

Returns:

Error, or CAHUTE_OK.

int cahute_send_on_link_medium(cahute_link_medium *medium, cahute_u8 const *buf, size_t size)¶

Write exactly size bytes of data to the link.

Errors to be expected from this function are the following:

CAHUTE_ERROR_GONE

The device is no longer present, usually either because the USB cable has been unplugged on one end or the other, or the serial adapter has been unplugged from the host.

CAHUTE_ERROR_UNKNOWN

The medium-specific operations have yielded an error code that Cahute did not interpret. Some details can usually be found in the logs.

Parameters:
  • medium – Link medium to send data to.

  • buf – Buffer from which to read the data to send.

  • size – Size of the data to read and send.

Returns:

Error, or CAHUTE_OK.

Serial mediums such as CAHUTE_LINK_MEDIUM_POSIX_SERIAL or CAHUTE_LINK_MEDIUM_WIN32_SERIAL support changing the parameters of the serial link using the following function:

int cahute_set_serial_params_to_link_medium(cahute_link_medium *medium, unsigned long flags, unsigned long speed)¶

Set the serial parameters to the medium.

Accepted flags are a subset of the flags for cahute_open_serial_link():

  • CAHUTE_SERIAL_STOP_* (stop bits);

  • CAHUTE_SERIAL_PARITY_* (parity);

  • CAHUTE_SERIAL_XONXOFF_* (XON/XOFF software control);

  • CAHUTE_SERIAL_DTR_* (DTR hardware control);

  • CAHUTE_SERIAL_RTS_* (RTS hardware control).

Parameters:
  • medium – Link medium to set the serial parameters to.

  • flags – Flags to set to the medium.

  • speed – Speed to set to the medium.

Returns:

Error, or CAHUTE_OK.

USB Mass Storage mediums support an interface capable of making SCSI requests, with the following functions:

int cahute_scsi_request_to_link_medium(cahute_link_medium *medium, cahute_u8 const *command, size_t command_size, cahute_u8 const *data, size_t data_size, int *statusp)¶

Emit an SCSI request to the medium, with or without data.

Parameters:
  • medium – Link medium to send the command and optional payload to, and receive the status from.

  • command – Command to send.

  • command_size – Size of the command to send.

  • data – Optional data to send along with the command. This can be set to NULL if data_size is set to 0.

  • data_size – Size of the data to send along with the command.

  • statusp – Pointer to the status code to set to the one returned by the device.

Returns:

Error, or CAHUTE_OK.

int cahute_scsi_request_from_link_medium(cahute_link_medium *medium, cahute_u8 const *command, size_t command_size, cahute_u8 *buf, size_t buf_size, int *statusp)¶

Emit an SCSI request to the medium, while requesting data.

Parameters:
  • medium – Link medium to send the command to, and receive the data and status from.

  • command – Command to send.

  • command_size – Size of the command to send.

  • buf – Buffer to fill with the requested data.

  • buf_size – Size of the data to request.

  • statusp – Pointer to the status code to set to the one returned by the device.

Returns:

Error, or CAHUTE_OK.

Available medium types¶

Medium types are represented as CAHUTE_LINK_MEDIUM_* constants internally.

Warning

The medium constants are only represented if they are available on the current configuration. This is a simple way for medium-specific implementations to be defined or not, with #ifdef.

Available mediums are the following:

CAHUTE_LINK_MEDIUM_POSIX_SERIAL¶

Serial transport using the POSIX API, with a file descriptor (fd):

  • Closing using close(2);

  • Receiving uses select(2) and read(2);

  • Sending uses write(2);

  • Serial params setting uses termios(3), including tcdrain(), and tty_ioctl(4), especially TIOCMGET and TIOCMSET.

Only available on platforms considered POSIX, including Apple’s OS X explicitely (since they do not define the __unix__ constant like Linux does).

CAHUTE_LINK_MEDIUM_AMIGAOS_SERIAL¶

Serial transport using AmigaOS serial I/O, as described in the AmigaOS Serial Device Guide.

CAHUTE_LINK_MEDIUM_WIN32_SERIAL¶

Serial transport using the Windows API, with a HANDLE and Overlapped I/O:

  • Closing uses CloseHandle;

  • Receiving uses ReadFile and WaitForSingleObject, and depending on whether the second function succeeded or not, either GetOverlappedResult or CancelIo, to ensure we don’t have any buffer writes post-freeing the link;

  • Sending uses WriteFile and WaitForSingleObject, and depending on whether the second function succeeded or not, either GetOverlappedResult or CancelIo, to ensure we don’t have any buffer reads post-freeing the link;

  • Serial params setting uses SetCommState.

For more information, see Serial Communications in Win32.

CAHUTE_LINK_MEDIUM_WIN32_CESG¶

Serial transport over USB bulk or stream-only operations for USB Mass Storage (UMS) transport using CASIO’s CESG502 driver through the Windows API.

As described in Windows USB drivers, we must detect if the device driver is CESG502 or a libusb-compatible driver by using SetupAPI or CfgMgr32, and use this medium in the first case.

It is used with a HANDLE and Overlapped I/O:

  • Closing uses CloseHandle;

  • Receiving uses ReadFile and WaitForSingleObject, and depending on whether the second function succeeded or not, either GetOverlappedResult or CancelIo, to ensure we don’t have any buffer writes post-freeing the link;

  • Sending uses WriteFile and WaitForSingleObject, and depending on whether the second function succeeded or not, either GetOverlappedResult or CancelIo, to ensure we don’t have any buffer reads post-freeing the link.

Note that CESG502 waits for calculator input by default, and always requires a buffer bigger than the actual input it receives (4 KiB is usually enough). It also abstracts away whether it using bulk transfers directly, or USB Mass Storage, into a stream interface; this however does not allow you to make SCSI requests directly.

CAHUTE_LINK_MEDIUM_WIN32_UMS¶

USB Mass Storage (UMS) transport using the Windows API.

It is used with a HANDLE:

  • Closing uses CloseHandle;

  • Requesting using SCSI uses DeviceIoControl with IOCTL_SCSI_PASS_THROUGH_DIRECT.

CAHUTE_LINK_MEDIUM_LIBUSB¶

Serial transport over USB bulk using libusb.

It is used with a libusb_device_handle, opened using a libusb_context:

  • Closing uses libusb_close on the device handle, and libusb_exit on the libusb context;

  • Receiving and sending uses libusb_bulk_transfer.

CAHUTE_LINK_MEDIUM_LIBUSB_UMS¶

USB Mass Storage (UMS) transport using libusb.

As for CAHUTE_LINK_MEDIUM_LIBUSB, it is used with a libusb_device_handle, opened using a libusb_context:

  • Closing uses libusb_close on the device handle, and libusb_exit on the libusb context;

  • Requesting using SCSI uses libusb_bulk_transfer with manual reading and writing of the Command Block Wrapper (CBW) and Command Status Wrapper (CSW).

See USB Mass Storage Class, Bulk-Only Transport for more information on CBW and CSW format and protocol in general.

Protocols¶

Protocols define what operations and logics are available, and how to implement these operations and logics.

All protocols may use the data buffer, which is in the link directly, which serves at storing raw data or screen data received using the protocol.

Available protocols are:

CAHUTE_LINK_PROTOCOL_SERIAL_NONE¶

No protocol on a serial medium.

This can be selected by the user in order to use the medium functions more directly, through the ones referenced in Link medium access related function declarations.

CAHUTE_LINK_PROTOCOL_SERIAL_CAS¶

Generic CASIOLINK on a serial medium.

This can only be used when in receiver mode, i.e. CAHUTE_LINK_FLAG_RECEIVER must be present for this protocol to actually be useful.

See CASIOLINK protocols – Serial protocols used by pre fx-9860G calculators for more information.

CAHUTE_LINK_PROTOCOL_SERIAL_CAS40¶

CAS40 on a serial medium.

See CAS40 protocol – Serial protocol used by pre-1996 calculators for more information.

CAHUTE_LINK_PROTOCOL_SERIAL_CAS50¶

CAS50 on a serial medium.

See CAS50 protocol – Serial protocol used by calculators from 1996 to 2004 for more information.

CAHUTE_LINK_PROTOCOL_SERIAL_CAS100¶

CAS100 on a serial medium.

See CAS100 protocol – Serial protocol used by AFX / Graph 100 for more information.

CAHUTE_LINK_PROTOCOL_SERIAL_CAS300¶

CAS300 on a serial medium.

See CAS300 – Serial and USB protocol used by Classpad 300 / 330 (+) for more information.

CAHUTE_LINK_PROTOCOL_SERIAL_SEVEN¶

Protocol 7.00 over a serial medium.

See Protocol 7.00 – Serial and USB protocol used by post fx-9860G calculators for more information.

This differs from CAHUTE_LINK_PROTOCOL_USB_SEVEN by the availability of command 02 “Set link settings”.

CAHUTE_LINK_PROTOCOL_SERIAL_SEVEN_OHP¶

Protocol 7.00 Screenstreaming over a serial medium.

See Protocol 7.00 Screenstreaming – fx-9860G and fx-CG screenstreaming for more information.

CAHUTE_LINK_PROTOCOL_USB_NONE¶

No protocol on a USB medium.

This can be selected by the user in order to use the medium functions more directly, through the ones referenced in Link medium access related function declarations.

CAHUTE_LINK_PROTOCOL_USB_CAS300¶

CAS300 over USB bulk transport.

See CAS300 – Serial and USB protocol used by Classpad 300 / 330 (+) for more information.

CAHUTE_LINK_PROTOCOL_USB_SEVEN¶

Protocol 7.00 over USB bulk transport or USB Mass Storage or USB Mass Storage commands.

See Protocol 7.00 – Serial and USB protocol used by post fx-9860G calculators and USB Mass Storage (UMS) for more information.

CAHUTE_LINK_PROTOCOL_USB_SEVEN_OHP¶

Protocol 7.00 Screenstreaming over USB bulk transport or USB Mass Storage extended commands.

See Protocol 7.00 Screenstreaming – fx-9860G and fx-CG screenstreaming and USB Mass Storage (UMS) for more information.

CAHUTE_LINK_PROTOCOL_USB_MASS_STORAGE¶

USB Mass Storage without extensions.

Opening behaviours¶

In this section, we will describe the behaviour of link opening functions.

cahute_open_serial_link()

This function first validates all params to ensure compatibility, e.g. throws an error in case of unsupported flag, speed, or combination.

Note

The protocol is selected, depending on the flags, to one of the following:

  • CAHUTE_LINK_PROTOCOL_SERIAL_NONE;

  • CAHUTE_LINK_PROTOCOL_SERIAL_CAS;

  • CAHUTE_LINK_PROTOCOL_SERIAL_CAS40;

  • CAHUTE_LINK_PROTOCOL_SERIAL_CAS50;

  • CAHUTE_LINK_PROTOCOL_SERIAL_CAS100;

  • CAHUTE_LINK_PROTOCOL_SERIAL_CAS300;

  • CAHUTE_LINK_PROTOCOL_SERIAL_SEVEN;

  • CAHUTE_LINK_PROTOCOL_SERIAL_SEVEN_OHP.

Then, depending on the platform:

  • On POSIX and compatible, it will attempt to open the serial device using open(2). If this succeeds, the medium of the created link will be set to CAHUTE_LINK_MEDIUM_POSIX_SERIAL;

  • On Windows, it will attempt to open the serial device using CreateFile, then, if it succeeds, call SetCommTimeouts with ReadTimeoutInterval set to MAXDWORD in order to only read what is directly available, and create the event for the overlapped object using CreateEvent. If this succeeds, the medium of the created link will be set to CAHUTE_LINK_MEDIUM_WIN32_SERIAL;

  • Otherwise, it will return CAHUTE_ERROR_IMPL.

If the underlying medium has successfully been opened, it will allocate the link and call cahute_set_serial_params_to_link() to set the initial serial parameters to it.

It will then initialize the protocol using the common protocol initialization procedure; see Protocol initialization.

cahute_open_usb_link()

This function first validates all params to ensure compatibility, e.g. throws an error in case of unsupported flag or combination.

If libusb support has been disabled, the function returns CAHUTE_ERROR_IMPL.

Otherwise, on all platforms, this function creates a context using libusb_init, gets the device list using libusb_get_device_list, and finds one matching the provided bus and address numbers using libusb_get_bus_number and libusb_get_device_address on every entry.

If a matching device is found, the configuration is obtained using libusb_get_device_descriptor and libusb_get_active_config_descriptor, in order to:

  • Get the vendor (VID) and product (PID) identifiers, to ensure they match one of the known combinations for CASIO calculators.

  • Get the interface class (bInterfaceClass) to determine the protocol and medium type.

  • In both cases, ensure that the bulk IN and OUT endpoints exist, and get their endpoint identifiers.

Note

While historical implementations of CASIO’s protocols using libusb hardcode 0x82 as Bulk IN and 0x01 as Bulk OUT, this has proven to change on other platforms such as OS X; see #3 (comment 1823215641) for more context.

The interface class, CAHUTE_USB_OHP flag presence, and CAHUTE_USB_SEVEN or CAHUTE_USB_CAS300 flag presence to protocol and medium type mapping is the following:

(in) Intf. class

(in) OHP flag

(in) SEVEN or CAS300

(out) Medium

(out) Protocol

8

absent

CAHUTE_LINK_MEDIUM_LIBUSB_UMS

CAHUTE_LINK_PROTOCOL_USB_MASS_STORAGE

8

present

CAHUTE_LINK_MEDIUM_LIBUSB_UMS

CAHUTE_LINK_PROTOCOL_USB_SEVEN_OHP

255

present

CAHUTE_LINK_MEDIUM_LIBUSB

CAHUTE_LINK_PROTOCOL_USB_SEVEN_OHP

255

absent

CAS300

CAHUTE_LINK_MEDIUM_LIBUSB

CAHUTE_LINK_PROTOCOL_USB_CAS300

255

absent

SEVEN

CAHUTE_LINK_MEDIUM_LIBUSB

CAHUTE_LINK_PROTOCOL_USB_SEVEN

255

absent

none

CAHUTE_LINK_MEDIUM_LIBUSB

CAHUTE_LINK_PROTOCOL_USB_CAS300, CAHUTE_LINK_PROTOCOL_USB_SEVEN or CAHUTE_LINK_PROTOCOL_USB_SEVEN_OHP.

See USB detection for CASIO calculators for more information.

Warning

If CAHUTE_USB_NOPROTO flag is passed, the medium is kept, but the protocol is replaced by CAHUTE_LINK_PROTOCOL_USB_NONE.

Once all metadata has been gathered, the function opens the device using libusb_open, and attempt to claim its interface using libusb_claim_interface and libusb_detach_kernel_driver.

Note

Access errors, i.e. any of these two functions returning LIBUSB_ERROR_ACCESS, are ignored, since libusb is still able to communicate with the device on some platforms afterwards.

See #3 for more context.

If the device opening yields LIBUSB_ERROR_NOT_SUPPORTED, it means that the device is running a driver that is not supported by libusb.

On Windows, in this case, we look for a USB device with a device address equal to the libusb port number, obtained using libusb_get_port_number, then:

  • If the underlying driver to the device is identified as CESG502, we use the USB device interface as a CAHUTE_LINK_MEDIUM_WIN32_CESG medium;

  • Otherwise, we look for disk drive then volume devices via bus relations, and use the volume device interface as a CAHUTE_LINK_MEDIUM_WIN32_UMS medium.

Once all is done, the link is created with the selected medium and protocol. The function will then initialize the protocol using the common protocol initialization procedure; see Protocol initialization.

cahute_open_simple_usb_link()

This function is a convenience function, using mostly public functions to work:

  • It detects available USB devices using cahute_detect_usb(). It only picks USB devices matching the provided filter(s) which, if non-zero, act as an accepted device type mask, i.e.:

    • If CAHUTE_USB_FILTER_SERIAL is set, devices identifying as a CASIOLINK, Protocol 7.00 or Protocol 7.00 Screenstreaming device are accepted;

    • If CAHUTE_USB_FILTER_UMS is set, devices identifying as an USB Mass Storage speaking calculator are accepted.

    If this function finds no matching devices, it sleeps and retries until it has no attempts left. If it finds multiple, it fails with error CAHUTE_ERROR_TOO_MANY.

  • It opens the found USB device using cahute_open_usb_link().

It used to be to the program or library to define by itself, and was in the guides, but this behaviour is found in most simple scripts that use the Cahute library, so it was decided to include it within the library.

Protocol initialization¶

The common protocol initialization procedure is defined by a function named init_link in link/open.c.

First of all, if the selected protocol is automatic detection, the communication initialization is used to determine the protocol in which both devices should communicate.

Note

Since the initialization step is necessary for automatic protocol discovery to take place:

  • The CAHUTE_SERIAL_NOCHECK flag is forbidden with CAHUTE_SERIAL_PROTOCOL_AUTO.

  • The CAHUTE_USB_NOCHECK flag is forbidden if neither CAHUTE_USB_SEVEN nor CAHUTE_USB_CAS300 is provided.

Then, the initialization sequence is run depending on the protocol and role (sender or receiver, depending on the presence of the CAHUTE_SERIAL_RECEIVER CAHUTE_USB_RECEIVER in the flags of the original function).

Next
File internals
Previous
Internal compatibility utilities
Copyright © 2024, Thomas Touhey
Made with Sphinx and @pradyunsg's Furo
On this page
  • Links and medium internals
    • Mediums
      • Medium interface
      • Available medium types
    • Protocols
    • Opening behaviours
      • Protocol initialization