linuxaldl/src/linuxaldl.h

218 lines
8.0 KiB
C

#ifndef LINUXALDL_INCLUDED
#define LINUXALDL_INCLUDED
/*(C) copyright 2008, Steven Snyder, All Rights Reserved
Steven T. Snyder, <stsnyder@ucla.edu> http://www.steventsnyder.com
LICENSING INFORMATION:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// debug mode
//#define _LINUXALDL_DEBUG
#define MAX_CONNECT_ATTEMPTS 3
// macros
#define _ALDL_MESSAGE_MODE8 aldl_settings.definition->mode8_request,aldl_settings.definition->mode8_request_length
#define _ALDL_MESSAGE_MODE9 aldl_settings.definition->mode9_request,aldl_settings.definition->mode9_request_length
#define __MAX_REQUEST_SIZE 16 /* maximum size (bytes) of a request message to send to the ECM */
enum ALDL_OP { ALDL_OP_SCALAR=0,
ALDL_OP_MAP,
ALDL_OP_BIT,
ALDL_OP_SEPERATOR,
};
// ============================================================================
// ALDL DEFINITION STRUCTS
// ============================================================================
// See linuxaldl_definitions.h for instructions on how to make a new definition
// byte_def_t struct
typedef struct _linuxaldl_byte_definition{
const char* label;
unsigned char byte_offset; /* Offset from the 1st byte of the data part of the mode1 message */
unsigned char bits; /* 8 or 16 are currently supported */
enum ALDL_OP operation;
float op_factor; // factor for the operation
float op_offset; // offset for the operation
const char* units; /* Text string */
const float *map;
unsigned char b_bit;
const char *b_set;
const char *b_unset;
} byte_def_t;
#define ALDL_DEF_SCALAR8(__label, __offset, __factor, __shift, __units ) \
{ .label = __label, \
.byte_offset = __offset, \
.operation = ALDL_OP_SCALAR, \
.bits = 8, \
.op_factor = __factor, \
.op_offset = __shift, \
.units = __units, \
}
#define ALDL_DEF_SCALAR16(__label, __offset, __factor, __shift, __units ) \
{ .label = __label, \
.byte_offset = __offset, \
.operation = ALDL_OP_SCALAR, \
.bits = 16, \
.op_factor = __factor, \
.op_offset = __shift, \
.units = __units, \
}
#define ALDL_DEF_MAP8(__label, __offset, __map, __units ) \
{ .label = __label, \
.byte_offset = __offset, \
.operation = ALDL_OP_MAP, \
.bits = 8, \
.map = __map, \
.units = __units, \
}
#define ALDL_DEF_BIT(__label, __offset, __bit, __set, __unset ) \
{ .label = __label, \
.byte_offset = __offset, \
.operation = ALDL_OP_BIT, \
.bits = 8, \
.b_bit = __bit, \
.b_set = __set, \
.b_unset = __unset, \
}
#define ALDL_DEF_SEPERATOR(__label) \
{ .label = __label, \
.operation = ALDL_OP_SEPERATOR, \
}
#define ALDL_DEF_END { .label = NULL }
typedef struct _linuxaldl_definition {
const char* mask;
const char* name;
char mode1_request[__MAX_REQUEST_SIZE]; // the mode 1 request message, including the checksum
unsigned int mode1_request_length; // the length of the mode 1 message including the checksum
unsigned int mode1_response_length; // the total length of the response from the ecm
unsigned int mode1_data_length; // the number of data bytes in the mode1 message response
unsigned int mode1_data_offset; // the byte offest from the start of the mode1 message response
// to the first byte of the data. e.g. if the data part of the
// message is the 4th byte onward, this should be 3. (1+3 = 4)
byte_def_t* mode1_def; // pointer to start of table of byte_def_t structs.
// the last element must be LINUXALDL_MODE1_END_DEF
char mode8_request[__MAX_REQUEST_SIZE]; // the mode 8 (silence) request message, incl checksum
unsigned int mode8_request_length; // the length of the mode 8 message incl checksum
char mode9_request[__MAX_REQUEST_SIZE]; // the mode 9 (un-silence) request message, incl checksum
unsigned int mode9_request_length; // the length of the mode 9 message including the checksum
unsigned int basic_baudrate; /* Fallback datarate */
unsigned int ideal_baudrate; /* Desired datarate -- 8192 or 160 */
} aldl_definition;
// looks up def_name in the aldl_definition_table until it finds the first
// definition in the table with the name def_name or the mask defmask
// if the definition is not in the table, returns NULL
aldl_definition* aldl_get_definition(const char* defname, const char *defmask);
typedef struct _linuxaldl_settings
{
/* Configuration fields */
const char* aldlportname; // path to aldl interface port
const char* logfilename; // filename for the log file
const char* aldldefname; // name for the ALDL definition to be used
unsigned int scan_interval; // msec between scan requests
unsigned int scan_timeout; // msec to timeout on scan request.
// note that read-sequence takes timeout in usec.
// usec = msec*1000
/* Data definitions */
aldl_definition** aldl_definition_table; // array of pointers to data definitions. (see linuxaldl_definitions.h)
/* Runtime stuff */
int customrate; // 1 if we are using accurate datarate.
int faldl; // aldl serial interface file descriptor
int flogfile; // file descriptor for log file
int scanning; // 1 when the timer has been set for making scans, otherwise 0.
aldl_definition* definition; // see linuxaldl_definitions.h
char* data_set_raw; // the current/most recent set of data from a mode1 message.
// this is allocated when a definition is selected
char** data_set_strings;// pointer to array of data set in string format.
// allocated when a definition is selected in the GUI
float* data_set_floats; // data set in float format
// allocated when a definition is selected in the GUI
} linuxaldl_settings;
// function prototypes
// =================================================
int verifyaldl();
// wake up / verify the ALDL interface
int aldl_scan_and_log(int fd);
// listens for aldl data and writes it to the file descriptor fd
// stops when terminate_scan = 1 in the global settings struct and
// returns number of bytes written to fd.
char get_checksum(char* buffer, unsigned int len);
// calculates the single-byte checksum, summing from the start of buffer
// through len bytes. the checksum is calculated by summing the bytes,
// dropping carried bits, then adding 1 and taking the two's complement
// (subtract from FF)
int send_aldl_message(char* msg_buf, unsigned int size);
// sends an artibtrary aldl message contained in the buffer msg_buf.
// the checksum must be set in the buffer by the caller.
// the following macros can be used as arguments:
// _ALDL_MESSAGE_MODE8
// _ALDL_MESSAGE_MODE9
// which use the mode 8 and mode 9 message definitions from the
// current aldl definition.
int get_mode1_message(char* inbuffer, unsigned int size);
// requests a mode1 message from the ECM using the currently loaded
// aldl definition.
// returns 0 if the message was received successfully, -1 no response
// or bad checksum.
int aldl_listen_raw(char* inbuffer, unsigned int len, int timeout);
// reads up to len bytes into inbuffer from the interface.
// listens for a maximum of timeout seconds.
// returns -1 on failure, 0 on timeout with no bytes received,
// and otherwise returns the number of bytes received
typedef enum _ALDL_UPDATE_FLAGS { ALDL_UPDATE_STRINGS=1, ALDL_UPDATE_FLOATS=2} ALDL_UPDATE_FLAGS_t;
void aldl_update_sets(int flags);
// updates data_set_floats and/or data_set_strings using the current data_set_raw bytes.
// if the flags argument is ALDL_UPDATE_STRINGS then both sets will be updated.
// if it is ALDL_UPDATE_FLOATS then only floats will be updated, and the data_set_strings
// array will not be modified in any way.
#endif