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
14 *
15 * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
16 *
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.
21 *
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.
25 *
26 ********************************************************************/
27
28 #include <linux/string.h>
29
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"
35
36 hashbin_t *irlap_compressors = NULL;
37
38 /*
39 * Function irda_register_compressor (cp)
40 *
41 * Register new compressor with the IrLAP
42 *
43 */
44 int irda_register_compressor( struct compressor *cp)
45 {
46 struct irda_compressor *new;
47
48 IRDA_DEBUG( 4, __FUNCTION__ "()\n");
49
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;
54 }
55
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;
61
62 memset( new, 0, sizeof( struct irda_compressor));
63 new->cp = cp;
64
65 /* Insert IrDA compressor into hashbin */
66 hashbin_insert( irlap_compressors, (irda_queue_t *) new, cp->compress_proto,
67 NULL);
68
69 return 0;
70 }
71
72 /*
73 * Function irda_unregister_compressor (cp)
74 *
75 * Unregister compressor
76 *
77 */
78 void irda_unregister_compressor ( struct compressor *cp)
79 {
80 struct irda_compressor *node;
81
82 IRDA_DEBUG( 4, __FUNCTION__ "()\n");
83
84 node = hashbin_remove( irlap_compressors, cp->compress_proto, NULL);
85 if ( !node) {
86 IRDA_DEBUG( 0, __FUNCTION__ "(), compressor not found!\n");
87 return;
88 }
89 kfree( node);
90 }
91
92 /*
93 * Function irda_set_compression (self, proto)
94 *
95 * The the compression protocol to be used by this session
96 *
97 */
98 int irda_set_compression( struct irlap_cb *self, int proto)
99 {
100 struct compressor *cp;
101 struct irda_compressor *comp;
102
103 __u8 options[CILEN_DEFLATE];
104
105 IRDA_DEBUG( 4, __FUNCTION__ "()\n");
106
107 ASSERT( self != NULL, return -ENODEV;);
108 ASSERT( self->magic == LAP_MAGIC, return -EBADR;);
109
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;
115
116 comp = hashbin_find( irlap_compressors, proto, NULL);
117 if ( !comp) {
118 IRDA_DEBUG( 0, __FUNCTION__ "(), Unable to find compressor\n");
119 return -1;
120 }
121
122 cp = comp->cp;
123 /*
124 * Compressor part
125 */
126 if ( self->compressor.state != NULL)
127 (*self->compressor.cp->comp_free)( self->compressor.state);
128 self->compressor.state = NULL;
129
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;
135 }
136
137 /*
138 * Decompress part
139 */
140
141 if ( self->decompressor.state != NULL)
142 irda_decomp_free( self->decompressor.state);
143 self->decompressor.state = NULL;
144
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;
150 }
151 return 0;
152 }
153
154 /*
155 * Function irda_free_compression (self)
156 *
157 *
158 *
159 */
160 void irda_free_compression( struct irlap_cb *self)
161 {
162 IRDA_DEBUG( 4, __FUNCTION__ "()\n");
163
164 if ( self->compressor.state) {
165 irda_comp_free( self->compressor.state);
166 self->compressor.state = NULL;
167 }
168
169 if ( self->decompressor.state) {
170 irda_decomp_free( self->decompressor.state);
171 self->decompressor.state = NULL;
172 }
173 }
174
175 /*
176 * Function irlap_compress_init (self)
177 *
178 *
179 *
180 */
181 void irlap_compressor_init( struct irlap_cb *self, int compress)
182 {
183 int debug = TRUE;
184 __u8 options[CILEN_DEFLATE];
185
186 IRDA_DEBUG(4, __FUNCTION__ "()\n");
187
188 ASSERT( self != NULL, return;);
189 ASSERT( self->magic == LAP_MAGIC, return;);
190
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;
196
197 /*
198 * We're agreeing to send compressed packets.
199 */
200 if ( self->compressor.state == NULL) {
201 IRDA_DEBUG( 0, __FUNCTION__ "(), state == NULL\n");
202 return;
203 }
204
205 if ((*self->compressor.cp->comp_init)( self->compressor.state,
206 options, sizeof( options),
207 0, 0, debug))
208 {
209 IRDA_DEBUG( 0, __FUNCTION__ "(), Compressor running!\n");
210 /* ppp->flags |= SC_COMP_RUN; */
211 }
212
213 /*
214 * Initialize decompressor
215 */
216 if ( self->decompressor.state == NULL) {
217 IRDA_DEBUG( 0, __FUNCTION__ "(), state == NULL\n");
218 return;
219 }
220
221 if (( self->decompressor.cp->decomp_init)( self->decompressor.state,
222 options, sizeof( options),
223 0, 0, 0, debug))
224 {
225 IRDA_DEBUG( 0, __FUNCTION__ "(), Decompressor running!\n");
226
227 /* ppp->flags |= SC_DECOMP_RUN; */
228 /* ppp->flags &= ~(SC_DC_ERROR | SC_DC_FERROR); */
229 }
230 }
231
232 /*
233 * Function irlap_compress_frame (self, skb)
234 *
235 *
236 *
237 */
238 struct sk_buff *irlap_compress_frame( struct irlap_cb *self,
239 struct sk_buff *skb)
240 {
241 struct sk_buff *new_skb;
242 int count;
243
244 ASSERT( skb != NULL, return NULL;);
245
246 IRDA_DEBUG(4, __FUNCTION__ "() skb->len=%d, jiffies=%ld\n", (int) skb->len,
247 jiffies);
248
249 ASSERT( self != NULL, return NULL;);
250 ASSERT( self->magic == LAP_MAGIC, return NULL;);
251
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;
257
258 return skb;
259 }
260
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;
265
266 skb_reserve( new_skb, LAP_MAX_HEADER);
267 skb_put( new_skb, skb->len+10);
268
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);
275
276 /* Tell peer that this frame is not compressed */
277 skb_push( skb, 1);
278 skb->data[0] = IRDA_NORMAL;
279
280 return skb;
281 }
282 skb_trim( new_skb, count);
283
284 /* Tell peer that this frame is compressed */
285 skb_push( new_skb, 1);
286 new_skb->data[0] = IRDA_COMPRESSED;
287
288 dev_kfree_skb( skb);
289
290 IRDA_DEBUG(4, __FUNCTION__ "() new_skb->len=%d\n, jiffies=%ld",
291 (int) new_skb->len, jiffies);
292
293 return new_skb;
294 }
295
296 /*
297 * Function irlap_decompress_frame (self, skb)
298 *
299 *
300 *
301 */
302 struct sk_buff *irlap_decompress_frame( struct irlap_cb *self,
303 struct sk_buff *skb)
304 {
305 struct sk_buff *new_skb;
306 int count;
307
308 IRDA_DEBUG( 4, __FUNCTION__ "() skb->len=%d\n", (int) skb->len);
309
310 ASSERT( self != NULL, return NULL;);
311 ASSERT( self->magic == LAP_MAGIC, return NULL;);
312
313 ASSERT( self->compressor.state != NULL, return NULL;);
314
315 /* Check if frame is compressed */
316 if ( skb->data[0] == IRDA_NORMAL) {
317
318 /* Remove compression header */
319 skb_pull( skb, LAP_COMP_HEADER);
320
321 /*
322 * The frame is not compressed. Pass it to the
323 * decompression code so it can update its
324 * dictionary if necessary.
325 */
326 irda_incomp( self->decompressor.state, skb->data, skb->len);
327
328 return skb;
329 }
330
331 /* Remove compression header */
332 skb_pull( skb, LAP_COMP_HEADER);
333
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);
338
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");
343
344 dev_kfree_skb( new_skb);
345 return skb;
346 }
347
348 skb_trim( new_skb, count);
349
350 IRDA_DEBUG( 4, __FUNCTION__ "() new_skb->len=%d\n", (int) new_skb->len);
351
352 return new_skb;
353 }
354
355
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.