~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/net/irda/wrapper.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.