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: 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");
56 /* Make new IrDA compressor */
57 new = (struct irda_compressor
*)
58 kmalloc( sizeof( struct irda_compressor
), GFP_KERNEL
);
62 memset( new, 0, sizeof( struct irda_compressor
));
65 /* Insert IrDA compressor into hashbin */
66 hashbin_insert( irlap_compressors
, (irda_queue_t
*) new, cp
->compress_proto
,
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
);
86 IRDA_DEBUG( 0, __FUNCTION__
"(), compressor not found!\n");
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
);
118 IRDA_DEBUG( 0, __FUNCTION__
"(), Unable to find compressor\n");
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");
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");
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
)
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");
205 if ((*self
->compressor
.cp
->comp_init
)( self
->compressor
.state
,
206 options
, sizeof( options
),
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");
221 if (( self
->decompressor
.cp
->decomp_init
)( self
->decompressor
.state
,
222 options
, sizeof( options
),
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
,
241 struct sk_buff
*new_skb
;
244 ASSERT( skb
!= NULL
, return NULL
;);
246 IRDA_DEBUG(4, __FUNCTION__
"() skb->len=%d, jiffies=%ld\n", (int) skb
->len
,
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
;
261 /* FIXME: Find out what is the max overhead (not 10) */
262 new_skb
= dev_alloc_skb( skb
->len
+LAP_MAX_HEADER
+10);
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
);
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 */
278 skb
->data
[0] = IRDA_NORMAL
;
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
;
290 IRDA_DEBUG(4, __FUNCTION__
"() new_skb->len=%d\n, jiffies=%ld",
291 (int) new_skb
->len
, jiffies
);
297 * Function irlap_decompress_frame (self, skb)
302 struct sk_buff
*irlap_decompress_frame( struct irlap_cb
*self
,
305 struct sk_buff
*new_skb
;
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
);
331 /* Remove compression header */
332 skb_pull( skb
, LAP_COMP_HEADER
);
334 new_skb
= dev_alloc_skb( 2048); /* FIXME: find the right size */
337 skb_put( new_skb
, 2048);
339 count
= irda_decompress( self
->decompressor
.state
, skb
->data
,
340 skb
->len
, new_skb
->data
, new_skb
->len
);
342 IRDA_DEBUG( 4, __FUNCTION__
"(), Unable to decompress frame!\n");
344 dev_kfree_skb( new_skb
);
348 skb_trim( new_skb
, count
);
350 IRDA_DEBUG( 4, __FUNCTION__
"() new_skb->len=%d\n", (int) new_skb
->len
);