Changed the handle private structure, added legacy protocol drafts
This commit is contained in:
parent
ef5e9c9a8f
commit
37fa838e5c
|
@ -79,6 +79,7 @@ extern "C" {
|
|||
# define p7_error_fullmem 0x36
|
||||
# define p7_error_notfound 0x37
|
||||
# define p7_error_denied_overwrite 0x38
|
||||
# define p7_error_groupname 0x39
|
||||
|
||||
/* Error type -- for compatibility with old programs using enum */
|
||||
typedef int p7_error_t;
|
||||
|
|
|
@ -111,43 +111,41 @@ int p7_command_is_supported(unsigned int code, const p7_env_t *env);
|
|||
/* ************************************************************************** */
|
||||
/* Handle-related */
|
||||
/* ************************************************************************** */
|
||||
/* main structure */
|
||||
/* handle flags */
|
||||
# define p7_intflag_sendalt 0x0001 /* use alternative buffer (_buffers[1]) */
|
||||
# define p7_intflag_alloc 0x0002 /* was allocated */
|
||||
# define p7_intflag_serial 0x0004 /* is a serial connexion */
|
||||
# define p7_intflag_active 0x0008 /* active status */
|
||||
# define p7_intflag_shifted 0x0010 /* shift status */
|
||||
# define p7_intflag_terminated 0x0020 /* terminated */
|
||||
# define p7_intflag_term 0x0040 /* should terminate at exit */
|
||||
|
||||
/* handle structure */
|
||||
struct p7_handle_s {
|
||||
/* was allocated */
|
||||
int _wasalloc;
|
||||
/* flags - see above */
|
||||
unsigned int _flags;
|
||||
|
||||
/* stream */
|
||||
p7_stream_t *_stream;
|
||||
p7_stream_t _stream_data;
|
||||
|
||||
/* current server and environment */
|
||||
/* stream, environment, response, server information */
|
||||
const p7_env_t *_env; /* see `core/devices.c` */
|
||||
p7_stream_t _stream;
|
||||
p7_packet_t _response;
|
||||
p7_server_t _server;
|
||||
const p7_env_t *_env;
|
||||
|
||||
/* last sent command, response */
|
||||
p7ushort_t _last_sent_command;
|
||||
p7_packet_t _response_data;
|
||||
|
||||
/* MCS head */
|
||||
# ifndef P7_DISABLED_LIBG1M
|
||||
/* head of the current MCS file */
|
||||
g1m_mcshead_t mcshead;
|
||||
# endif
|
||||
|
||||
/* various flags */
|
||||
int _serial; /* is a serial connexion */
|
||||
int _active; /* active status */
|
||||
int _shifted; /* shift status */
|
||||
int _terminated; /* was terminated */
|
||||
int _term; /* should terminate at exit */
|
||||
|
||||
/* 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];
|
||||
unsigned char _recv_buffer[MAX_PACKET_SIZE];
|
||||
|
||||
/* name - a space/null, 8 characters max, then imposed null char. */
|
||||
char _name[10];
|
||||
|
@ -182,7 +180,7 @@ int p7_recv(p7_handle_t *handle, int checksum);
|
|||
int p7_send_err_resend(p7_handle_t *handle);
|
||||
|
||||
/* active response */
|
||||
# define response (*handle->_response)
|
||||
# define response (handle->_response)
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Macros */
|
||||
|
@ -190,15 +188,15 @@ int p7_send_err_resend(p7_handle_t *handle);
|
|||
/* check if handle is initialized */
|
||||
# define chk_handle(H) \
|
||||
if (!(H)) return (p7_error_uninitialized); \
|
||||
if ((H)->_terminated) return (p7_error_terminated);
|
||||
if ((H)->_flags & p7_intflag_terminated) return (p7_error_terminated);
|
||||
|
||||
/* check if active */
|
||||
# define chk_active(H) \
|
||||
if (!(H)->_active) return (p7_error_active)
|
||||
if (~(H)->_flags & p7_intflag_active) return (p7_error_active)
|
||||
|
||||
/* check if passive */
|
||||
# define chk_passive(H) \
|
||||
if ((H)->_active) return (p7_error_active)
|
||||
if ((H)->_flags & p7_intflag_active) return (p7_error_active)
|
||||
|
||||
/* check if filename is ok */
|
||||
# define chk_filename(F) \
|
||||
|
@ -212,6 +210,11 @@ int p7_send_err_resend(p7_handle_t *handle);
|
|||
# define chk_dirname(D) \
|
||||
if ((D) && !p7_validate_dirname(D)) return (p7_error_dirname)
|
||||
|
||||
/* check if mcs request head is ok */
|
||||
# define chk_head(H) \
|
||||
if (!(H)->name[0]) return (p7_error_filename); \
|
||||
if (!(H)->_group[0]) return (p7_error_groupname)
|
||||
|
||||
/* check if filestream is readable */
|
||||
# define chk_isread(F) \
|
||||
if (!(F) || !__freadable(F)) return (p7_error_noread)
|
||||
|
|
|
@ -43,7 +43,7 @@ const size_t p7_handle_size = sizeof(p7_handle_t);
|
|||
|
||||
const p7_packet_t *p7_get_response(p7_handle_t *handle)
|
||||
{
|
||||
return (handle->_response);
|
||||
return (&handle->_response);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,7 +58,7 @@ const p7_packet_t *p7_get_response(p7_handle_t *handle)
|
|||
|
||||
const p7_stream_t *p7_get_stream(p7_handle_t *handle)
|
||||
{
|
||||
return (handle->_stream);
|
||||
return (&handle->_stream);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -154,15 +154,17 @@ int p7_sinit(p7_handle_t **h, unsigned int flags,
|
|||
|
||||
/* initialize handle */
|
||||
p7_handle_t *handle = *h;
|
||||
memset(handle, 0, sizeof(p7_handle_t));
|
||||
handle->_wasalloc = alloc;
|
||||
handle->_stream_data = dstream;
|
||||
handle->_stream = &handle->_stream_data;
|
||||
handle->_response = &handle->_response_data;
|
||||
memset(handle, 0, sizeof(p7_handle_t)); /* important! */
|
||||
handle->_stream = dstream;
|
||||
|
||||
/* initialize flags */
|
||||
handle->_flags = 0;
|
||||
if (alloc) handle->_flags |= p7_intflag_alloc;
|
||||
if (flags & P7_ACTIVE) handle->_flags |= p7_intflag_active;
|
||||
if (flags & P7_TERM) handle->_flags |= p7_intflag_term;
|
||||
|
||||
/* prepare the name */
|
||||
if (!name) handle->_name[0] = 0;
|
||||
else {
|
||||
if (name) {
|
||||
handle->_name[0] = ' ';
|
||||
strncpy(&handle->_name[1], name, 8);
|
||||
handle->_name[9] = 0;
|
||||
|
@ -170,25 +172,12 @@ int p7_sinit(p7_handle_t **h, unsigned int flags,
|
|||
log_info("handle prepared, masta!");
|
||||
|
||||
/* set communication thingies */
|
||||
handle->_serial = 0;
|
||||
log_info("initializing stream settings");
|
||||
p7_setcomm(handle->_stream, P7_B9600, P7_PARITY_NONE, P7_TWOSTOPBITS);
|
||||
|
||||
/* starting as active */
|
||||
handle->_active = flags & P7_ACTIVE;
|
||||
handle->_terminated = 0;
|
||||
handle->_term = flags & P7_TERM;
|
||||
/* initialize environment */
|
||||
handle->_env = NULL;
|
||||
/* initialize stupid things */
|
||||
handle->_shifted = 0;
|
||||
handle->_send_buffers_size[0] = 0;
|
||||
handle->_send_buffers_size[1] = 0;
|
||||
handle->_send_buffer_id = 0;
|
||||
p7_setcomm(&handle->_stream, P7_B9600, P7_PARITY_NONE, P7_TWOSTOPBITS);
|
||||
|
||||
/* if active, start */
|
||||
if (handle->_active && (err = start(handle, flags & P7_CHECK))) {
|
||||
handle->_term = P7_TERM;
|
||||
if ((handle->_flags & p7_intflag_active)
|
||||
&& (err = start(handle, flags & P7_CHECK))) {
|
||||
p7_exit(*h); *h = NULL;
|
||||
return (err);
|
||||
}
|
||||
|
@ -215,18 +204,21 @@ void p7_exit(p7_handle_t *handle)
|
|||
log_info("and handle is still there, so let's go!");
|
||||
|
||||
/* terminate communication */
|
||||
if (handle->_active && !handle->_terminated && handle->_term) {
|
||||
if (handle->_flags & p7_intflag_active
|
||||
&& ~handle->_flags & p7_intflag_terminated
|
||||
&& handle->_flags & p7_intflag_term) {
|
||||
log_info("we were active, send sending terminate packet");
|
||||
if (p7_send_term(handle)) {
|
||||
log_warn("couldn't send terminate packet, already disconnected?");
|
||||
/* don't bother */
|
||||
}
|
||||
/* don't bother checking ack */
|
||||
}
|
||||
|
||||
/* close stream */
|
||||
(*handle->_stream->close)(handle->_stream->cookie);
|
||||
(*handle->_stream.close)(handle->_stream.cookie);
|
||||
|
||||
/* free handle */
|
||||
log_info("freeing the handle!");
|
||||
if (handle->_wasalloc) free(handle);
|
||||
if (handle->_flags & p7_intflag_alloc) free(handle);
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ int p7_cominit(p7_handle_t **handle, unsigned int flags, const char *path)
|
|||
# endif
|
||||
|
||||
/* check error */
|
||||
if (!err) (*handle)->_serial = 1;
|
||||
if (!err) (*handle)->_flags |= p7_intflag_serial;
|
||||
if (err != p7_error_nocalc)
|
||||
return (err);
|
||||
|
||||
|
|
|
@ -81,6 +81,8 @@ const char *p7_error_strings[] = {
|
|||
"file not found",
|
||||
[p7_error_denied_overwrite] =
|
||||
"we denied overwrite",
|
||||
[p7_error_groupname] =
|
||||
"the group name was missing or invalid",
|
||||
|
||||
/* others */
|
||||
[p7_error_unsupported] =
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/* *****************************************************************************
|
||||
* legacy/init.c -- initialize the legacy communication.
|
||||
* 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/>.
|
||||
* ************************************************************************** */
|
||||
#include <libp7/internals.h>
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Initialization */
|
||||
/* ************************************************************************** */
|
||||
/**
|
||||
* start:
|
||||
* Start the communication.
|
||||
*
|
||||
* @arg handle the handle.
|
||||
* @return the error, if any.
|
||||
*/
|
||||
|
||||
static int start(p7_handle_t *handle)
|
||||
{
|
||||
/* receive the attention request */
|
||||
unsigned char byte;
|
||||
p7_read(handle->stream, &byte, 1, 0);
|
||||
if (byte != 0x15) return (p7_error_unknown);
|
||||
|
||||
/* send the device present */
|
||||
byte = 0x13;
|
||||
p7_write(handle->stream, &byte, 1);
|
||||
|
||||
/* receive first packet */
|
||||
p7_legacy_recv(&packet);
|
||||
}
|
|
@ -0,0 +1,218 @@
|
|||
/* *****************************************************************************
|
||||
* legacy/recv.c -- receive a legacy packet.
|
||||
* 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/>.
|
||||
* ************************************************************************** */
|
||||
#include <libp7/internals.h>
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Raw packet structure */
|
||||
/* ************************************************************************** */
|
||||
/* Complete structure */ */
|
||||
struct raw_packet {
|
||||
uint8_t type[4];
|
||||
|
||||
uint8_t subtype[2];
|
||||
uint8_t _zero2;
|
||||
|
||||
uint8_t in_use; /* 0 or 1 */
|
||||
uint8_t _zero3;
|
||||
|
||||
uint8_t in_use2; /* duplicate of `in_use` */
|
||||
uint8_t varname; /* variable name: 0x41 t 0x5A, 0xCD for r, 0xCE for è */
|
||||
|
||||
uint8_t _spacing[7];
|
||||
|
||||
uint8_t variable[8]; /* "Variable", ASCII-encoded */
|
||||
uint8_t complex; /* 'C' if complex, 'R' if real */
|
||||
|
||||
uint8_t unknown; /* 0x0A */
|
||||
|
||||
uint8_t _spacing2[20];
|
||||
|
||||
uint8_t checksum; /* ~sum(all bytes not including start and checksum) + 1 */
|
||||
};
|
||||
|
||||
/* Types */
|
||||
static packet_type_t types[] = {
|
||||
{"REQ", request},
|
||||
{"VAL", value_description},
|
||||
};
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Packet completing utilities */
|
||||
/* ************************************************************************** */
|
||||
/**
|
||||
* complete_packet:
|
||||
* Complete the packet with N bytes.
|
||||
*
|
||||
* Uses stream buffering to achieve this.
|
||||
*
|
||||
* @arg handle the libp7 handle.
|
||||
* @arg buf the buffer.
|
||||
* @arg recv pointer to currently received bytes.
|
||||
* @arg with complete with this number of byte.
|
||||
* @return the error (0 if ok)
|
||||
*/
|
||||
|
||||
static int complete_packet(p7_handle_t *handle,
|
||||
unsigned char *buf, size_t *recv, size_t with)
|
||||
{
|
||||
int err = p7_read(handle->_stream, &buf[*recv], with, ACTIVE_TIMEOUT);
|
||||
*recv += with;
|
||||
return (err);
|
||||
}
|
||||
|
||||
#define buffer handle->_recv_buffer
|
||||
#define COMPLETE_PACKET(N) { \
|
||||
int COMP_PACKET_err; \
|
||||
if ((COMP_PACKET_err = complete_packet(handle, \
|
||||
buffer, &received, (N)))) \
|
||||
return (COMP_PACKET_err); \
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Receive the packet */
|
||||
/* ************************************************************************** */
|
||||
/**
|
||||
* p7_legacy_recv:
|
||||
* Receive a [legacy] packet.
|
||||
*
|
||||
* This is the main receiving function. It receives, parses, and returns
|
||||
* if everything has been successfully done or not.
|
||||
* It reads progressively all of the packet.
|
||||
*
|
||||
* The checksum holds in one byte instead of two (Protocol 7).
|
||||
* Because I don't want to make an other `p7_checksum` function,
|
||||
* `p7_checksum(buffer, received + 1)` is a hack.
|
||||
*
|
||||
* Sources for these functions are Cafix and some reverse engineering
|
||||
* report from Erik Grindheim (CASIO CFX-9950G communications protocol).
|
||||
*
|
||||
* @arg handle the libp7 handle
|
||||
* @return the error (0 if ok)
|
||||
*/
|
||||
|
||||
static int p7_legacy_recv(p7_handle_t *handle)
|
||||
{
|
||||
/* prepare reception */
|
||||
size_t received = 0;
|
||||
|
||||
/* log packet */
|
||||
log_info("receiving packet...");
|
||||
|
||||
/* get the first character */
|
||||
COMPLETE_PACKET(1)
|
||||
if (buffer[0] != ':') switch (buffer[0]) {
|
||||
/* initial packets */
|
||||
case 0x15: /* is interactive initial packet */
|
||||
case 0x16: resp.type = p7_pt_ini; return (0);
|
||||
|
||||
/* initial packet response */
|
||||
case 0x13: resp.type = p7_pt_ini_resp; return (0);
|
||||
|
||||
/* ack */
|
||||
case 0x06: resp.type = p7_pt_ack; return (0);
|
||||
|
||||
/* unknown data type */
|
||||
case 0x00: case 0x24: return (0);
|
||||
|
||||
/* checksum error */
|
||||
case 0x2B: return (0);
|
||||
|
||||
/* abort XXX */
|
||||
case 0x15: return (0);
|
||||
|
||||
/* we don't know this */
|
||||
default: return (p7_error_unknown);
|
||||
}
|
||||
|
||||
/* read the type */
|
||||
COMPLETE_PACKET(4)
|
||||
|
||||
/* check if value packet */
|
||||
if (!memcmp(&buffer[1], "\x00\x01\x00\x01", 4)) {
|
||||
/* get the packet */
|
||||
size_t packet_size = 16 - 10;
|
||||
if (handle->_expecting_complex)
|
||||
packet_size += 10;
|
||||
COMPLETE_PACKET(packet_size)
|
||||
|
||||
/* check the sum */
|
||||
if (checksum != p7_checksum(buffer, received + 1))
|
||||
return (p7_error_checksum);
|
||||
|
||||
/* read the value */
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* check legacy screendump packet */
|
||||
if (buffer[3] == '@') {
|
||||
COMPLETE_PACKET(35)
|
||||
if (buffer[50] != p7_checksum(&buffer[1], 48))
|
||||
return (p7_error_checksum);
|
||||
|
||||
/* TODO */
|
||||
|
||||
/* yay! */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* check legacy packet */
|
||||
if (buffer[4] == 0) {
|
||||
COMPLETE_PACKET(45)
|
||||
if (buffer[50] != p7_checksum(&buffer[1], 48))
|
||||
return (p7_error_checksum);
|
||||
|
||||
/* check the type */
|
||||
const char *type = &buffer[1];
|
||||
int datatype = get_data_type(&buffer[5]);
|
||||
if (!memcmp(type, "REQ", 3)) {
|
||||
/* request */
|
||||
} else if (!memcmp(type, "VAL", 3)) {
|
||||
/* variable */
|
||||
} else if (!memcmp(type, "MEM", 3)) {
|
||||
/* backup */
|
||||
} else if (!memcmp(type, "FNC", 3)) {
|
||||
/* function */
|
||||
} else if (!memcmp(type, "IMG", 3)) {
|
||||
/* picture */
|
||||
} else if (!memcmp(type, "TXT", 3)) {
|
||||
/* program */
|
||||
} else if (!memcmp(type, "REQ", 3)) {
|
||||
/* request? */
|
||||
} else if (!memcmp(type, "END", 3)) {
|
||||
/* end */
|
||||
} else if (type[0] == 'P' && isdigit(type[1]) && type[2] == 0) {
|
||||
/* program in P0, P1, ... */
|
||||
} else {
|
||||
/* unknown */
|
||||
}
|
||||
|
||||
/* yay! */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* special packet? see cafix */
|
||||
COMPLETE_PACKET(5)
|
||||
if (!memcmp(&buffer[1], "BUTYPEA02", 9)) {
|
||||
/* backup from CFX-9800G? */
|
||||
COMPLETE_PACKET(30)
|
||||
}
|
||||
|
||||
/* unknown packet! */
|
||||
return (p7_error_unknown);
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/* *****************************************************************************
|
||||
* legacy/special.c -- send special legacy packets.
|
||||
* 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/>.
|
||||
* ************************************************************************** */
|
||||
#include <libp7/internals.h>
|
||||
|
||||
/**
|
||||
* p7_legacy_send_ack:
|
||||
* Send a legacy ack.
|
||||
*
|
||||
* @arg handle the handle.
|
||||
* @return the error (if one).
|
||||
*/
|
||||
|
||||
int p7_legacy_send_ack(p7_handle_t *handle)
|
||||
{
|
||||
char byte = 0x06;
|
||||
int err = p7_write(handle->stream, &byte, 1, 0);
|
||||
return (err ? err : p7_recv(handle->stream));
|
||||
}
|
||||
|
||||
/**
|
||||
* p7_legacy_send_end:
|
||||
* Send the end packet.
|
||||
*
|
||||
* @arg
|
||||
*/
|
|
@ -25,23 +25,24 @@
|
|||
*
|
||||
* @arg handle the libp7 handle.
|
||||
* @arg file the file handle to create.
|
||||
* @arg head the head to get the file with.
|
||||
* @arg reqhead the request head.
|
||||
* @arg disp the progression display callback.
|
||||
* @return the libp7 error (0 if ok)
|
||||
*/
|
||||
|
||||
int p7_mcs_request(p7_handle_t *handle, g1m_mcsfile_t **file,
|
||||
const g1m_mcshead_t *head, p7_disp_t disp)
|
||||
const g1m_mcshead_t *reqhead, p7_disp_t disp)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* make checks */
|
||||
chk_handle(handle);
|
||||
chk_active(handle);
|
||||
chk_head(reqhead);
|
||||
|
||||
/* send command */
|
||||
log_info("sending file transfer request");
|
||||
if ((err = p7_send_cmdmcs_reqfile(handle, head))) {
|
||||
if ((err = p7_send_cmdmcs_reqfile(handle, reqhead))) {
|
||||
log_fatal("couldn't send file transfer request/didn't receive answer");
|
||||
return (err);
|
||||
} if (response.type == p7_pt_error
|
||||
|
@ -63,10 +64,16 @@ int p7_mcs_request(p7_handle_t *handle, g1m_mcsfile_t **file,
|
|||
return (p7_error_unknown);
|
||||
}
|
||||
|
||||
/* save the head */
|
||||
g1m_mcshead_t head;
|
||||
g1m_decode_mcsfile_head(&head, response.mcstype,
|
||||
(unsigned char*)response.args[2], (unsigned char*)response.args[0],
|
||||
(unsigned char*)response.args[1], response.filesize);
|
||||
|
||||
/* get data */
|
||||
unsigned char *tmp = malloc(response.filesize);
|
||||
unsigned char *tmp = malloc(head.size);
|
||||
if (!tmp) return (p7_error_alloc);
|
||||
if ((err = p7_get_data(handle, tmp, response.filesize, 0, disp)))
|
||||
if ((err = p7_get_data(handle, tmp, head.size, 0, disp)))
|
||||
goto fail;
|
||||
|
||||
/* check if last answer was roleswap */
|
||||
|
@ -76,7 +83,7 @@ int p7_mcs_request(p7_handle_t *handle, g1m_mcsfile_t **file,
|
|||
}
|
||||
|
||||
/* decode */
|
||||
if (g1m_decode_mcsfile_data(file, head, tmp, response.filesize)) {
|
||||
if (g1m_decode_mcsfile_data(file, &head, tmp, head.size)) {
|
||||
err = p7_error_unknown;
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ int p7_setlink(p7_handle_t *handle, int baudrate, int parity, int stopbits)
|
|||
}
|
||||
|
||||
/* set communication properties */
|
||||
p7_setcomm(handle->_stream, baudrate, parity, stopbits);
|
||||
p7_setcomm(&handle->_stream, baudrate, parity, stopbits);
|
||||
|
||||
end:
|
||||
/* wait for the calculator to set its serial interface, and we're done */
|
||||
|
|
|
@ -217,7 +217,7 @@ static inline void cpy_string(char *dest, const char *src, size_t n)
|
|||
int p7_decode_ack(p7_handle_t *handle,
|
||||
const unsigned char *data, size_t data_size)
|
||||
{
|
||||
p7_packet_t *packet = handle->_response;
|
||||
p7_packet_t *packet = &handle->_response;
|
||||
/* check the data size */
|
||||
if (data_size != sizeof(packetdata_ackext_t)) return (1);
|
||||
|
||||
|
|
|
@ -140,7 +140,7 @@ int p7_send_cmdsys_setlink(p7_handle_t *handle,
|
|||
int baudrate, int parity, int stopbits)
|
||||
{
|
||||
/* check if is a serial connexion */
|
||||
if (!handle->_serial) return (p7_error_unsupported);
|
||||
if (~handle->_flags & p7_intflag_serial) return (p7_error_unsupported);
|
||||
|
||||
/* make arguments */
|
||||
char sbaud[10], sparity[10], sstopbits[2];
|
||||
|
@ -216,7 +216,7 @@ int p7_send_cmdosu_upandrun(p7_handle_t *handle,
|
|||
int p7_decode_command(p7_handle_t *handle,
|
||||
const unsigned char *raw, size_t raw_size)
|
||||
{
|
||||
p7_packet_t *packet = handle->_response;
|
||||
p7_packet_t *packet = &handle->_response;
|
||||
/* check up_and_run command */
|
||||
if (packet->code == 0x56) {
|
||||
if (raw_size != 12) return (1);
|
||||
|
|
|
@ -105,7 +105,7 @@ static int unshift(p7_handle_t *handle)
|
|||
int err;
|
||||
if ((err = p7_recv(handle, 1)))
|
||||
return (err);
|
||||
handle->_shifted = 0;
|
||||
handle->_flags &= ~p7_intflag_shifted;
|
||||
|
||||
/* then return */
|
||||
return (0);
|
||||
|
@ -259,7 +259,7 @@ int p7_get_buffer(p7_handle_t *handle, const p7_buffer_t *buffer, p7uint_t size,
|
|||
if (disp) (*disp)(response.id, response.total);
|
||||
|
||||
/* check overflow */
|
||||
if (response.data_size > size) {
|
||||
if ((size_t)response.data_size > size) {
|
||||
log_fatal("%" PRIuP7SHORT " bytes received... "
|
||||
"that's more than the %" PRIuSIZE " expected. "
|
||||
"Taking the first bytes.",
|
||||
|
@ -410,7 +410,7 @@ int p7_get_data(p7_handle_t *handle, void *vbuf, p7uint_t size,
|
|||
if (disp) (*disp)(response.id, response.total);
|
||||
|
||||
/* check overflow */
|
||||
if (response.data_size >= size) {
|
||||
if (response.data_size > size) {
|
||||
log_fatal("%" PRIuP7SHORT " bytes received... "
|
||||
"that's more than the %" PRIuSIZE " expected. "
|
||||
"Taking the first bytes.",
|
||||
|
@ -461,7 +461,7 @@ typedef struct {
|
|||
int p7_decode_data(p7_handle_t *handle,
|
||||
const void *raw, p7ushort_t raw_size)
|
||||
{
|
||||
p7_packet_t *packet = handle->_response;
|
||||
p7_packet_t *packet = &handle->_response;
|
||||
const packetdata_data_t *d = raw;
|
||||
|
||||
/* total number */
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
static int complete_packet(p7_handle_t *handle,
|
||||
unsigned char *buf, size_t *recv, size_t with)
|
||||
{
|
||||
int err = p7_read(handle->_stream, &buf[*recv], with, ACTIVE_TIMEOUT);
|
||||
int err = p7_read(&handle->_stream, &buf[*recv], with, ACTIVE_TIMEOUT);
|
||||
*recv += with;
|
||||
return (err);
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ static int p7_recv_main(p7_handle_t *handle)
|
|||
case p7_pt_roleswp:
|
||||
log_info("packet was interpreted as a roleswap one");
|
||||
log_info("becoming active again");
|
||||
handle->_active = 1;
|
||||
handle->_flags |= p7_intflag_active;
|
||||
break;
|
||||
|
||||
/* - for check - */
|
||||
|
@ -189,7 +189,7 @@ static int p7_recv_main(p7_handle_t *handle)
|
|||
&& p7_decode_ack(handle, &buffer[8], data_size))
|
||||
return (p7_error_checksum);
|
||||
if (subtype == 0x03)
|
||||
handle->_terminated = 1;
|
||||
handle->_flags |= p7_intflag_terminated;
|
||||
break;
|
||||
|
||||
/* - for error - */
|
||||
|
@ -199,7 +199,7 @@ static int p7_recv_main(p7_handle_t *handle)
|
|||
p7_geterrstring(subtype), subtype);
|
||||
response.code = subtype;
|
||||
if (subtype == p7_err_fullmem)
|
||||
handle->_terminated = 1;
|
||||
handle->_flags |= p7_intflag_terminated;
|
||||
break;
|
||||
|
||||
/* - for termination - */
|
||||
|
@ -274,7 +274,7 @@ int p7_recv(p7_handle_t *handle, int checksum)
|
|||
/* if we receive an invalid checksum while we are in packet
|
||||
* shifting mode, or if we received an error when we sent a
|
||||
* resend error, cut connexion... we can't do anything. */
|
||||
if (handle->_shifted || wasresend)
|
||||
if ((handle->_flags & p7_intflag_shifted) || wasresend)
|
||||
return (p7_error_irrecoverable);
|
||||
|
||||
/* otherwise, send resend error */
|
||||
|
|
|
@ -21,9 +21,13 @@
|
|||
#include <libp7/internals.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#define buffer handle->_send_buffers[handle->_send_buffer_id]
|
||||
#define buffer_size handle->_send_buffers_size[handle->_send_buffer_id]
|
||||
#define switch_buffer() handle->_send_buffer_id = !handle->_send_buffer_id
|
||||
#define buffer \
|
||||
handle->_send_buffers[handle->_flags & p7_intflag_sendalt]
|
||||
#define buffer_size \
|
||||
handle->_send_buffers_size[handle->_flags & p7_intflag_sendalt]
|
||||
#define switch_buffer() \
|
||||
handle->_flags = (handle->_flags & ~p7_intflag_shifted) | \
|
||||
(~handle->_flags & p7_intflag_shifted)
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Main functions */
|
||||
|
@ -48,8 +52,9 @@ static int p7_send_buf(p7_handle_t *handle,
|
|||
/* check if user wants to shift
|
||||
* with hack: if `buf` is non-NULL, we simply want to send custom packet */
|
||||
if (!buf && !resp) {
|
||||
if (handle->_shifted) return (p7_error_doubleshift);
|
||||
else handle->_shifted = 1;
|
||||
if (handle->_flags & p7_intflag_shifted)
|
||||
return (p7_error_doubleshift);
|
||||
else handle->_flags |= p7_intflag_shifted;
|
||||
}
|
||||
|
||||
/* get buffer */
|
||||
|
@ -63,13 +68,13 @@ static int p7_send_buf(p7_handle_t *handle,
|
|||
do {
|
||||
/* log resend request */
|
||||
if (wasresend) {
|
||||
if (handle->_shifted) switch_buffer();
|
||||
if (handle->_flags & p7_intflag_shifted) switch_buffer();
|
||||
buf = buffer; bufsize = buffer_size;
|
||||
log_warn("resend request was received, resend it goes");
|
||||
}
|
||||
|
||||
/* send prepared packet */
|
||||
int err = p7_write(handle->_stream, buf, bufsize);
|
||||
int err = p7_write(&handle->_stream, buf, bufsize);
|
||||
if (err) return (err);
|
||||
|
||||
/* set wasreset for logging */
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
int p7_send_roleswp(p7_handle_t *handle)
|
||||
{
|
||||
/* as we can only send this when we're active, put role to passive */
|
||||
handle->_active = 0;
|
||||
handle->_flags &= ~p7_intflag_active;
|
||||
/* send packet */
|
||||
return (p7_send_basic(handle, p7_pt_roleswp, 0, 1));
|
||||
}
|
||||
|
|
Reference in New Issue