Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

wrapper.c

Go to the documentation of this file.
00001 /*********************************************************************
00002  *                
00003  * Filename:      wrapper.c
00004  * Version:       1.2
00005  * Description:   IrDA SIR async wrapper layer
00006  * Status:        Stable
00007  * Author:        Dag Brattli <dagb@cs.uit.no>
00008  * Created at:    Mon Aug  4 20:40:53 1997
00009  * Modified at:   Sat Jan 15 13:32:27 2000
00010  * Modified by:   Dag Brattli <dagb@cs.uit.no>
00011  * Modified at:   Fri May 28  3:11 CST 1999
00012  * Modified by:   Horst von Brand <vonbrand@sleipnir.valparaiso.cl>
00013  * 
00014  *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>, 
00015  *     All Rights Reserved.
00016  *     
00017  *     This program is free software; you can redistribute it and/or 
00018  *     modify it under the terms of the GNU General Public License as 
00019  *     published by the Free Software Foundation; either version 2 of 
00020  *     the License, or (at your option) any later version.
00021  *
00022  *     Neither Dag Brattli nor University of Tromsų admit liability nor
00023  *     provide warranty for any of this software. This material is 
00024  *     provided "AS-IS" and at no charge.
00025  *
00026  ********************************************************************/
00027 
00028 #include <linux/skbuff.h>
00029 #include <linux/string.h>
00030 #include <asm/byteorder.h>
00031 
00032 #include <net/irda/irda.h>
00033 #include <net/irda/wrapper.h>
00034 #include <net/irda/irtty.h>
00035 #include <net/irda/crc.h>
00036 #include <net/irda/irlap.h>
00037 #include <net/irda/irlap_frame.h>
00038 #include <net/irda/irda_device.h>
00039 
00040 static inline int stuff_byte(__u8 byte, __u8 *buf);
00041 
00042 static void state_outside_frame(struct device *dev, 
00043                                 struct net_device_stats *stats, 
00044                                 iobuff_t *rx_buff, __u8 byte);
00045 static void state_begin_frame(struct device *dev, 
00046                               struct net_device_stats *stats, 
00047                               iobuff_t *rx_buff, __u8 byte);
00048 static void state_link_escape(struct device *dev, 
00049                               struct net_device_stats *stats, 
00050                               iobuff_t *rx_buff, __u8 byte);
00051 static void state_inside_frame(struct device *dev, 
00052                                struct net_device_stats *stats, 
00053                                iobuff_t *rx_buff, __u8 byte);
00054 
00055 static void (*state[])(struct device *dev, struct net_device_stats *stats, 
00056                        iobuff_t *rx_buff, __u8 byte) = 
00057 { 
00058         state_outside_frame,
00059         state_begin_frame,
00060         state_link_escape,
00061         state_inside_frame,
00062 };
00063 
00064 /*
00065  * Function async_wrap (skb, *tx_buff, buffsize)
00066  *
00067  *    Makes a new buffer with wrapping and stuffing, should check that 
00068  *    we don't get tx buffer overflow.
00069  */
00070 int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize)
00071 {
00072         int xbofs;
00073         int i;
00074         int n;
00075         union {
00076                 __u16 value;
00077                 __u8 bytes[2];
00078         } fcs;
00079 
00080         /* Initialize variables */
00081         fcs.value = INIT_FCS;
00082         n = 0;
00083 
00084         /*
00085          *  Send  XBOF's for required min. turn time and for the negotiated
00086          *  additional XBOFS
00087          */
00088         if (((struct irda_skb_cb *)(skb->cb))->magic != LAP_MAGIC) {
00089                 /* 
00090                  * This will happen for all frames sent from user-space.
00091                  * Nothing to worry about, but we set the default number of 
00092                  * BOF's
00093                  */
00094                 IRDA_DEBUG(1, __FUNCTION__ "(), wrong magic in skb!\n");
00095                 xbofs = 10;
00096         } else
00097                 xbofs = ((struct irda_skb_cb *)(skb->cb))->xbofs;
00098 
00099         IRDA_DEBUG(4, __FUNCTION__ "(), xbofs=%d\n", xbofs);
00100 
00101         /* Check that we never use more than 115 + 48 xbofs */
00102         if (xbofs > 163) {
00103                 IRDA_DEBUG(0, __FUNCTION__ "(), too many xbofs (%d)\n", xbofs);
00104                 xbofs = 163;
00105         }
00106 
00107         memset(tx_buff+n, XBOF, xbofs);
00108         n += xbofs;
00109 
00110         /* Start of packet character BOF */
00111         tx_buff[n++] = BOF;
00112 
00113         /* Insert frame and calc CRC */
00114         for (i=0; i < skb->len; i++) {
00115                 /*
00116                  *  Check for the possibility of tx buffer overflow. We use
00117                  *  bufsize-5 since the maximum number of bytes that can be 
00118                  *  transmitted after this point is 5.
00119                  */
00120                 ASSERT(n < (buffsize-5), return n;);
00121 
00122                 n += stuff_byte(skb->data[i], tx_buff+n);
00123                 fcs.value = irda_fcs(fcs.value, skb->data[i]);
00124         }
00125         
00126         /* Insert CRC in little endian format (LSB first) */
00127         fcs.value = ~fcs.value;
00128 #ifdef __LITTLE_ENDIAN
00129         n += stuff_byte(fcs.bytes[0], tx_buff+n);
00130         n += stuff_byte(fcs.bytes[1], tx_buff+n);
00131 #else ifdef __BIG_ENDIAN
00132         n += stuff_byte(fcs.bytes[1], tx_buff+n);
00133         n += stuff_byte(fcs.bytes[0], tx_buff+n);
00134 #endif
00135         tx_buff[n++] = EOF;
00136 
00137         return n;
00138 }
00139 
00140 /*
00141  * Function stuff_byte (byte, buf)
00142  *
00143  *    Byte stuff one single byte and put the result in buffer pointed to by
00144  *    buf. The buffer must at all times be able to have two bytes inserted.
00145  * 
00146  */
00147 static inline int stuff_byte(__u8 byte, __u8 *buf) 
00148 {
00149         switch (byte) {
00150         case BOF: /* FALLTHROUGH */
00151         case EOF: /* FALLTHROUGH */
00152         case CE:
00153                 /* Insert transparently coded */
00154                 buf[0] = CE;               /* Send link escape */
00155                 buf[1] = byte^IRDA_TRANS;    /* Complement bit 5 */
00156                 return 2;
00157                 /* break; */
00158         default:
00159                  /* Non-special value, no transparency required */
00160                 buf[0] = byte;
00161                 return 1;
00162                 /* break; */
00163         }
00164 }
00165 
00166 /*
00167  * Function async_bump (buf, len, stats)
00168  *
00169  *    Got a frame, make a copy of it, and pass it up the stack! We can try
00170  *    to inline it since it's only called from state_inside_frame
00171  */
00172 inline void async_bump(struct device *dev, struct net_device_stats *stats,
00173                        __u8 *buf, int len)
00174 {
00175         struct sk_buff *skb;
00176 
00177         skb = dev_alloc_skb(len+1);
00178         if (!skb)  {
00179                 stats->rx_dropped++;
00180                 return;
00181         }
00182 
00183         /* Align IP header to 20 bytes */
00184         skb_reserve(skb, 1);
00185         
00186         /* Copy data without CRC */
00187         memcpy(skb_put(skb, len-2), buf, len-2); 
00188         
00189         /* Feed it to IrLAP layer */
00190         skb->dev = dev;
00191         skb->mac.raw  = skb->data;
00192         skb->protocol = htons(ETH_P_IRDA);
00193 
00194         netif_rx(skb);
00195 
00196         stats->rx_packets++;
00197         stats->rx_bytes += len; 
00198 }
00199 
00200 /*
00201  * Function async_unwrap_char (dev, rx_buff, byte)
00202  *
00203  *    Parse and de-stuff frame received from the IrDA-port
00204  *
00205  */
00206 inline void async_unwrap_char(struct device *dev, 
00207                               struct net_device_stats *stats, 
00208                               iobuff_t *rx_buff, __u8 byte)
00209 {
00210         (*state[rx_buff->state])(dev, stats, rx_buff, byte);
00211 }
00212          
00213 /*
00214  * Function state_outside_frame (dev, rx_buff, byte)
00215  *
00216  *    Not receiving any frame (or just bogus data)
00217  *
00218  */
00219 static void state_outside_frame(struct device *dev, 
00220                                 struct net_device_stats *stats, 
00221                                 iobuff_t *rx_buff, __u8 byte)
00222 {
00223         switch (byte) {
00224         case BOF:
00225                 rx_buff->state = BEGIN_FRAME;
00226                 rx_buff->in_frame = TRUE;
00227                 break;
00228         case XBOF:
00229                 /* idev->xbofs++; */
00230                 break;
00231         case EOF:
00232                 irda_device_set_media_busy(dev, TRUE);
00233                 break;
00234         default:
00235                 irda_device_set_media_busy(dev, TRUE);
00236                 break;
00237         }
00238 }
00239 
00240 /*
00241  * Function state_begin_frame (idev, byte)
00242  *
00243  *    Begin of frame detected
00244  *
00245  */
00246 static void state_begin_frame(struct device *dev, 
00247                               struct net_device_stats *stats, 
00248                               iobuff_t *rx_buff, __u8 byte)
00249 {
00250         /* Time to initialize receive buffer */
00251         rx_buff->data = rx_buff->head;
00252         rx_buff->len = 0;
00253         rx_buff->fcs = INIT_FCS;
00254 
00255         switch (byte) {
00256         case BOF:
00257                 /* Continue */
00258                 break;
00259         case CE:
00260                 /* Stuffed byte */
00261                 rx_buff->state = LINK_ESCAPE;
00262                 break;
00263         case EOF:
00264                 /* Abort frame */
00265                 rx_buff->state = OUTSIDE_FRAME;
00266                 IRDA_DEBUG(1, __FUNCTION__ "(), abort frame\n");
00267                 stats->rx_errors++;
00268                 stats->rx_frame_errors++;
00269                 break;
00270         default:
00271                 rx_buff->data[rx_buff->len++] = byte;
00272                 rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
00273                 rx_buff->state = INSIDE_FRAME;
00274                 break;
00275         }
00276 }
00277 
00278 /*
00279  * Function state_link_escape (dev, byte)
00280  *
00281  *    Found link escape character
00282  *
00283  */
00284 static void state_link_escape(struct device *dev, 
00285                               struct net_device_stats *stats, 
00286                               iobuff_t *rx_buff, __u8 byte)
00287 {
00288         switch (byte) {
00289         case BOF: /* New frame? */
00290                 rx_buff->state = BEGIN_FRAME;
00291                 irda_device_set_media_busy(dev, TRUE);
00292                 break;
00293         case CE:
00294                 WARNING(__FUNCTION__ "(), state not defined\n");
00295                 break;
00296         case EOF: /* Abort frame */
00297                 rx_buff->state = OUTSIDE_FRAME;
00298                 break;
00299         default:
00300                 /* 
00301                  *  Stuffed char, complement bit 5 of byte 
00302                  *  following CE, IrLAP p.114 
00303                  */
00304                 byte ^= IRDA_TRANS;
00305                 if (rx_buff->len < rx_buff->truesize)  {
00306                         rx_buff->data[rx_buff->len++] = byte;
00307                         rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
00308                         rx_buff->state = INSIDE_FRAME;
00309                 } else {
00310                         IRDA_DEBUG(1, __FUNCTION__ "(), rx buffer overflow\n");
00311                         rx_buff->state = OUTSIDE_FRAME;
00312                 }
00313                 break;
00314         }
00315 }
00316 
00317 /*
00318  * Function state_inside_frame (dev, byte)
00319  *
00320  *    Handle bytes received within a frame
00321  *
00322  */
00323 static void state_inside_frame(struct device *dev, 
00324                                struct net_device_stats *stats,
00325                                iobuff_t *rx_buff, __u8 byte)
00326 {
00327         int ret = 0; 
00328 
00329         switch (byte) {
00330         case BOF: /* New frame? */
00331                 rx_buff->state = BEGIN_FRAME;
00332                 irda_device_set_media_busy(dev, TRUE);
00333                 break;
00334         case CE: /* Stuffed char */
00335                 rx_buff->state = LINK_ESCAPE;
00336                 break;
00337         case EOF: /* End of frame */
00338                 rx_buff->state = OUTSIDE_FRAME;
00339                 rx_buff->in_frame = FALSE;
00340                 
00341                 /* Test FCS and signal success if the frame is good */
00342                 if (rx_buff->fcs == GOOD_FCS) {
00343                         /* Deliver frame */
00344                         async_bump(dev, stats, rx_buff->data, rx_buff->len);
00345                         ret = TRUE;
00346                         break;
00347                 } else {
00348                         /* Wrong CRC, discard frame!  */
00349                         irda_device_set_media_busy(dev, TRUE); 
00350 
00351                         IRDA_DEBUG(1, __FUNCTION__ "(), crc error\n");
00352                         stats->rx_errors++;
00353                         stats->rx_crc_errors++;
00354                 }                       
00355                 break;
00356         default: /* Must be the next byte of the frame */
00357                 if (rx_buff->len < rx_buff->truesize)  {
00358                         rx_buff->data[rx_buff->len++] = byte;
00359                         rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
00360                 } else {
00361                         IRDA_DEBUG(1, __FUNCTION__ 
00362                               "(), Rx buffer overflow, aborting\n");
00363                         rx_buff->state = OUTSIDE_FRAME;
00364                 }
00365                 break;
00366         }
00367 }
00368 
00369