238 lines
8.0 KiB
C
238 lines
8.0 KiB
C
/* ************************************************************************** */
|
|
/* _____ _ */
|
|
/* libp7/internals.h |_ _|__ _ _| |__ ___ _ _ */
|
|
/* | Project: libp7 | |/ _ \| | | | '_ \ / _ \ | | | */
|
|
/* | | (_) | |_| | | | | __/ |_| | */
|
|
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
|
/* Last updated: 2017/01/04 15:01:48 |___/ */
|
|
/* */
|
|
/* ************************************************************************** */
|
|
#ifndef LIBP7_INTERNALS_H
|
|
# define LIBP7_INTERNALS_H
|
|
# include <libp7.h>
|
|
# include <libp7/packetio.h>
|
|
# include <libp7/stream.h>
|
|
# include <libp7/internals/stdio_ext.h>
|
|
# include <libp7/internals/endian.h>
|
|
# define DEFAULT_BAUDRATE P7_B9600
|
|
|
|
/* Macros */
|
|
# ifndef min
|
|
# define min(A, B) ((A) < (B) ? (A) : (B))
|
|
# endif
|
|
# ifndef max
|
|
# define max(A, B) ((A) > (B) ? (A) : (B))
|
|
# endif
|
|
|
|
/* ************************************************************************** */
|
|
/* Buffer sizes */
|
|
/* ************************************************************************** */
|
|
/**
|
|
* MAX_RAWDFLD_SIZE:
|
|
* Max raw data field size.
|
|
*
|
|
* > id (4 bytes) + total (4 bytes) + data
|
|
*/
|
|
|
|
# define MAX_RAWDFLD_SIZE (8 + MAX_RAWDATA_SIZE)
|
|
|
|
/**
|
|
* MAX_ENCDFLD_SIZE:
|
|
* Max encoded data field size.
|
|
*
|
|
* > id (4 bytes) + total (4 bytes) + encoded data
|
|
* The worst case is where every byte has to be encoded (an '\' has to be
|
|
* added), so the size of the worst (biggest) case is MAX_RAWDFLD_SIZE * 2.
|
|
*/
|
|
|
|
# define MAX_ENCDFLD_SIZE (8 + (MAX_RAWDATA_SIZE * 2))
|
|
|
|
/**
|
|
* MAX_PACKET_SIZE:
|
|
* Max packet size.
|
|
*
|
|
* Used to be :
|
|
* > t + st + ext + encoded D field + checksum + nullbyte
|
|
* > 8 + MAX_ENCDFLD_SIZE + 2 + 1
|
|
*
|
|
* But with OHP (screen streaming) introduction, this size wasn't enough to
|
|
* store screen streaming packets. So we use the OHP packet size as a
|
|
* reference, even for normal protocol, in case user launches "normal" packet
|
|
* mode and the calculator sends OHP packets. The formula is :
|
|
*
|
|
* > ohp type + pic data + checksum
|
|
*/
|
|
|
|
# define MAX_PACKET_SIZE (6 + MAX_VRAM_SIZE + 2)
|
|
|
|
/* ************************************************************************** */
|
|
/* Timeouts */
|
|
/* ************************************************************************** */
|
|
/* Active timeout - waiting for a direct answer */
|
|
# define ACTIVE_TIMEOUT (10 * 1000)
|
|
|
|
/* Idle timeout - waiting for a command */
|
|
# define IDLE_TIMEOUT (6 * 60 * 1000)
|
|
|
|
/* ************************************************************************** */
|
|
/* Environments */
|
|
/* ************************************************************************** */
|
|
/* main structure */
|
|
typedef struct {
|
|
const char *model; /* model identifier */
|
|
const char *name; /* name */
|
|
unsigned int mask; /* the supported commands mask bit */
|
|
} p7_env_t;
|
|
|
|
/* environment functions */
|
|
p7_env_t *p7_get_env(const char *model);
|
|
int p7_command_is_supported(unsigned int code, const p7_env_t *env);
|
|
# define command_is_supported(N) p7_command_is_supported(N, handle->_env)
|
|
|
|
/* ************************************************************************** */
|
|
/* Handle-related */
|
|
/* ************************************************************************** */
|
|
/* main structure */
|
|
struct p7_handle_s {
|
|
/* was allocated */
|
|
int _wasalloc;
|
|
|
|
/* stream */
|
|
p7_stream_t *_stream;
|
|
p7_stream_t _stream_data;
|
|
|
|
/* current server and environment */
|
|
p7_server_t _server;
|
|
const p7_env_t *_env;
|
|
|
|
/* active status */
|
|
int _active;
|
|
/* shift status */
|
|
int _shifted;
|
|
/* was terminated */
|
|
int _terminated;
|
|
/* should terminate */
|
|
int _term;
|
|
/* last sent command */
|
|
p7ushort_t _last_sent_command;
|
|
/* response */
|
|
p7_packet_t *_response;
|
|
p7_packet_t _response_data;
|
|
|
|
/* raw sending packet buffers */
|
|
unsigned char _send_buffers[2][MAX_PACKET_SIZE];
|
|
size_t _send_buffers_size[2];
|
|
int _send_buffer_id;
|
|
/* raw reception packet buffer */
|
|
unsigned char _recv_buffer[MAX_PACKET_SIZE + 1];
|
|
|
|
/* name - a space/null, 8 characters max, then imposed null char. */
|
|
char _name[10];
|
|
};
|
|
|
|
/* sub-sub-init utils */
|
|
# ifndef P7_DISABLED_FILE
|
|
int _p7_finit(p7_handle_t **handle, unsigned int flags,
|
|
FILE *rstream, FILE *wstream, int rstream_close);
|
|
# endif
|
|
|
|
/* ************************************************************************** */
|
|
/* Packet I/O */
|
|
/* ************************************************************************** */
|
|
/* Checks */
|
|
int p7_send_ini_check(p7_handle_t *handle);
|
|
|
|
/* decode packets */
|
|
int p7_decode_command(p7_handle_t *handle,
|
|
const unsigned char *data, size_t data_size);
|
|
int p7_decode_ack(p7_handle_t *handle,
|
|
const unsigned char *data, size_t data_size);
|
|
int p7_decode_data(p7_handle_t *handle,
|
|
const void *raw, p7ushort_t raw_size);
|
|
|
|
/* utilities */
|
|
int p7_send_again(p7_handle_t *handle);
|
|
int p7_recv(p7_handle_t *handle, int checksum);
|
|
|
|
/* Resend error packet (meant to be used with recv, not suited for public) */
|
|
int p7_send_err_resend(p7_handle_t *handle);
|
|
/* Check packet (meant to be used with recv, not suited for public) */
|
|
int p7_send_check(p7_handle_t *handle);
|
|
|
|
/* active response */
|
|
# define response (*handle->_response)
|
|
|
|
/* ************************************************************************** */
|
|
/* Macros */
|
|
/* ************************************************************************** */
|
|
/* check if handle is initialized */
|
|
# define chk_handle(H) \
|
|
if (!(H)) return (p7_error_uninitialized); \
|
|
if ((H)->_terminated) return (p7_error_terminated);
|
|
|
|
/* check if active */
|
|
# define chk_active(H) \
|
|
if (!(H)->_active) return (p7_error_active)
|
|
|
|
/* check if passive */
|
|
# define chk_passive(H) \
|
|
if ((H)->_active) return (p7_error_active)
|
|
|
|
/* check if filename is ok */
|
|
# define chk_filename(F) \
|
|
if ((F) && !p7_validate_filename(F)) return (p7_error_filename)
|
|
|
|
/* check if filename is there and ok */
|
|
# define chk_required_filename(F) \
|
|
if (!(F) || !p7_validate_filename(F)) return (p7_error_filename)
|
|
|
|
/* check if dirname is ok */
|
|
# define chk_dirname(D) \
|
|
if ((D) && !p7_validate_dirname(D)) return (p7_error_dirname)
|
|
|
|
/* check if filestream is readable */
|
|
# define chk_isread(F) \
|
|
if (!(F) || !__freadable(F)) return (p7_error_noread)
|
|
|
|
/* check if filestream is writable */
|
|
# define chk_iswrite(F) \
|
|
if (!(F) || !__fwritable(F)) return (p7_error_nowrite)
|
|
|
|
/* check if filesize is ok */
|
|
# define chk_filesize(S) \
|
|
if (!(S)) return (p7_error_empty); \
|
|
if ((S) > UINT32_MAX) return (p7_error_fullmem)
|
|
|
|
/* check if buffer is readable */
|
|
# define chk_bufread(B) \
|
|
if (!(B) || !(B)->read) return (p7_error_noread)
|
|
|
|
/* check if buffer is writable */
|
|
# define chk_bufwrite(B) \
|
|
if (!(B) || !(B)->write) return (p7_error_nowrite)
|
|
|
|
/* ************************************************************************** */
|
|
/* Utilities */
|
|
/* ************************************************************************** */
|
|
/* File/buffer callbacks */
|
|
# ifndef P7_DISABLED_FILE
|
|
int p7_filebuffer_read(void *cookie, unsigned char *dest, size_t size);
|
|
int p7_filebuffer_write(void *cookie, const unsigned char *data, size_t size);
|
|
# endif
|
|
|
|
/* Encoding/decoding functions */
|
|
p7ushort_t p7_encode(void *fnal, const void *raw, p7ushort_t size);
|
|
p7ushort_t p7_decode(void *fnal, const void *encoded, p7ushort_t size);
|
|
|
|
/* Checksum function */
|
|
unsigned int p7_checksum(unsigned char *packet, p7ushort_t size);
|
|
|
|
/* ASCII-hex utilities */
|
|
void p7_putascii(unsigned char *p, p7uint_t i, int n);
|
|
p7uint_t p7_getascii(const unsigned char *p, int n);
|
|
p7uint_t p7_getdec(p7uint_t h);
|
|
p7uint_t p7_gethex(p7uint_t d);
|
|
|
|
# include <libp7/internals/log.h>
|
|
#endif
|