- Linus: drop support for old-style Makefiles entirely. Big.
[davej-history.git] / net / irda / irlap_comp.c
blobe81fc7e4a6d290ebeec3829d9380d58ba2b27005
1 /*********************************************************************
2 *
3 * Filename: irlap_comp.c
4 * Version:
5 * Description:
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Fri Oct 9 09:18:07 1998
9 * Modified at: Tue Oct 5 11:34:52 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 * Modified at: Fri May 28 3:11 CST 1999
12 * Modified by: Horst von Brand <vonbrand@sleipnir.valparaiso.cl>
13 * Sources: ppp.c, isdn_ppp.c
15 * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License as
19 * published by the Free Software Foundation; either version 2 of
20 * the License, or (at your option) any later version.
22 * Neither Dag Brattli nor University of Tromsø admit liability nor
23 * provide warranty for any of this software. This material is
24 * provided "AS-IS" and at no charge.
26 ********************************************************************/
28 #include <linux/string.h>
30 #include <net/irda/irda.h>
31 #include <net/irda/irqueue.h>
32 #include <net/irda/irlap.h>
33 #include <net/irda/irlap_comp.h>
34 #include "../../drivers/net/zlib.h"
36 hashbin_t *irlap_compressors = NULL;
39 * Function irda_register_compressor (cp)
41 * Register new compressor with the IrLAP
44 int irda_register_compressor( struct compressor *cp)
46 struct irda_compressor *new;
48 IRDA_DEBUG( 4, __FUNCTION__ "()\n");
50 /* Check if this compressor has been registred before */
51 if ( hashbin_find ( irlap_compressors, cp->compress_proto, NULL)) {
52 IRDA_DEBUG( 0, __FUNCTION__ "(), Compressor already registered\n");
53 return 0;
56 /* Make new IrDA compressor */
57 new = (struct irda_compressor *)
58 kmalloc( sizeof( struct irda_compressor), GFP_KERNEL);
59 if (new == NULL)
60 return 1;
62 memset( new, 0, sizeof( struct irda_compressor));
63 new->cp = cp;
65 /* Insert IrDA compressor into hashbin */
66 hashbin_insert( irlap_compressors, (irda_queue_t *) new, cp->compress_proto,
67 NULL);
69 return 0;
73 * Function irda_unregister_compressor (cp)
75 * Unregister compressor
78 void irda_unregister_compressor ( struct compressor *cp)
80 struct irda_compressor *node;
82 IRDA_DEBUG( 4, __FUNCTION__ "()\n");
84 node = hashbin_remove( irlap_compressors, cp->compress_proto, NULL);
85 if ( !node) {
86 IRDA_DEBUG( 0, __FUNCTION__ "(), compressor not found!\n");
87 return;
89 kfree( node);
93 * Function irda_set_compression (self, proto)
95 * The the compression protocol to be used by this session
98 int irda_set_compression( struct irlap_cb *self, int proto)
100 struct compressor *cp;
101 struct irda_compressor *comp;
103 __u8 options[CILEN_DEFLATE];
105 IRDA_DEBUG( 4, __FUNCTION__ "()\n");
107 ASSERT( self != NULL, return -ENODEV;);
108 ASSERT( self->magic == LAP_MAGIC, return -EBADR;);
110 /* Initialize options */
111 options[0] = CI_DEFLATE;
112 options[1] = CILEN_DEFLATE;
113 options[2] = DEFLATE_METHOD( DEFLATE_METHOD_VAL);
114 options[3] = DEFLATE_CHK_SEQUENCE;
116 comp = hashbin_find( irlap_compressors, proto, NULL);
117 if ( !comp) {
118 IRDA_DEBUG( 0, __FUNCTION__ "(), Unable to find compressor\n");
119 return -1;
122 cp = comp->cp;
124 * Compressor part
126 if ( self->compressor.state != NULL)
127 (*self->compressor.cp->comp_free)( self->compressor.state);
128 self->compressor.state = NULL;
130 self->compressor.cp = cp;
131 self->compressor.state = cp->comp_alloc( options, sizeof( options));
132 if ( self->compressor.state == NULL) {
133 IRDA_DEBUG( 0, __FUNCTION__ "(), Failed!\n");
134 return -ENOBUFS;
138 * Decompress part
141 if ( self->decompressor.state != NULL)
142 irda_decomp_free( self->decompressor.state);
143 self->decompressor.state = NULL;
145 self->decompressor.cp = cp;
146 self->decompressor.state = cp->decomp_alloc( options, sizeof( options));
147 if ( self->decompressor.state == NULL) {
148 IRDA_DEBUG( 0, __FUNCTION__ "(), Failed!\n");
149 return -ENOBUFS;
151 return 0;
155 * Function irda_free_compression (self)
160 void irda_free_compression( struct irlap_cb *self)
162 IRDA_DEBUG( 4, __FUNCTION__ "()\n");
164 if ( self->compressor.state) {
165 irda_comp_free( self->compressor.state);
166 self->compressor.state = NULL;
169 if ( self->decompressor.state) {
170 irda_decomp_free( self->decompressor.state);
171 self->decompressor.state = NULL;
176 * Function irlap_compress_init (self)
181 void irlap_compressor_init( struct irlap_cb *self, int compress)
183 int debug = TRUE;
184 __u8 options[CILEN_DEFLATE];
186 IRDA_DEBUG(4, __FUNCTION__ "()\n");
188 ASSERT( self != NULL, return;);
189 ASSERT( self->magic == LAP_MAGIC, return;);
191 /* Initialize options */
192 options[0] = CI_DEFLATE;
193 options[1] = CILEN_DEFLATE;
194 options[2] = DEFLATE_METHOD_VAL;
195 options[3] = DEFLATE_CHK_SEQUENCE;
198 * We're agreeing to send compressed packets.
200 if ( self->compressor.state == NULL) {
201 IRDA_DEBUG( 0, __FUNCTION__ "(), state == NULL\n");
202 return;
205 if ((*self->compressor.cp->comp_init)( self->compressor.state,
206 options, sizeof( options),
207 0, 0, debug))
209 IRDA_DEBUG( 0, __FUNCTION__ "(), Compressor running!\n");
210 /* ppp->flags |= SC_COMP_RUN; */
214 * Initialize decompressor
216 if ( self->decompressor.state == NULL) {
217 IRDA_DEBUG( 0, __FUNCTION__ "(), state == NULL\n");
218 return;
221 if (( self->decompressor.cp->decomp_init)( self->decompressor.state,
222 options, sizeof( options),
223 0, 0, 0, debug))
225 IRDA_DEBUG( 0, __FUNCTION__ "(), Decompressor running!\n");
227 /* ppp->flags |= SC_DECOMP_RUN; */
228 /* ppp->flags &= ~(SC_DC_ERROR | SC_DC_FERROR); */
233 * Function irlap_compress_frame (self, skb)
238 struct sk_buff *irlap_compress_frame( struct irlap_cb *self,
239 struct sk_buff *skb)
241 struct sk_buff *new_skb;
242 int count;
244 ASSERT( skb != NULL, return NULL;);
246 IRDA_DEBUG(4, __FUNCTION__ "() skb->len=%d, jiffies=%ld\n", (int) skb->len,
247 jiffies);
249 ASSERT( self != NULL, return NULL;);
250 ASSERT( self->magic == LAP_MAGIC, return NULL;);
252 /* Check if compressor got initialized */
253 if ( self->compressor.state == NULL) {
254 /* Tell peer that this frame is not compressed */
255 skb_push( skb, LAP_COMP_HEADER);
256 skb->data[0] = IRDA_NORMAL;
258 return skb;
261 /* FIXME: Find out what is the max overhead (not 10) */
262 new_skb = dev_alloc_skb( skb->len+LAP_MAX_HEADER+10);
263 if(!new_skb)
264 return skb;
266 skb_reserve( new_skb, LAP_MAX_HEADER);
267 skb_put( new_skb, skb->len+10);
269 count = (self->compressor.cp->compress)( self->compressor.state,
270 skb->data, new_skb->data,
271 skb->len, new_skb->len);
272 if( count <= 0) {
273 IRDA_DEBUG(4, __FUNCTION__ "(), Unable to compress frame!\n");
274 dev_kfree_skb( new_skb);
276 /* Tell peer that this frame is not compressed */
277 skb_push( skb, 1);
278 skb->data[0] = IRDA_NORMAL;
280 return skb;
282 skb_trim( new_skb, count);
284 /* Tell peer that this frame is compressed */
285 skb_push( new_skb, 1);
286 new_skb->data[0] = IRDA_COMPRESSED;
288 dev_kfree_skb( skb);
290 IRDA_DEBUG(4, __FUNCTION__ "() new_skb->len=%d\n, jiffies=%ld",
291 (int) new_skb->len, jiffies);
293 return new_skb;
297 * Function irlap_decompress_frame (self, skb)
302 struct sk_buff *irlap_decompress_frame( struct irlap_cb *self,
303 struct sk_buff *skb)
305 struct sk_buff *new_skb;
306 int count;
308 IRDA_DEBUG( 4, __FUNCTION__ "() skb->len=%d\n", (int) skb->len);
310 ASSERT( self != NULL, return NULL;);
311 ASSERT( self->magic == LAP_MAGIC, return NULL;);
313 ASSERT( self->compressor.state != NULL, return NULL;);
315 /* Check if frame is compressed */
316 if ( skb->data[0] == IRDA_NORMAL) {
318 /* Remove compression header */
319 skb_pull( skb, LAP_COMP_HEADER);
322 * The frame is not compressed. Pass it to the
323 * decompression code so it can update its
324 * dictionary if necessary.
326 irda_incomp( self->decompressor.state, skb->data, skb->len);
328 return skb;
331 /* Remove compression header */
332 skb_pull( skb, LAP_COMP_HEADER);
334 new_skb = dev_alloc_skb( 2048); /* FIXME: find the right size */
335 if(!new_skb)
336 return skb;
337 skb_put( new_skb, 2048);
339 count = irda_decompress( self->decompressor.state, skb->data,
340 skb->len, new_skb->data, new_skb->len);
341 if ( count <= 0) {
342 IRDA_DEBUG( 4, __FUNCTION__ "(), Unable to decompress frame!\n");
344 dev_kfree_skb( new_skb);
345 return skb;
348 skb_trim( new_skb, count);
350 IRDA_DEBUG( 4, __FUNCTION__ "() new_skb->len=%d\n", (int) new_skb->len);
352 return new_skb;