1 /*********************************************************************
3 * Filename: irlap_comp.c
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");
52 /* Make new IrDA compressor */
53 new = (struct irda_compressor
*)
54 kmalloc( sizeof( struct irda_compressor
), GFP_KERNEL
);
58 memset( new, 0, sizeof( struct irda_compressor
));
61 /* Insert IrDA compressor into hashbin */
62 hashbin_insert( irlap_compressors
, (QUEUE
*) new, cp
->compress_proto
,
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
);
82 DEBUG( 0, __FUNCTION__
"(), compressor not found!\n");
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
);
114 DEBUG( 0, __FUNCTION__
"(), Unable to find compressor\n");
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");
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");
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
)
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");
201 if ((*self
->compressor
.cp
->comp_init
)( self
->compressor
.state
,
202 options
, sizeof( options
),
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");
217 if (( self
->decompressor
.cp
->decomp_init
)( self
->decompressor
.state
,
218 options
, sizeof( options
),
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
,
237 struct sk_buff
*new_skb
;
240 ASSERT( skb
!= NULL
, return NULL
;);
242 DEBUG(4, __FUNCTION__
"() skb->len=%d, jiffies=%ld\n", (int) skb
->len
,
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
;
257 /* FIXME: Find out what is the max overhead (not 10) */
258 new_skb
= dev_alloc_skb( skb
->len
+LAP_MAX_HEADER
+10);
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
);
269 DEBUG(4, __FUNCTION__
"(), Unable to compress frame!\n");
270 dev_kfree_skb( new_skb
);
272 /* Tell peer that this frame is not compressed */
274 skb
->data
[0] = IRDA_NORMAL
;
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
;
286 DEBUG(4, __FUNCTION__
"() new_skb->len=%d\n, jiffies=%ld",
287 (int) new_skb
->len
, jiffies
);
293 * Function irlap_decompress_frame (self, skb)
298 struct sk_buff
*irlap_decompress_frame( struct irlap_cb
*self
,
301 struct sk_buff
*new_skb
;
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
);
327 /* Remove compression header */
328 skb_pull( skb
, LAP_COMP_HEADER
);
330 new_skb
= dev_alloc_skb( 2048); /* FIXME: find the right size */
333 skb_put( new_skb
, 2048);
335 count
= irda_decompress( self
->decompressor
.state
, skb
->data
,
336 skb
->len
, new_skb
->data
, new_skb
->len
);
338 DEBUG( 4, __FUNCTION__
"(), Unable to decompress frame!\n");
340 dev_kfree_skb( new_skb
);
344 skb_trim( new_skb
, count
);
346 DEBUG( 4, __FUNCTION__
"() new_skb->len=%d\n", (int) new_skb
->len
);