|
|
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
arap.c
Abstract:
Header file for all the v42bis stuff useed by ARAP (adapted from fcr's code)
Author:
Shirish Koti
Revision History: 15 Nov 1996 Initial Version
--*/
// v42bis stuff begin
// #define PRIVATE static
// v42bis stuff end
/* negotiated parameters in XID */ #define PARM_GROUP_ID 0xf0 /* ISB 8885, Addendum 3 */
#define PARM_PARM_ID_V42 0x00
#define PARM_PARM_ID_P0 0x01
#define PARM_PARM_ID_P1 0x02
#define PARM_PARM_ID_P2 0x03
/* control code words (compression mode) */ #define CCW_ETM 0x00 /* enter transparent mode */
#define CCW_FLUSH 0x01 /* flush data */
#define CCW_STEPUP 0x02 /* stepup code word size */
/* command code words (transparent mode) */ #define CCW_ECM 0x00 /* enter compression mode */
#define CCW_EID 0x01 /* escape character in data */
#define CCW_RESET 0x02 /* force reinitialization */
/* escape char cycling */ #define ESCAPE_CYCLE 51
/*
* v.42bis dictionary node */ typedef struct { UCHAR byte; /* character */ USHORT parent; /* ptr to parent node */ USHORT node; /* chain of nodes w/same parent */ USHORT leaf; /* chain of leafs w/same parent */ } node_t;
/*
* v.42bis state block */ typedef struct { /* connection */ void *connection;
/* values from spec */ SHORT n1; /* maximum codeword size (bits) */ SHORT n2; /* total number of codewords */ #define N3 8 /* character size (bits) */
#define N4 256 /* characters in alphabet (2^n3) */
#define N5 (N4+N6) /* index # of 1st entry to store a string */
#define N6 3 /* # of control words */
UCHAR n7; /* maximum string length */
/* dictionary */ #define CODES 2048 /* max # of codewords */
#define LOG2_CODES 11 /* log2(CODES) (max # of codeword bits) */
node_t dictionary[CODES]; #define DICT(i) (&state->dictionary[i])
#define CODE(n) ((n) - state->dictionary)
USHORT c1; /* next dictionary entry */ UCHAR c2; /* current codeword size */ USHORT c3; /* threshhold for codeword size change */
UCHAR string_size; /* # bytes in string so far */ USHORT last_match; /* index of last match of "string" */ USHORT last_new; /* index of last new node */ USHORT last_decode; UCHAR last_decode_size;
UCHAR escape; /* escape character */ BOOLEAN transparent; /* are we in transparent mode? */ BOOLEAN decode_only; /* are we decode side ? */
#if DEBUG
UCHAR dump_indent; /* indentation dumping dict. tree */ BOOLEAN debug_encode_bytes; BOOLEAN debug_encode; BOOLEAN debug_decode_bytes; BOOLEAN debug_decode; BOOLEAN debug_flow; #endif
UCHAR word_size; /* local # bits to decode into */ BOOLEAN exception_next; /* do exception processing; next ch */ BOOLEAN escaped; /* have we just gotten an escape? */ BOOLEAN just_flushed; /* did we just flush? */ BOOLEAN dict_full; /* is dictionary full? */
/* decode bytes->codeword state */ DWORD bits_waiting; /* decode holder */ UCHAR bits_remaining; /* # bits waiting in holder now */
UCHAR *input_ptr; USHORT input_size;
/* encode codeword->bytes state */ DWORD bits_acc; /* encode accumulator */ UCHAR bits_used; /* # bits packed in acc now */
UCHAR *output_buffer; /* ptr to work buffer */ UCHAR *output_ptr; /* current ptr into buffer */ USHORT output_size; /* current work size */ USHORT output_max; /* size of work buffer */
/* i/o */ void *push_context; //void (*push_func)(void *a, u_char *b, int c, int d);
void (*push_func)();
/* statistics for compressibility */ DWORD bytes_in; /* total bytes input to compress */ DWORD bytes_out; /* total bytes output from compress */ long bits_out_other_mode; /* output if we were in other mode */ long bits_out_this_mode; /* since last transition */ USHORT bytes_since_last_check; /* since last compression test */
UCHAR *OverFlowBuf; UCHAR OverFlowBytes; #define bits_out_if_compressed bits_out_other_mode
#define bits_out_while_compressed bits_out_this_mode
#define bits_out_if_transparent bits_out_other_mode
#define bits_out_while_transparent bits_out_this_mode
} v42bis_t;
/*
define hysteresis for compressed/transparent mode switch
WINDOW_FULL defines how many bits we look at WINDOW_MIN_BITS is the min bits of difference required for a change */ #define WINDOW_FULL(n) (n & 0xfffffc00) /* 1024 bits */
#define WINDOW_MIN_BITS 16*N3 /* 128 bits */
#define WINDOW_CHECK_BYTES 32 /* check every 32 */
#ifdef DEBUG
# define V_FLOW(s) if (state->debug_flow) logf s;
# define EN_DEBUG(s) \
if (state->debug_encode) { \ logf_prefix(state->decode_only ? "decode: " : "encode: "); \ logf s; }
//# define EN_S_DEBUG(s) \ // if (state->debug_encode > 1) { \ // logf_prefix(state->decode_only ? "decode: " : "encode: "); \ // logf s; }
# define EN_S_DEBUG(s) \
if (state->debug_encode > 1) { \ DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,s); # define EN_DEBUG_ON (state->debug_encode)
# define DE_DEBUG(s) \
if (state->debug_decode) { logf_prefix("decode: "); logf s; } # define DE_DEBUG_ON (state->debug_decode)
# define E_DEBUG(s) if (state->debug_encode_bytes) logf s;
# define D_DEBUG(s) if (state->debug_decode_bytes) logf s;
#else
# define V_FLOW(s) /* #s */
# define EN_DEBUG(s) /* #s */
# define DE_DEBUG(s) /* #s */
# define E_DEBUG(s) /* #s */
# define D_DEBUG(s) /* #s */
# define EN_S_DEBUG(s)
# define EN_DEBUG_ON FALSE
# define DE_DEBUG_ON FALSE
#endif
/*
* v42bis connection type */ typedef struct { /* negotiated options */ UCHAR neg_p0; /* negotiated value of p0 */ USHORT neg_p1; /* negotiated value of p1 */ UCHAR neg_p2; /* negotiated value of p2 */
UCHAR default_p0; /* default value of p0 */ USHORT default_p1; /* default value of p1 */ #define MIN_P1 512
#define DEF_P1 2048
USHORT default_p2; /* default value of p2 */ #define MIN_P2 6
/*#define DEF_P2 8 */ #define DEF_P2 250
#define MAX_P2 250
BOOLEAN compress_init_resp; /* comp. in initiator->responder dir */ BOOLEAN compress_resp_init; /* comp. in responder->initiator dir */ BOOLEAN got_p0; /* got negitated XID options */ BOOLEAN got_p1; BOOLEAN got_p2; BOOLEAN got_unknown_p; /* got unknown option */
v42bis_t encode; /* encode state */ v42bis_t decode; /* decode state */ } v42bis_connection_t;
/* turn a "state" into a connection */ #define CONN(s) ((v42bis_connection_t *)(s)->connection)
#define PUT(ch) \
{ \ if (state->output_size < state->output_max) \ { \ *state->output_ptr++ = (ch); \ state->output_size++; \ } \ else \ { \ /* put this byte in the overflow buffer: we'll recover later */ \ if (state == &((v42bis_connection_t *)state->connection)->decode) \ { \ *(state->OverFlowBuf + state->OverFlowBytes) = (ch); \ state->OverFlowBytes++; \ \ ASSERT(state->OverFlowBytes <= MAX_P2); \ } \ \ /* we don't have overflow buffer for encode side!! */ \ else \ { \ DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR, \ ("Arap v42bis: buf overflow on encode!! (%ld)\n", \ state->output_size)); \ \ ASSERT(0); \ } \ } \ }
/* local routines */ int decode_xid_params (v42bis_t *state, PUCHAR params, int len); DWORD v42bis_encode_codeword (v42bis_t *state, USHORT value); DWORD v42bis_c_error (v42bis_t *state, char *msg); DWORD v42bis_transition_to_compressed (v42bis_t *state); DWORD v42bis_transition_to_transparent (v42bis_t *state); DWORD v42bis_disconnect(v42bis_t *state, char *reason_string); DWORD v42bis_init_dictionary(v42bis_t *state); DWORD exit_handler( void ); DWORD v42bis_init(v42bis_t *state); USHORT v42bis_decode_codeword(v42bis_t *state, UCHAR value); USHORT v42bis_decode_codeword_flush(v42bis_t *state); DWORD v42bis_encode_codeword_flush(v42bis_t *state); DWORD v42bis_encode_codeword_flush(v42bis_t *state); DWORD v42bis_encode_value(v42bis_t *state, USHORT value); DWORD v42bis_apply_compression_test(v42bis_t *state); DWORD v42bis_encode_buffer(v42bis_t *state, PUCHAR string, int insize); DWORD v42bis_encode_flush(v42bis_t *state); DWORD v42bis_signal_reset(v42bis_t *state); DWORD v42bis_decode_match(v42bis_t *state, USHORT codeword, int *psize, UCHAR *pRetChar); DWORD v42bis_decode_buffer(v42bis_t *state, PUCHAR data, int *pDataSize); DWORD v42bis_decode_flush(v42bis_t *state); DWORD v42bis_init_buffer(v42bis_t *state, PUCHAR buf, int size); DWORD v42bis_connection_init(v42bis_connection_t *conn); DWORD v42bis_connection_init_buffers(v42bis_connection_t *conn, PUCHAR e_buf, int e_size, PUCHAR d_buf, int d_size); DWORD v42bis_connection_init_push(v42bis_connection_t *conn, void *context, void (*e_push)(), void (*d_push)());
|