cake
/
libp7
Archived
1
0
Fork 1
This repository has been archived on 2024-03-16. You can view files and clone it, but cannot push or open issues or pull requests.
libp7/include/libp7/protocol/seven.h

290 lines
14 KiB
C

/* *****************************************************************************
* libp7/protocol/seven.h -- libp7 latest protocol packet I/O interface.
* Copyright (C) 2016-2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libp7.
* libp7 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.
*
* libp7 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 libp7; if not, see <http://www.gnu.org/licenses/>.
*
* Aside from the public and easy interface described in `libp7.h`, you may
* want to have more control on the communication. This file is one of
* the ones: it allows you to exchange packets directly, using Protocol 7.00
* (libp7 internals will take care of the odd details).
* ************************************************************************** */
#ifndef LIBP7_PROTOCOL_SEVEN_H
# define LIBP7_PROTOCOL_SEVEN_H
# include <libp7/types.h>
# include <libp7/stream.h>
# ifdef __cplusplus
extern "C" {
# endif
/* ************************************************************************** */
/* Packets */
/* ************************************************************************** */
/* Protocol 7.00 (the latest proprietary protocol from CASIO) is a protocol
* using several-bytes packets. Every packet, at one exception we'll detail
* later, contains a type, a subtype, an optional payload, and a checksum.
*
* Here are the known packet types: */
typedef int p7_seven_type_t;
# define p7_seven_type_cmd 0x01 /* ask something (initiate a packet flow) */
# define p7_seven_type_data 0x02 /* send some data */
# define p7_seven_type_swp 0x03 /* change roles */
# define p7_seven_type_check 0x05 /* check if there is an interlocutor */
# define p7_seven_type_ack 0x06 /* acknowledge ('okay') */
# define p7_seven_type_ohp 0x0B /* screenstreaming packet */
# define p7_seven_type_nak 0x15 /* acknowledge negatively ('nope') */
# define p7_seven_type_end 0x18 /* end the communication */
/* And here are some aliases, for old code. */
# define p7_seven_type_roleswp p7_seven_type_swp
# define p7_seven_type_error p7_seven_type_nak
# define p7_seven_type_term p7_seven_type_end
# define p7_seven_type_terminate p7_seven_type_end
/* The subtype has a different meaning according to the type it is used with.
* For check packets, it can mean: */
# define p7_seven_chk_ini 0x00 /* initial check */
# define p7_seven_chk_wait 0x01 /* in-communication check, while waiting */
/* For ACK packets: */
# define p7_seven_ack_normal 0x00 /* normal ACK */
# define p7_seven_ack_ow 0x01 /* confirm overwrite */
# define p7_seven_ack_ext 0x02 /* extended ACK */
# define p7_seven_ack_term 0x03 /* ACK, end the communication (0x56) */
/* For NAK packets (error packets): */
typedef int p7_seven_err_t;
typedef p7_seven_err_t p7_seven_error_t;
# define p7_seven_err_resend 0x01 /* checksum/timeout error, resend */
# define p7_seven_err_overwrite 0x02 /* server response: confirm ow? */
# define p7_seven_err_dont_overwrite 0x03 /* denial */
# define p7_seven_err_other 0x04 /* generic error (other errors) */
# define p7_seven_err_fullmem 0x05 /* full memory (terminates comm'!) */
/* For END packets (terminate packets): */
typedef int p7_seven_term_t;
# define p7_seven_term_default 0x00 /* normal termination */
# define p7_seven_term_user 0x01 /* user has interrupted communication */
# define p7_seven_term_timeouts 0x02 /* terminated due to timeouts */
# define p7_seven_term_overwrite 0x03 /* in response to `p7_ow_terminate` */
/* I said there was an exception earlier on, I wasn't lying: screenstreaming
* packets have a different format than other packets. Basically, after the
* type, there is a five-letter subtype (such as "TYP01" or "TYPZ1"), and
* for some types, subheaders. libp7 translates this into a VRAM and a picture
* format, which you can see in the libp7 Protocol 7.00 packet
* representation.
*
* Note that the screenstreaming packet flow is totally different from
* the normal packet flow: it's just the calculator sending its screen
* repeateadly, not expecting any answer from the other side. */
/* ************************************************************************** */
/* Command payload */
/* ************************************************************************** */
/* The command has a payload which contain, even in the cases where they are
* not useful, the overwrite status (OW), the MCS raw data type (DT),
* the file size (FS), and the six arguments (of variable length,
* although they never are above 16 bytes long).
*
* Some commands have a completely different format than others, such as
* the 0x56 command (upload'n'run), which also finishes with a binary zero.
*
* The overwrite status (OW) is useful for when sending a file. It can basically
* say, using the codes: */
typedef int p7_seven_ow_t;
# define p7_seven_ow_confirm 0x00 /* ask for confirmation */
# define p7_seven_ow_terminate 0x01 /* terminate if the file exists */
# define p7_seven_ow_force 0x02 /* force overwriting */
/* With `p7_ow_confirm`, if the file exists, a `p7_err_overwrite` NAK packet,
* then, you will either confirm with an ACK packet, or infirm with a
* `p7_err_dont_overwrite` error packet.
*
* The MCS raw data type (DT) should be used with other arguments that are
* found within the arguments -- it is all documented in libg1m.
* The filesize (FS) is used when sending a file or file information only.
* For some commands (such as 0x4E), it can also be the free capacity.
*
* The arguments usually are:
*
* # | Argument signification | Alternative significations
* --+-------------------------+----------------------------------------
* 1 | Directory name | Setup entry name
* 2 | File name | New directory name (directory renaming)
* | | Setup entry content (ASCII-hex)
* 3 | New directory name | MCS group name
* 4 | New file name |
* 5 | Storage device name |
* 6 | ??? (unused everywhere) |
*
* Whether arguments are used or not depend on the command. */
/* ************************************************************************** */
/* libp7 packet representation */
/* ************************************************************************** */
/* The libp7 Protocol 7.00 packet representation includes all the data
* you could have in a packet. First, here are the buffer sizes: */
# define MAX_VRAM_SIZE 0x28800 /* format size * max_width * max_height */
# define MAX_VRAM_WIDTH 384 /* the maximum encountered VRAM width */
# define MAX_VRAM_HEIGHT 500 /* the maximum encountered VRAM height */
# define MAX_RAWDATA_SIZE 256 /* the maximum raw data size */
# define MAX_CMDARG_SIZE 256 /* the technical maximum argument size */
/* VRAM data isn't decoded directly by libp7 Protocol 7.00 Packet I/O utilities,
* although some functions such as `p7_getscreen` do decode it to a 32-bit
* pixel matrix (easier for the user, and extensible).
*
* Here are the known VRAM types you could get using libp7: */
# define p7_pictype_1bit 0x01
# define p7_pictype_2bit 0x02
# define p7_pictype_3bit 0x03
# define p7_pictype_16bit 0x10
typedef int p7_pictype_t;
/* ************************************************************************** */
/* libp7 Protocol 7.00 packet sending utilities */
/* ************************************************************************** */
/* These are the base functions to send a packet.
* Unless `resp` is zero, it will also get the response to the packet,
* and store its info in the handle's packet representation.
*
* You shouldn't use them directly to send a packet, but here they are: */
extern int p7_seven_send_basic(p7_handle_t *handle,
p7_seven_type_t type, p7ushort_t subtype, int resp);
extern int p7_seven_send_ext(p7_handle_t *handle,
p7_seven_type_t type, p7ushort_t subtype,
const void *data, p7ushort_t size, int resp);
/* Send checks.
* Initial checks are useful to check if there is another device speaking P7
* at the other end of the line.
* Waiting checks are for the other device which is waiting for a command
* not to timeout (which takes six minutes). */
extern int p7_seven_send_check(p7_handle_t *handle);
# define p7_seven_send_ini_check(H) \
(p7_seven_send_basic((H), p7_seven_type_check, p7_seven_chk_ini, 1))
/* Send acknowledgements (ACK packets).
* Basic ACK packets are used for plenty of things (`resp` should always be
* different from zero, as zero for this is used by data exchanging functions).
* Extended ACK is used for sending server information, usually as a response
* to the 0x01 command (sys_getinfo). */
# define p7_seven_send_ack(H, R) \
(p7_seven_send_basic((H), p7_seven_type_ack, 0x00, (R)))
# define p7_seven_confirm_ow(H) \
(p7_seven_send_basic((H), p7_seven_type_ack, 0x01, 1))
extern int p7_seven_send_eack(p7_handle_t *handle, p7_server_t *info);
/* Send negative acknowledgements (NAK packets).
* These are used to report errors. */
# define p7_seven_send_err(H, C) \
(p7_seven_send_basic((H), p7_seven_type_nak, (C), 1))
# define p7_seven_deny_ow(H) \
(p7_seven_send_err((H), p7_seven_err_dont_overwrite))
/* Send termination packets.
* Will end the communication from the handle point of view. */
# define p7_seven_send_term_because(H, R) \
(p7_seven_send_basic((H), p7_seven_type_end, (R), 1))
# define p7_seven_send_term(H) \
(p7_seven_send_term_because((H), p7_seven_term_default))
/* Send a roleswap notice.
* Will pass the handle in passive mode. */
# define p7_seven_send_roleswp(H) \
(p7_seven_send_basic((H), p7_seven_type_swp, 0, 1))
# define p7_seven_send_swp(H) (p7_seven_send_roleswp(H))
/* Here are the base functions for sending a command.
* There are specific command-sending in `libp7/protocol/seven/commands.h`,
* so if you're using a classical command, you should use them instead. */
extern int p7_seven_send_cmd(p7_handle_t *handle, p7ushort_t subtype);
extern int p7_seven_send_cmd_data(p7_handle_t *handle, p7ushort_t subtype,
int overwrite, p7ushort_t datatype, p7uint_t filesize,
const char *arg1, const char *arg2, const char *arg3,
const char *arg4, const char *arg5, const char *arg6);
# include <libp7/protocol/seven/commands.h>
/* ************************************************************************** */
/* Packet flows */
/* ************************************************************************** */
/* Once the communication is initialized (`p7_init` with the
* `p7_flag_active | p7_flag_check` flags takes care of that),
* Protocol 7.00 is basically a set of packet flows.
*
* A packet flow always start with a command from the active side to the
* passive side. Then, once the command is ACK-ed, according to the command,
* different packet flows can occur. Here are a few characteristic examples:
*
* - Simple action. For example, file removing require nothing after the
* command confirmation;
* - File sending. After the overwrite flow, the active side sends data
* packets containing the file data (`p7_send_buffer`/`p7_send_data`);
* - File receiving. The active side sends a role swap packet, then the
* server (now active) does the file sending procedure (with command). Once
* it has finished sending the file, it swaps roles again;
* - File listing. The active side sends a role swap packet, then the
* server (now active) sends file information commands for each entry.
* Once it has finished, it swap roles again.
*
* If you have finished doing what you wanted to do and the communication is
* still active, send an END packet, to which the other calculator should
* respond with an ACK. */
/* ************************************************************************** */
/* libp7 Protocol 7.00 packet flow utilities */
/* ************************************************************************** */
/* Send and receive data, using buffers (see `libp7/buffer.h`).
* This will automatically divide your data into packets, or make up the
* data from packets.
*
* Packet shifting (enabled with `shift != 0`) is a technique discovered by
* Nessotrin (from Planète Casio), and made accessible by Cakeisalie5 in
* libp7. It makes data exchanges quicker.
* It is advised not to use it for receiving data, or for sensitive
* data. */
extern int p7_seven_send_buffer(p7_handle_t *handle, const p7_buffer_t *buffer,
int shift, p7_disp_t disp);
extern int p7_seven_get_buffer(p7_handle_t *handle, const p7_buffer_t *buffer,
p7uint_t size, int shift, p7_disp_t disp);
/* Send and receive data, using memory areas.
* Beyond the buffer/memory difference, those and the previous ones are
* basically the same thing. */
extern int p7_seven_send_data(p7_handle_t *handle, const void *vbuf, \
p7uint_t size, int shift, void (*disp)(p7ushort_t, p7ushort_t));
extern int p7_seven_get_data(p7_handle_t *handle, void *buf, p7uint_t size,
int shift, p7_disp_t disp);
# ifdef __cplusplus
}
# endif
#endif /* LIBP7_PROTOCOL_SEVEN_H */