Import 2.3.4pre3
[davej-history.git] / net / irda / irlap_comp.c
blob57a6b420bebc4f7dfa6a241c6978cb95869cef65
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: Sun May 9 11:37:06 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 * Sources: ppp.c, isdn_ppp.c
13 * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
20 * Neither Dag Brattli nor University of Tromsø admit liability nor
21 * provide warranty for any of this software. This material is
22 * provided "AS-IS" and at no charge.
24 ********************************************************************/
26 #include <net/irda/irda.h>
27 #include <net/irda/irqueue.h>
28 #include <net/irda/irlap.h>
29 #include <net/irda/irlap_comp.h>
30 #include "../../drivers/net/zlib.h"
32 hashbin_t *irlap_compressors = NULL;
35 * Function irda_register_compressor (cp)
37 * Register new compressor with the IrLAP
40 int irda_register_compressor( struct compressor *cp)
42 struct irda_compressor *new;
44 DEBUG( 4, __FUNCTION__ "()\n");
46 /* Check if this compressor has been registred before */
47 if ( hashbin_find ( irlap_compressors, cp->compress_proto, NULL)) {
48 DEBUG( 0, __FUNCTION__ "(), Compressor already registered\n");
49 return 0;
52 /* Make new IrDA compressor */
53 new = (struct irda_compressor *)
54 kmalloc( sizeof( struct irda_compressor), GFP_KERNEL);
55 if (new == NULL)
56 return 1;
58 memset( new, 0, sizeof( struct irda_compressor));
59 new->cp = cp;
61 /* Insert IrDA compressor into hashbin */
62 hashbin_insert( irlap_compressors, (QUEUE *) new, cp->compress_proto,
63 NULL);
65 return 0;
69 * Function irda_unregister_compressor (cp)
71 * Unregister compressor
74 void irda_unregister_compressor ( struct compressor *cp)
76 struct irda_compressor *node;
78 DEBUG( 4, __FUNCTION__ "()\n");
80 node = hashbin_remove( irlap_compressors, cp->compress_proto, NULL);
81 if ( !node) {
82 DEBUG( 0, __FUNCTION__ "(), compressor not found!\n");
83 return;
85 kfree( node);
89 * Function irda_set_compression (self, proto)
91 * The the compression protocol to be used by this session
94 int irda_set_compression( struct irlap_cb *self, int proto)
96 struct compressor *cp;
97 struct irda_compressor *comp;
99 __u8 options[CILEN_DEFLATE];
101 DEBUG( 4, __FUNCTION__ "()\n");
103 ASSERT( self != NULL, return -ENODEV;);
104 ASSERT( self->magic == LAP_MAGIC, return -EBADR;);
106 /* Initialize options */
107 options[0] = CI_DEFLATE;
108 options[1] = CILEN_DEFLATE;
109 options[2] = DEFLATE_METHOD( DEFLATE_METHOD_VAL);
110 options[3] = DEFLATE_CHK_SEQUENCE;
112 comp = hashbin_find( irlap_compressors, proto, NULL);
113 if ( !comp) {
114 DEBUG( 0, __FUNCTION__ "(), Unable to find compressor\n");
115 return -1;
118 cp = comp->cp;
120 * Compressor part
122 if ( self->compressor.state != NULL)
123 (*self->compressor.cp->comp_free)( self->compressor.state);
124 self->compressor.state = NULL;
126 self->compressor.cp = cp;
127 self->compressor.state = cp->comp_alloc( options, sizeof( options));
128 if ( self->compressor.state == NULL) {
129 DEBUG( 0, __FUNCTION__ "(), Failed!\n");
130 return -ENOBUFS;
134 * Decompress part
137 if ( self->decompressor.state != NULL)
138 irda_decomp_free( self->decompressor.state);
139 self->decompressor.state = NULL;
141 self->decompressor.cp = cp;
142 self->decompressor.state = cp->decomp_alloc( options, sizeof( options));
143 if ( self->decompressor.state == NULL) {
144 DEBUG( 0, __FUNCTION__ "(), Failed!\n");
145 return -ENOBUFS;
147 return 0;
151 * Function irda_free_compression (self)
156 void irda_free_compression( struct irlap_cb *self)
158 DEBUG( 4, __FUNCTION__ "()\n");
160 if ( self->compressor.state) {
161 irda_comp_free( self->compressor.state);
162 self->compressor.state = NULL;
165 if ( self->decompressor.state) {
166 irda_decomp_free( self->decompressor.state);
167 self->decompressor.state = NULL;
172 * Function irlap_compress_init (self)
177 void irlap_compressor_init( struct irlap_cb *self, int compress)
179 int debug = TRUE;
180 __u8 options[CILEN_DEFLATE];
182 DEBUG(4, __FUNCTION__ "()\n");
184 ASSERT( self != NULL, return;);
185 ASSERT( self->magic == LAP_MAGIC, return;);
187 /* Initialize options */
188 options[0] = CI_DEFLATE;
189 options[1] = CILEN_DEFLATE;
190 options[2] = DEFLATE_METHOD_VAL;
191 options[3] = DEFLATE_CHK_SEQUENCE;
194 * We're agreeing to send compressed packets.
196 if ( self->compressor.state == NULL) {
197 DEBUG( 0, __FUNCTION__ "(), state == NULL\n");
198 return;
201 if ((*self->compressor.cp->comp_init)( self->compressor.state,
202 options, sizeof( options),
203 0, 0, debug))
205 DEBUG( 0, __FUNCTION__ "(), Compressor running!\n");
206 /* ppp->flags |= SC_COMP_RUN; */
210 * Initialize decompressor
212 if ( self->decompressor.state == NULL) {
213 DEBUG( 0, __FUNCTION__ "(), state == NULL\n");
214 return;
217 if (( self->decompressor.cp->decomp_init)( self->decompressor.state,
218 options, sizeof( options),
219 0, 0, 0, debug))
221 DEBUG( 0, __FUNCTION__ "(), Decompressor running!\n");
223 /* ppp->flags |= SC_DECOMP_RUN; */
224 /* ppp->flags &= ~(SC_DC_ERROR | SC_DC_FERROR); */
229 * Function irlap_compress_frame (self, skb)
234 struct sk_buff *irlap_compress_frame( struct irlap_cb *self,
235 struct sk_buff *skb)
237 struct sk_buff *new_skb;
238 int count;
240 ASSERT( skb != NULL, return NULL;);
242 DEBUG(4, __FUNCTION__ "() skb->len=%d, jiffies=%ld\n", (int) skb->len,
243 jiffies);
245 ASSERT( self != NULL, return NULL;);
246 ASSERT( self->magic == LAP_MAGIC, return NULL;);
248 /* Check if compressor got initialized */
249 if ( self->compressor.state == NULL) {
250 /* Tell peer that this frame is not compressed */
251 skb_push( skb, LAP_COMP_HEADER);
252 skb->data[0] = IRDA_NORMAL;
254 return skb;
257 /* FIXME: Find out what is the max overhead (not 10) */
258 new_skb = dev_alloc_skb( skb->len+LAP_MAX_HEADER+10);
259 if(!new_skb)
260 return skb;
262 skb_reserve( new_skb, LAP_MAX_HEADER);
263 skb_put( new_skb, skb->len+10);
265 count = (self->compressor.cp->compress)( self->compressor.state,
266 skb->data, new_skb->data,
267 skb->len, new_skb->len);
268 if( count <= 0) {
269 DEBUG(4, __FUNCTION__ "(), Unable to compress frame!\n");
270 dev_kfree_skb( new_skb);
272 /* Tell peer that this frame is not compressed */
273 skb_push( skb, 1);
274 skb->data[0] = IRDA_NORMAL;
276 return skb;
278 skb_trim( new_skb, count);
280 /* Tell peer that this frame is compressed */
281 skb_push( new_skb, 1);
282 new_skb->data[0] = IRDA_COMPRESSED;
284 dev_kfree_skb( skb);
286 DEBUG(4, __FUNCTION__ "() new_skb->len=%d\n, jiffies=%ld",
287 (int) new_skb->len, jiffies);
289 return new_skb;
293 * Function irlap_decompress_frame (self, skb)
298 struct sk_buff *irlap_decompress_frame( struct irlap_cb *self,
299 struct sk_buff *skb)
301 struct sk_buff *new_skb;
302 int count;
304 DEBUG( 4, __FUNCTION__ "() skb->len=%d\n", (int) skb->len);
306 ASSERT( self != NULL, return NULL;);
307 ASSERT( self->magic == LAP_MAGIC, return NULL;);
309 ASSERT( self->compressor.state != NULL, return NULL;);
311 /* Check if frame is compressed */
312 if ( skb->data[0] == IRDA_NORMAL) {
314 /* Remove compression header */
315 skb_pull( skb, LAP_COMP_HEADER);
318 * The frame is not compressed. Pass it to the
319 * decompression code so it can update its
320 * dictionary if necessary.
322 irda_incomp( self->decompressor.state, skb->data, skb->len);
324 return skb;
327 /* Remove compression header */
328 skb_pull( skb, LAP_COMP_HEADER);
330 new_skb = dev_alloc_skb( 2048); /* FIXME: find the right size */
331 if(!new_skb)
332 return skb;
333 skb_put( new_skb, 2048);
335 count = irda_decompress( self->decompressor.state, skb->data,
336 skb->len, new_skb->data, new_skb->len);
337 if ( count <= 0) {
338 DEBUG( 4, __FUNCTION__ "(), Unable to decompress frame!\n");
340 dev_kfree_skb( new_skb);
341 return skb;
344 skb_trim( new_skb, count);
346 DEBUG( 4, __FUNCTION__ "() new_skb->len=%d\n", (int) new_skb->len);
348 return new_skb;