patch-2.2.10 linux/net/irda/wrapper.c

Next file: linux/net/netlink/af_netlink.c
Previous file: linux/net/irda/qos.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.9/linux/net/irda/wrapper.c linux/net/irda/wrapper.c
@@ -1,15 +1,15 @@
 /*********************************************************************
  *                
  * Filename:      wrapper.c
- * Version:       1.1
- * Description:   SIR wrapper layer
+ * Version:       1.2
+ * Description:   IrDA SIR async wrapper layer
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Aug  4 20:40:53 1997
- * Modified at:   Wed Apr 21 12:45:55 1999
+ * Modified at:   Fri May 28 20:30:24 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, 
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
  *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
@@ -34,7 +34,20 @@
 #include <net/irda/irlap_frame.h>
 #include <net/irda/irda_device.h>
 
-inline static int stuff_byte(__u8 byte, __u8 *buf);
+static inline int stuff_byte(__u8 byte, __u8 *buf);
+
+static void state_outside_frame(struct irda_device *idev, __u8 byte);
+static void state_begin_frame(struct irda_device *idev, __u8 byte);
+static void state_link_escape(struct irda_device *idev, __u8 byte);
+static void state_inside_frame(struct irda_device *idev, __u8 byte);
+
+static void (*state[])(struct irda_device *idev, __u8 byte) = 
+{ 
+	state_outside_frame,
+	state_begin_frame,
+	state_link_escape,
+	state_inside_frame,
+};
 
 /*
  * Function async_wrap (skb, *tx_buff)
@@ -52,8 +65,6 @@
 		__u8 bytes[2];
 	} fcs;
 
-	ASSERT(skb != NULL, return 0;);
-
 	/* Initialize variables */
 	fcs.value = INIT_FCS;
 	n = 0;
@@ -74,13 +85,9 @@
 	} else
 		xbofs = ((struct irlap_skb_cb *)(skb->cb))->xbofs;
 
-#if 0
- 	for (i=0; i<xbofs; i++)
-  		tx_buff[n++] = XBOF;
-#else
 	memset(tx_buff+n, XBOF, xbofs);
 	n += xbofs;
-#endif
+
 	/* Start of packet character BOF */
 	tx_buff[n++] = BOF;
 
@@ -94,7 +101,7 @@
 		ASSERT(n < (buffsize-5), return n;);
 
 		n += stuff_byte(skb->data[i], tx_buff+n);
-		fcs.value = IR_FCS(fcs.value, skb->data[i]);
+		fcs.value = irda_fcs(fcs.value, skb->data[i]);
 	}
 	
 	/* Insert CRC in little endian format (LSB first) */
@@ -108,15 +115,6 @@
 #endif
 	tx_buff[n++] = EOF;
 
-#if 0
-	{
-		int i;
-		
-		for (i=0;i<n;i++)
-			printk("%02x", tx_buff[i]);
-		printk("\n");
-	}
-#endif
 	return n;
 }
 
