1 /*********************************************************************
2 *
3 * Filename: wrapper.c
4 * Version: 1.2
5 * Description: IrDA SIR async wrapper layer
6 * Status: Stable
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Mon Aug 4 20:40:53 1997
9 * Modified at: Fri Jan 28 13:21:09 2000
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 *
14 * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
15 * 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/skbuff.h>
29 #include <linux/string.h>
30 #include <asm/byteorder.h>
31
32 #include <net/irda/irda.h>
33 #include <net/irda/wrapper.h>
34 #include <net/irda/irtty.h>
35 #include <net/irda/crc.h>
36 #include <net/irda/irlap.h>
37 #include <net/irda/irlap_frame.h>
38 #include <net/irda/irda_device.h>
39
40 static inline int stuff_byte(__u8 byte, __u8 *buf);
41
42 static void state_outside_frame(struct net_device *dev,
43 struct net_device_stats *stats,
44 iobuff_t *rx_buff, __u8 byte);
45 static void state_begin_frame(struct net_device *dev,
46 struct net_device_stats *stats,
47 iobuff_t *rx_buff, __u8 byte);
48 static void state_link_escape(struct net_device *dev,
49 struct net_device_stats *stats,
50 iobuff_t *rx_buff, __u8 byte);
51 static void state_inside_frame(struct net_device *dev,
52 struct net_device_stats *stats,
53 iobuff_t *rx_buff, __u8 byte);
54
55 static void (*state[])(struct net_device *dev, struct net_device_stats *stats,
56 iobuff_t *rx_buff, __u8 byte) =
57 {
58 state_outside_frame,
59 state_begin_frame,
60 state_link_escape,
61 state_inside_frame,
62 };
63
64 /*
65 * Function async_wrap (skb, *tx_buff, buffsize)
66 *
67 * Makes a new buffer with wrapping and stuffing, should check that
68 * we don't get tx buffer overflow.
69 */
70 int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize)
71 {
72 struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb;
73 int xbofs;
74 int i;
75 int n;
76 union {
77 __u16 value;
78 __u8 bytes[2];
79 } fcs;
80
81 /* Initialize variables */
82 fcs.value = INIT_FCS;
83 n = 0;
84
85 /*
86 * Send XBOF's for required min. turn time and for the negotiated
87 * additional XBOFS
88 */
89
90 if (cb->magic != LAP_MAGIC) {
91 /*
92 * This will happen for all frames sent from user-space.
93 * Nothing to worry about, but we set the default number of
94 * BOF's
95 */
96 IRDA_DEBUG(1, __FUNCTION__ "(), wrong magic in skb!\n");
97 xbofs = 10;
98 } else
99 xbofs = cb->xbofs + cb->xbofs_delay;
100
101 IRDA_DEBUG(4, __FUNCTION__ "(), xbofs=%d\n", xbofs);
102
103 /* Check that we never use more than 115 + 48 xbofs */
104 if (xbofs > 163) {
105 IRDA_DEBUG(0, __FUNCTION__ "(), too many xbofs (%d)\n", xbofs);
106 xbofs = 163;
107 }
108
109 memset(tx_buff+n, XBOF, xbofs);
110 n += xbofs;
111
112 /* Start of packet character BOF */
113 tx_buff[n++] = BOF;
114
115 /* Insert frame and calc CRC */
116 for (i=0; i < skb->len; i++) {
117 /*
118 * Check for the possibility of tx buffer overflow. We use
119 * bufsize-5 since the maximum number of bytes that can be
120 * transmitted after this point is 5.
121 */
122 ASSERT(n < (buffsize-5), return n;);
123
124 n += stuff_byte(skb->data[i], tx_buff+n);
125 fcs.value = irda_fcs(fcs.value, skb->data[i]);
126 }
127
128 /* Insert CRC in little endian format (LSB first) */
129 fcs.value = ~fcs.value;
130 #ifdef __LITTLE_ENDIAN
131 n += stuff_byte(fcs.bytes[0], tx_buff+n);
132 n += stuff_byte(fcs.bytes[1], tx_buff+n);
133 #else ifdef __BIG_ENDIAN
134 n += stuff_byte(fcs.bytes[1], tx_buff+n);
135 n += stuff_byte(fcs.bytes[0], tx_buff+n);
136 #endif
137 tx_buff[n++] = EOF;
138
139 return n;
140 }
141
142 /*
143 * Function stuff_byte (byte, buf)
144 *
145 * Byte stuff one single byte and put the result in buffer pointed to by
146 * buf. The buffer must at all times be able to have two bytes inserted.
147 *
148 */
149 static inline int stuff_byte(__u8 byte, __u8 *buf)
150 {
151 switch (byte) {
152 case BOF: /* FALLTHROUGH */
153 case EOF: /* FALLTHROUGH */
154 case CE:
155 /* Insert transparently coded */
156 buf[0] = CE; /* Send link escape */
157 buf[1] = byte^IRDA_TRANS; /* Complement bit 5 */
158 return 2;
159 /* break; */
160 default:
161 /* Non-special value, no transparency required */
162 buf[0] = byte;
163 return 1;
164 /* break; */
165 }
166 }
167
168 /*
169 * Function async_bump (buf, len, stats)
170 *
171 * Got a frame, make a copy of it, and pass it up the stack! We can try
172 * to inline it since it's only called from state_inside_frame
173 */
174 inline void async_bump(struct net_device *dev, struct net_device_stats *stats,
175 __u8 *buf, int len)
176 {
177 struct sk_buff *skb;
178
179 skb = dev_alloc_skb(len+1);
180 if (!skb) {
181 stats->rx_dropped++;
182 return;
183 }
184
185 /* Align IP header to 20 bytes */
186 skb_reserve(skb, 1);
187
188 /* Copy data without CRC */
189 memcpy(skb_put(skb, len-2), buf, len-2);
190
191 /* Feed it to IrLAP layer */
192 skb->dev = dev;
193 skb->mac.raw = skb->data;
194 skb->protocol = htons(ETH_P_IRDA);
195
196 netif_rx(skb);
197
198 stats->rx_packets++;
199 stats->rx_bytes += len;
200 }
201
202 /*
203 * Function async_unwrap_char (dev, rx_buff, byte)
204 *
205 * Parse and de-stuff frame received from the IrDA-port
206 *
207 */
208 inline void async_unwrap_char(struct net_device *dev,
209 struct net_device_stats *stats,
210 iobuff_t *rx_buff, __u8 byte)
211 {
212 (*state[rx_buff->state])(dev, stats, rx_buff, byte);
213 }
214
215 /*
216 * Function state_outside_frame (dev, rx_buff, byte)
217 *
218 * Not receiving any frame (or just bogus data)
219 *
220 */
221 static void state_outside_frame(struct net_device *dev,
222 struct net_device_stats *stats,
223 iobuff_t *rx_buff, __u8 byte)
224 {
225 switch (byte) {
226 case BOF:
227 rx_buff->state = BEGIN_FRAME;
228 rx_buff->in_frame = TRUE;
229 break;
230 case XBOF:
231 /* idev->xbofs++; */
232 break;
233 case EOF:
234 irda_device_set_media_busy(dev, TRUE);
235 break;
236 default:
237 irda_device_set_media_busy(dev, TRUE);
238 break;
239 }
240 }
241
242 /*
243 * Function state_begin_frame (idev, byte)
244 *
245 * Begin of frame detected
246 *
247 */
248 static void state_begin_frame(struct net_device *dev,
249 struct net_device_stats *stats,
250 iobuff_t *rx_buff, __u8 byte)
251 {
252 /* Time to initialize receive buffer */
253 rx_buff->data = rx_buff->head;
254 rx_buff->len = 0;
255 rx_buff->fcs = INIT_FCS;
256
257 switch (byte) {
258 case BOF:
259 /* Continue */
260 break;
261 case CE:
262 /* Stuffed byte */
263 rx_buff->state = LINK_ESCAPE;
264 break;
265 case EOF:
266 /* Abort frame */
267 rx_buff->state = OUTSIDE_FRAME;
268 IRDA_DEBUG(1, __FUNCTION__ "(), abort frame\n");
269 stats->rx_errors++;
270 stats->rx_frame_errors++;
271 break;
272 default:
273 rx_buff->data[rx_buff->len++] = byte;
274 rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
275 rx_buff->state = INSIDE_FRAME;
276 break;
277 }
278 }
279
280 /*
281 * Function state_link_escape (dev, byte)
282 *
283 * Found link escape character
284 *
285 */
286 static void state_link_escape(struct net_device *dev,
287 struct net_device_stats *stats,
288 iobuff_t *rx_buff, __u8 byte)
289 {
290 switch (byte) {
291 case BOF: /* New frame? */
292 IRDA_DEBUG(1, __FUNCTION__
293 "(), Discarding incomplete frame\n");
294 rx_buff->state = BEGIN_FRAME;
295 irda_device_set_media_busy(dev, TRUE);
296 break;
297 case CE:
298 WARNING(__FUNCTION__ "(), state not defined\n");
299 break;
300 case EOF: /* Abort frame */
301 rx_buff->state = OUTSIDE_FRAME;
302 break;
303 default:
304 /*
305 * Stuffed char, complement bit 5 of byte
306 * following CE, IrLAP p.114
307 */
308 byte ^= IRDA_TRANS;
309 if (rx_buff->len < rx_buff->truesize) {
310 rx_buff->data[rx_buff->len++] = byte;
311 rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
312 rx_buff->state = INSIDE_FRAME;
313 } else {
314 IRDA_DEBUG(1, __FUNCTION__ "(), rx buffer overflow\n");
315 rx_buff->state = OUTSIDE_FRAME;
316 }
317 break;
318 }
319 }
320
321 /*
322 * Function state_inside_frame (dev, byte)
323 *
324 * Handle bytes received within a frame
325 *
326 */
327 static void state_inside_frame(struct net_device *dev,
328 struct net_device_stats *stats,
329 iobuff_t *rx_buff, __u8 byte)
330 {
331 int ret = 0;
332
333 switch (byte) {
334 case BOF: /* New frame? */
335 IRDA_DEBUG(1, __FUNCTION__
336 "(), Discarding incomplete frame\n");
337 rx_buff->state = BEGIN_FRAME;
338 irda_device_set_media_busy(dev, TRUE);
339 break;
340 case CE: /* Stuffed char */
341 rx_buff->state = LINK_ESCAPE;
342 break;
343 case EOF: /* End of frame */
344 rx_buff->state = OUTSIDE_FRAME;
345 rx_buff->in_frame = FALSE;
346
347 /* Test FCS and signal success if the frame is good */
348 if (rx_buff->fcs == GOOD_FCS) {
349 /* Deliver frame */
350 async_bump(dev, stats, rx_buff->data, rx_buff->len);
351 ret = TRUE;
352 break;
353 } else {
354 /* Wrong CRC, discard frame! */
355 irda_device_set_media_busy(dev, TRUE);
356
357 IRDA_DEBUG(1, __FUNCTION__ "(), crc error\n");
358 stats->rx_errors++;
359 stats->rx_crc_errors++;
360 }
361 break;
362 default: /* Must be the next byte of the frame */
363 if (rx_buff->len < rx_buff->truesize) {
364 rx_buff->data[rx_buff->len++] = byte;
365 rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
366 } else {
367 IRDA_DEBUG(1, __FUNCTION__
368 "(), Rx buffer overflow, aborting\n");
369 rx_buff->state = OUTSIDE_FRAME;
370 }
371 break;
372 }
373 }
374
375
376
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.