00001 /* 00002 * SpanDSP - a series of DSP components for telephony 00003 * 00004 * v42bis.h 00005 * 00006 * Written by Steve Underwood <steveu@coppice.org> 00007 * 00008 * Copyright (C) 2005 Steve Underwood 00009 * 00010 * All rights reserved. 00011 * 00012 * This program is free software; you can redistribute it and/or modify 00013 * it under the terms of the GNU General Public License version 2, as 00014 * published by the Free Software Foundation. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software 00023 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00024 * 00025 * $Id: v42bis.h,v 1.19 2007/04/08 08:16:18 steveu Exp $ 00026 */ 00027 00028 /*! \page v42bis_page V.42bis modem data compression 00029 \section v42bis_page_sec_1 What does it do? 00030 The v.42bis specification defines a data compression scheme, to work in 00031 conjunction with the error correction scheme defined in V.42. 00032 00033 \section v42bis_page_sec_2 How does it work? 00034 */ 00035 00036 #if !defined(_SPANDSP_V42BIS_H_) 00037 #define _SPANDSP_V42BIS_H_ 00038 00039 #define V42BIS_MAX_BITS 12 00040 #define V42BIS_MAX_CODEWORDS 4096 /* 2^V42BIS_MAX_BITS */ 00041 #define V42BIS_TABLE_SIZE 5021 /* This should be a prime >(2^V42BIS_MAX_BITS) */ 00042 #define V42BIS_MAX_STRING_SIZE 250 00043 00044 enum 00045 { 00046 V42BIS_P0_NEITHER_DIRECTION = 0, 00047 V42BIS_P0_INITIATOR_RESPONDER, 00048 V42BIS_P0_RESPONDER_INITIATOR, 00049 V42BIS_P0_BOTH_DIRECTIONS 00050 }; 00051 00052 enum 00053 { 00054 V42BIS_COMPRESSION_MODE_DYNAMIC = 0, 00055 V42BIS_COMPRESSION_MODE_ALWAYS, 00056 V42BIS_COMPRESSION_MODE_NEVER 00057 }; 00058 00059 typedef void (*v42bis_frame_handler_t)(void *user_data, const uint8_t *pkt, int len); 00060 typedef void (*v42bis_data_handler_t)(void *user_data, const uint8_t *buf, int len); 00061 00062 typedef struct 00063 { 00064 /*! \brief The prior code for each defined code. */ 00065 uint16_t parent_code; 00066 /*! \brief The number of leaf nodes this node has */ 00067 int16_t leaves; 00068 /*! \brief This leaf octet for each defined code. */ 00069 uint8_t node_octet; 00070 /*! \brief Bit map of the children which exist */ 00071 uint32_t children[8]; 00072 } v42bis_dict_node_t; 00073 00074 typedef struct 00075 { 00076 /*! \brief Compression mode. */ 00077 int compression_mode; 00078 /*! \brief Callback function to handle received frames. */ 00079 v42bis_frame_handler_t handler; 00080 /*! \brief An opaque pointer passed in calls to frame_handler. */ 00081 void *user_data; 00082 /*! \brief The maximum frame length allowed */ 00083 int max_len; 00084 00085 uint32_t string_code; 00086 uint32_t latest_code; 00087 int string_length; 00088 uint32_t output_bit_buffer; 00089 int output_bit_count; 00090 int output_octet_count; 00091 uint8_t output_buf[1024]; 00092 v42bis_dict_node_t dict[V42BIS_MAX_CODEWORDS]; 00093 /*! \brief TRUE if we are in transparent (i.e. uncompressable) mode */ 00094 int transparent; 00095 int change_transparency; 00096 int compressibility_filter; 00097 int compressibility_persistence; 00098 00099 /*! \brief Next empty dictionary entry */ 00100 uint32_t v42bis_parm_c1; 00101 /*! \brief Current codeword size */ 00102 int v42bis_parm_c2; 00103 /*! \brief Threshold for codeword size change */ 00104 uint32_t v42bis_parm_c3; 00105 00106 /*! \brief Mark that this is the first octet/code to be processed */ 00107 int first; 00108 uint8_t escape_code; 00109 } v42bis_compress_state_t; 00110 00111 typedef struct 00112 { 00113 /*! \brief Callback function to handle decompressed data. */ 00114 v42bis_data_handler_t handler; 00115 /*! \brief An opaque pointer passed in calls to data_handler. */ 00116 void *user_data; 00117 /*! \brief The maximum decompressed data block length allowed */ 00118 int max_len; 00119 00120 uint32_t old_code; 00121 uint32_t last_old_code; 00122 uint32_t input_bit_buffer; 00123 int input_bit_count; 00124 int octet; 00125 int last_length; 00126 int output_octet_count; 00127 uint8_t output_buf[1024]; 00128 v42bis_dict_node_t dict[V42BIS_MAX_CODEWORDS]; 00129 /*! \brief TRUE if we are in transparent (i.e. uncompressable) mode */ 00130 int transparent; 00131 00132 int last_extra_octet; 00133 00134 /*! \brief Next empty dictionary entry */ 00135 uint32_t v42bis_parm_c1; 00136 /*! \brief Current codeword size */ 00137 int v42bis_parm_c2; 00138 /*! \brief Threshold for codeword size change */ 00139 uint32_t v42bis_parm_c3; 00140 00141 /*! \brief Mark that this is the first octet/code to be processed */ 00142 int first; 00143 uint8_t escape_code; 00144 int escaped; 00145 } v42bis_decompress_state_t; 00146 00147 /*! 00148 V.42bis compression/decompression descriptor. This defines the working state for a 00149 single instance of V.42bis compress/decompression. 00150 */ 00151 typedef struct 00152 { 00153 /*! \brief V.42bis data compression directions. */ 00154 int v42bis_parm_p0; 00155 00156 v42bis_compress_state_t compress; 00157 v42bis_decompress_state_t decompress; 00158 00159 /*! \brief Maximum codeword size (bits) */ 00160 int v42bis_parm_n1; 00161 /*! \brief Total number of codewords */ 00162 uint32_t v42bis_parm_n2; 00163 /*! \brief Maximum string length */ 00164 int v42bis_parm_n7; 00165 } v42bis_state_t; 00166 00167 #if defined(__cplusplus) 00168 extern "C" 00169 { 00170 #endif 00171 00172 /*! Compress a block of octets. 00173 \param s The V.42bis context. 00174 \param buf The data to be compressed. 00175 \param len The length of the data buffer. 00176 \return 0 */ 00177 int v42bis_compress(v42bis_state_t *s, const uint8_t *buf, int len); 00178 00179 /*! Flush out any data remaining in a compression buffer. 00180 \param s The V.42bis context. 00181 \return 0 */ 00182 int v42bis_compress_flush(v42bis_state_t *s); 00183 00184 /*! Decompress a block of octets. 00185 \param s The V.42bis context. 00186 \param buf The data to be decompressed. 00187 \param len The length of the data buffer. 00188 \return 0 */ 00189 int v42bis_decompress(v42bis_state_t *s, const uint8_t *buf, int len); 00190 00191 /*! Flush out any data remaining in the decompression buffer. 00192 \param s The V.42bis context. 00193 \return 0 */ 00194 int v42bis_decompress_flush(v42bis_state_t *s); 00195 00196 /*! Initialise a V.42bis context. 00197 \param s The V.42bis context. 00198 \param negotiated_p0 The negotiated P0 parameter, from the V.42bis spec. 00199 \param negotiated_p1 The negotiated P1 parameter, from the V.42bis spec. 00200 \param negotiated_p2 The negotiated P2 parameter, from the V.42bis spec. 00201 \param frame_handler . 00202 \param frame_user_data . 00203 \param max_frame_len The maximum length that should be passed to the frame handler. 00204 \param data_handler . 00205 \param data_user_data . 00206 \param max_data_len The maximum length that should be passed to the data handler. 00207 \return The V.42bis context. */ 00208 v42bis_state_t *v42bis_init(v42bis_state_t *s, 00209 int negotiated_p0, 00210 int negotiated_p1, 00211 int negotiated_p2, 00212 v42bis_frame_handler_t frame_handler, 00213 void *frame_user_data, 00214 int max_frame_len, 00215 v42bis_data_handler_t data_handler, 00216 void *data_user_data, 00217 int max_data_len); 00218 00219 /*! Set the compression mode. 00220 \param s The V.42bis context. 00221 \param mode One of the V.42bis compression modes - 00222 V42BIS_COMPRESSION_MODE_DYNAMIC, 00223 V42BIS_COMPRESSION_MODE_ALWAYS, 00224 V42BIS_COMPRESSION_MODE_NEVER */ 00225 void v42bis_compression_control(v42bis_state_t *s, int mode); 00226 00227 /*! Release a V.42bis context. 00228 \param s The V.42bis context. 00229 \return 0 if OK */ 00230 int v42bis_release(v42bis_state_t *s); 00231 00232 #if defined(__cplusplus) 00233 } 00234 #endif 00235 00236 #endif 00237 /*- End of file ------------------------------------------------------------*/