@@ -155,147 +153,13 @@
 }
 
 /*
- * Function async_unwrap (skb)
- *
- *    Parse and de-stuff frame received from the IR-port
- *
- */
-void async_unwrap_char(struct irda_device *idev, __u8 byte) 
-{
-	/* State machine for receiving frames */	   
-	switch (idev->rx_buff.state) {
-	case OUTSIDE_FRAME:
-		switch(byte) {
-		case BOF:
-			idev->rx_buff.state = BEGIN_FRAME;
-			idev->rx_buff.in_frame = TRUE;
-			break;
-		case XBOF:
-			/* idev->xbofs++; */
-			break;
-		case EOF:
-			irda_device_set_media_busy( idev, TRUE);
-			break;
-		default:
-			break;
-		}
-		break;
-	case BEGIN_FRAME:
-		switch (byte) {
-		case BOF:
-			/* Continue */
-			break;
-		case CE:
-			/* Stuffed byte */
-			idev->rx_buff.state = LINK_ESCAPE;
-			break;
-		case EOF:
-			/* Abort frame */
-			idev->rx_buff.state = OUTSIDE_FRAME;
-
-			idev->stats.rx_errors++;
-			idev->stats.rx_frame_errors++;
-			break;
-		default:
-			/* Got first byte of frame */
-			idev->rx_buff.data = idev->rx_buff.head;
-			idev->rx_buff.len = 0;
-
-			idev->rx_buff.data[idev->rx_buff.len++] = byte;
-			
-			idev->rx_buff.fcs = IR_FCS(INIT_FCS, byte);
-			idev->rx_buff.state = INSIDE_FRAME;
-			break;
-		}
-		break;
-	case LINK_ESCAPE:
-		switch (byte) {
-		case BOF:
-			/* New frame? */
-			idev->rx_buff.state = BEGIN_FRAME;
-			irda_device_set_media_busy(idev, TRUE);
-			break;
-		case CE:
-			DEBUG(4, "WARNING: State not defined\n");
-			break;
-		case EOF:
-			/* Abort frame */
-			idev->rx_buff.state = OUTSIDE_FRAME;
-			break;
-		default:
-			/* 
-			 *  Stuffed char, complement bit 5 of byte 
-			 *  following CE, IrLAP p.114 
-			 */
-			byte ^= IR_TRANS;
-			if (idev->rx_buff.len < idev->rx_buff.truesize)  {
-				idev->rx_buff.data[idev->rx_buff.len++] = byte;
-				idev->rx_buff.fcs = IR_FCS(idev->rx_buff.fcs,
-							   byte);
-				idev->rx_buff.state = INSIDE_FRAME;
-			} else {
-				DEBUG(1, __FUNCTION__ 
-				       "(), Rx buffer overflow, aborting\n");
-				idev->rx_buff.state = OUTSIDE_FRAME;
-			}
-			break;
-		}
-		break;
-	case INSIDE_FRAME:
-		switch (byte) {
-		case BOF:
-			/* New frame? */
-			idev->rx_buff.state = BEGIN_FRAME;
-			irda_device_set_media_busy(idev, TRUE);
-			break;
-		case CE:
-			/* Stuffed char */
-			idev->rx_buff.state = LINK_ESCAPE;
-			break;
-		case EOF:
-			/* End of frame */
-			idev->rx_buff.state = OUTSIDE_FRAME;
-			idev->rx_buff.in_frame = FALSE;
-			
-			/* 
-			 *  Test FCS and deliver frame if it's good
-			 */			
-			if (idev->rx_buff.fcs == GOOD_FCS) {
-				async_bump(idev, idev->rx_buff.data, 
-					   idev->rx_buff.len);
-			} else {
-				/* Wrong CRC, discard frame!  */
-				irda_device_set_media_busy(idev, TRUE); 
-
-				idev->stats.rx_errors++;
-				idev->stats.rx_crc_errors++;
-			}			
-			break;
-		default:
-			/* Next byte of frame */
-			if (idev->rx_buff.len < idev->rx_buff.truesize)  {
-				idev->rx_buff.data[idev->rx_buff.len++] = byte;
-				idev->rx_buff.fcs = IR_FCS(idev->rx_buff.fcs,
-							   byte);
-			} else {
-				DEBUG(1, __FUNCTION__ 
-				      "(), Rx buffer overflow, aborting\n");
-				idev->rx_buff.state = OUTSIDE_FRAME;
-			}
-			break;
-		}
-		break;
-	}
-}
- 
-/*
  * Function stuff_byte (byte, buf)
  *
  *    Byte stuff one single byte and put the result in buffer pointed to by
  *    buf. The buffer must at all times be able to have two bytes inserted.
  * 
  */
-inline static int stuff_byte(__u8 byte, __u8 *buf) 
+static inline int stuff_byte(__u8 byte, __u8 *buf) 
 {
 	switch (byte) {
 	case BOF: /* FALLTHROUGH */
@@ -303,7 +167,7 @@
 	case CE:
 		/* Insert transparently coded */
 		buf[0] = CE;               /* Send link escape */
-		buf[1] = byte^IR_TRANS;    /* Complement bit 5 */
+		buf[1] = byte^IRDA_TRANS;    /* Complement bit 5 */
 		return 2;
 		/* break; */
 	default:
@@ -313,7 +177,163 @@
 		/* break; */
 	}
 }
+
+/*
+ * Function async_unwrap (skb)
+ *
+ *    Parse and de-stuff frame received from the IrDA-port
+ *
+ */
+inline void async_unwrap_char(struct irda_device *idev, __u8 byte)
+{
+	(*state[idev->rx_buff.state]) (idev, byte);
+}
 	 
