231 lines
7.5 KiB
C
231 lines
7.5 KiB
C
/* ************************************************************************** */
|
|
/* _____ _ */
|
|
/* libp7/internals.h |_ _|__ _ _| |__ ___ _ _ */
|
|
/* | Project: libp7 | |/ _ \| | | | '_ \ / _ \ | | | */
|
|
/* | | (_) | |_| | | | | __/ |_| | */
|
|
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
|
/* Last updated: 2016/10/13 07:36:52 |___/ */
|
|
/* */
|
|
/* ************************************************************************** */
|
|
#ifndef LIBP7_INTERNALS_H
|
|
# define LIBP7_INTERNALS_H
|
|
# include <libp7.h>
|
|
# include <libp7/packetio.h>
|
|
# include <libp7/custom.h>
|
|
# include <libp7/internals/stdio_ext.h>
|
|
# include <libusb.h>
|
|
|
|
/* ************************************************************************** */
|
|
/* Macros and platform-specific functions */
|
|
/* ************************************************************************** */
|
|
/* MS-Windows <3 (srsly) */
|
|
# if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) \
|
|
&& !defined(__WINDOWS__)
|
|
# define __WINDOWS__
|
|
# endif
|
|
|
|
/* Macros */
|
|
# ifndef min
|
|
# define min(A, B) ((A) < (B) ? (A) : (B))
|
|
# endif
|
|
# ifndef max
|
|
# define max(A, B) ((A) > (B) ? (A) : (B))
|
|
# endif
|
|
|
|
/* Platform-specific functions */
|
|
# ifdef __WINDOWS__
|
|
# define bzero(B, LEN) ((void)memset((B), 0, (LEN)))
|
|
# 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)
|
|
|
|
/* ************************************************************************** */
|
|
/* 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(p7_commandcode_t code, const p7_env_t *env);
|
|
# define command_is_supported(N) p7_command_is_supported(N, handle->_env)
|
|
|
|
/* ************************************************************************** */
|
|
/* Handle-related */
|
|
/* ************************************************************************** */
|
|
/* P7 Stream */
|
|
# define libusb_bufsize 2048
|
|
# define p7_streamtype_libc 1
|
|
# define p7_streamtype_libusb 2
|
|
struct p7_stream_s {
|
|
int _type;
|
|
|
|
/* libc streams */
|
|
FILE *_rstream;
|
|
FILE *_wstream;
|
|
int _rstream_close;
|
|
|
|
/* libusb */
|
|
libusb_context *_libusb_context;
|
|
libusb_device_handle *_libusb_handle;
|
|
|
|
/* buffer */
|
|
unsigned char *_buffer;
|
|
size_t _buffer_size;
|
|
ssize_t _buffer_start, _buffer_end;
|
|
};
|
|
|
|
/* main structure */
|
|
struct p7_handle_s {
|
|
/* stream */
|
|
p7_stream_t *_stream;
|
|
p7_stream_t _stream_data;
|
|
|
|
/* current environment */
|
|
const p7_env_t *_env;
|
|
|
|
/* active status */
|
|
int _active;
|
|
/* shift status */
|
|
int _shifted;
|
|
/* last sent command */
|
|
p7ushort_t _last_sent_command;
|
|
/* response */
|
|
p7_packet_t *_response;
|
|
|
|
/* raw sending packet buffers */
|
|
unsigned char *_send_buffers[2];
|
|
size_t _send_buffers_size[2];
|
|
int _send_buffer_id;
|
|
/* raw reception packet buffer */
|
|
unsigned char *_recv_buffer;
|
|
/* pixels */
|
|
uint32_t **_pixels;
|
|
};
|
|
|
|
/* ************************************************************************** */
|
|
/* Packet I/O */
|
|
/* ************************************************************************** */
|
|
/* initialize */
|
|
int p7_usbinit(p7_handle_t **handle, int active, int check);
|
|
|
|
/* Utilities */
|
|
int p7_send_basic(p7_handle_t *handle,
|
|
p7_packettype_t type, p7ushort_t subtype, int resp);
|
|
int p7_send_ext(p7_handle_t *handle,
|
|
p7_packettype_t type, p7ushort_t subtype,
|
|
const void *data, p7ushort_t size, int resp);
|
|
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 filename is ok */
|
|
# define chk_filename(F) \
|
|
if (!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 handle is initialized */
|
|
# define chk_handle(H) \
|
|
if (!(H)) return (p7_error_uninitialized)
|
|
|
|
/* 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)
|
|
|
|
/* ************************************************************************** */
|
|
/* Utilities */
|
|
/* ************************************************************************** */
|
|
/* Main initialization function */
|
|
int _p7_init(p7_handle_t **h, int active, int check, p7_stream_t stream);
|
|
|
|
/* 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);
|
|
|
|
/* valid USB connexions */
|
|
int _p7_check_usb(unsigned int idVendor, unsigned int idProduct);
|
|
|
|
# include <libp7/internals/log.h>
|
|
#endif
|