+/*
+ * Function state_outside_frame (idev, byte)
+ *
+ *    
+ *
+ */
+static void state_outside_frame(struct irda_device *idev, __u8 byte)
+{
+	switch (byte) {
+	case BOF:
+		idev->rx_buff.state = BEGIN_FRAME;
+		idev->rx_buff.in_frame = TRUE;
+		break;
+	case XBOF:
+		/* idev->xbofs++; */
+		break;
+	case EOF:
+		irda_device_set_media_busy( idev, TRUE);
+		break;
+	default:
+		break;
+	}
+}
+
+/*
+ * Function state_begin_frame (idev, byte)
+ *
+ *    Begin of frame detected
+ *
+ */
+static void state_begin_frame(struct irda_device *idev, __u8 byte)
+{
+	switch (byte) {
+	case BOF:
+		/* Continue */
+		break;
+	case CE:
+		/* Stuffed byte */
+		idev->rx_buff.state = LINK_ESCAPE;
+
+		/* Time to initialize receive buffer */
+		idev->rx_buff.data = idev->rx_buff.head;
+		idev->rx_buff.len = 0;
+		break;
+	case EOF:
+		/* Abort frame */
+		idev->rx_buff.state = OUTSIDE_FRAME;
+		
+		idev->stats.rx_errors++;
+		idev->stats.rx_frame_errors++;
+		break;
+	default:	
+		/* Time to initialize receive buffer */
+		idev->rx_buff.data = idev->rx_buff.head;
+		idev->rx_buff.len = 0;
+
+		idev->rx_buff.data[idev->rx_buff.len++] = byte;
+		
+		idev->rx_buff.fcs = irda_fcs(INIT_FCS, byte);
+		idev->rx_buff.state = INSIDE_FRAME;
+		break;
+	}
+}
 
+/*
+ * Function state_link_escape (idev, byte)
+ *
+ *    
+ *
+ */
+static void state_link_escape(struct irda_device *idev, __u8 byte)
+{
+	switch (byte) {
+	case BOF: /* New frame? */
+		idev->rx_buff.state = BEGIN_FRAME;
+		irda_device_set_media_busy(idev, TRUE);
+		break;
+	case CE:
+		DEBUG(4, "WARNING: State not defined\n");
+		break;
+	case EOF: /* Abort frame */
+		idev->rx_buff.state = OUTSIDE_FRAME;
+		break;
+	default:
+		/* 
+		 *  Stuffed char, complement bit 5 of byte 
+		 *  following CE, IrLAP p.114 
+		 */
+		byte ^= IRDA_TRANS;
+		if (idev->rx_buff.len < idev->rx_buff.truesize)  {
+			idev->rx_buff.data[idev->rx_buff.len++] = byte;
+			idev->rx_buff.fcs = irda_fcs(idev->rx_buff.fcs, byte);
+			idev->rx_buff.state = INSIDE_FRAME;
+		} else {
+			DEBUG(1, __FUNCTION__ 
+			      "(), Rx buffer overflow, aborting\n");
+			idev->rx_buff.state = OUTSIDE_FRAME;
+		}
+		break;
+	}
+}
+
+/*
+ * Function state_inside_frame (idev, byte)
+ *
+ *    Handle bytes received within a frame
+ *
+ */
+static void state_inside_frame(struct irda_device *idev, __u8 byte)
+{
+	switch (byte) {
+	case BOF: /* New frame? */
+		idev->rx_buff.state = BEGIN_FRAME;
+		irda_device_set_media_busy(idev, TRUE);
+		break;
+	case CE: /* Stuffed char */
+		idev->rx_buff.state = LINK_ESCAPE;
+		break;
+	case EOF: /* End of frame */
+		idev->rx_buff.state = OUTSIDE_FRAME;
+		idev->rx_buff.in_frame = FALSE;
+		
+		/* Test FCS and deliver frame if it's good */
+		if (idev->rx_buff.fcs == GOOD_FCS) {
+			async_bump(idev, idev->rx_buff.data, 
+				   idev->rx_buff.len);
+		} else {
+			/* Wrong CRC, discard frame!  */
+			irda_device_set_media_busy(idev, TRUE); 
+			
+			idev->stats.rx_errors++;
+			idev->stats.rx_crc_errors++;
+		}			
+		break;
+	default: /* Must be the next byte of the frame */
+		if (idev->rx_buff.len < idev->rx_buff.truesize)  {
+			idev->rx_buff.data[idev->rx_buff.len++] = byte;
+			idev->rx_buff.fcs = irda_fcs(idev->rx_buff.fcs, byte);
+		} else {
+			DEBUG(1, __FUNCTION__ 
+			      "(), Rx buffer overflow, aborting\n");
+			idev->rx_buff.state = OUTSIDE_FRAME;
+		}
+		break;
+	}
+}
 
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)