예제 #1
0
/*
 * Function async_unwrap_other(dev, byte)
 *
 *    Handle other characters received within a frame
 *
 */
static inline void
async_unwrap_other(struct net_device *dev,
		   struct net_device_stats *stats,
		   iobuff_t *rx_buff, __u8 byte)
{
	switch(rx_buff->state) {
		/* This is on the critical path, case are ordered by
		 * probability (most frequent first) - Jean II */
	case INSIDE_FRAME:
		/* Must be the next byte of the frame */
		if (rx_buff->len < rx_buff->truesize)  {
			rx_buff->data[rx_buff->len++] = byte;
#ifndef POSTPONE_RX_CRC
			rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
#endif
		} else {
			IRDA_DEBUG(1, "%s(), Rx buffer overflow, aborting\n",
				   __FUNCTION__);
			rx_buff->state = OUTSIDE_FRAME;
		}
		break;

	case LINK_ESCAPE:
		/*
		 *  Stuffed char, complement bit 5 of byte
		 *  following CE, IrLAP p.114
		 */
		byte ^= IRDA_TRANS;
		if (rx_buff->len < rx_buff->truesize)  {
			rx_buff->data[rx_buff->len++] = byte;
#ifndef POSTPONE_RX_CRC
			rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
#endif
			rx_buff->state = INSIDE_FRAME;
		} else {
			IRDA_DEBUG(1, "%s(), Rx buffer overflow, aborting\n",
				   __FUNCTION__);
			rx_buff->state = OUTSIDE_FRAME;
		}
		break;

	case OUTSIDE_FRAME:
		/* Activate carrier sense */
		if(byte != XBOF)
			irda_device_set_media_busy(dev, TRUE);
		break;

	case BEGIN_FRAME:
	default:
		rx_buff->data[rx_buff->len++] = byte;
#ifndef POSTPONE_RX_CRC
		rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
#endif
		rx_buff->state = INSIDE_FRAME;
		break;
	}
}
예제 #2
0
/*
 * Function async_unwrap_other(dev, byte)
 *
 *    Handle other characters received within a frame
 *
 */
static inline void
async_unwrap_other(struct tty_struct *tty,
		   iobuff_t *rx_buff, __u8 byte)
{
	SHIRDA_DEBUGLOG("state=%d,byte=0x%x\n",rx_buff->state,byte);
	switch(rx_buff->state) {
		/* This is on the critical path, case are ordered by
		 * probability (most frequent first) - Jean II */
	case INSIDE_FRAME:
		/* Must be the next byte of the frame */
		if (rx_buff->len < rx_buff->truesize)  {
			rx_buff->data[rx_buff->len++] = byte;
#ifndef POSTPONE_RX_CRC
			rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
#endif
		} else {
			SHIRDA_DEBUGLOG("Rx buffer overflow, aborting\n");
			rx_buff->state = OUTSIDE_FRAME;
		}
		break;

	case LINK_ESCAPE:
		/*
		 *  Stuffed char, complement bit 5 of byte
		 *  following CE, IrLAP p.114
		 */
		byte ^= IRDA_TRANS;
		if (rx_buff->len < rx_buff->truesize)  {
			rx_buff->data[rx_buff->len++] = byte;
#ifndef POSTPONE_RX_CRC
			rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
#endif
			rx_buff->state = INSIDE_FRAME;
		} else {
			SHIRDA_DEBUGLOG("Rx buffer overflow, aborting\n");
			rx_buff->state = OUTSIDE_FRAME;
		}
		break;

	case OUTSIDE_FRAME:
		/* Activate carrier sense */
		break;

	case BEGIN_FRAME:
	default:
		rx_buff->data[rx_buff->len++] = byte;
#ifndef POSTPONE_RX_CRC
		rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
#endif
		rx_buff->state = INSIDE_FRAME;
		break;
	}
}
예제 #3
0
/*
 * Function async_unwrap_eof(dev, byte)
 *
 *    Handle End Of Frame character received within a frame
 *
 */
static inline void
async_unwrap_eof(struct net_device *dev,
		 struct net_device_stats *stats,
		 iobuff_t *rx_buff, __u8 byte)
{
#ifdef POSTPONE_RX_CRC
	int	i;
#endif

	switch(rx_buff->state) {
	case OUTSIDE_FRAME:
		/* Probably missed the BOF */
		stats->rx_errors++;
		stats->rx_missed_errors++;
		irda_device_set_media_busy(dev, TRUE);
		break;

	case BEGIN_FRAME:
	case LINK_ESCAPE:
	case INSIDE_FRAME:
	default:
		/* Note : in the case of BEGIN_FRAME and LINK_ESCAPE,
		 * the fcs will most likely not match and generate an
		 * error, as expected - Jean II */
		rx_buff->state = OUTSIDE_FRAME;
		rx_buff->in_frame = FALSE;

#ifdef POSTPONE_RX_CRC
		/* If we haven't done the CRC as we receive bytes, we
		 * must do it now... Jean II */
		for(i = 0; i < rx_buff->len; i++)
			rx_buff->fcs = irda_fcs(rx_buff->fcs,
						rx_buff->data[i]);
#endif

		/* Test FCS and signal success if the frame is good */
		if (rx_buff->fcs == GOOD_FCS) {
			/* Deliver frame */
			async_bump(dev, stats, rx_buff);
			break;
		} else {
			/* Wrong CRC, discard frame!  */
			irda_device_set_media_busy(dev, TRUE);

			IRDA_DEBUG(1, "%s(), crc error\n", __FUNCTION__);
			stats->rx_errors++;
			stats->rx_crc_errors++;
		}
		break;
	}
}
예제 #4
0
/*
 * Function async_unwrap_eof(dev, byte)
 *
 *    Handle End Of Frame character received within a frame
 *
 */
static inline void
async_unwrap_eof(struct tty_struct *tty, iobuff_t *rx_buff, __u8 byte)
{
#ifdef POSTPONE_RX_CRC
	int	i;
#endif

	SHIRDA_DEBUGLOG("state=%d,byte=0x%x\n",rx_buff->state,byte);
	switch(rx_buff->state) {
	case OUTSIDE_FRAME:
		/* Probably missed the BOF */
		rx_buff->stats.rx_errors++;
		rx_buff->stats.rx_missed_errors++;
		break;

	case BEGIN_FRAME:
	case LINK_ESCAPE:
	case INSIDE_FRAME:
	default:
		/* Note : in the case of BEGIN_FRAME and LINK_ESCAPE,
		 * the fcs will most likely not match and generate an
		 * error, as expected - Jean II */
		rx_buff->state = OUTSIDE_FRAME;
		rx_buff->in_frame = FALSE;

#ifdef POSTPONE_RX_CRC
		/* If we haven't done the CRC as we receive bytes, we
		 * must do it now... Jean II */
		for(i = 0; i < rx_buff->len; i++)
			rx_buff->fcs = irda_fcs(rx_buff->fcs,
						rx_buff->data[i]);
#endif

		/* Test FCS and signal success if the frame is good */
		if (rx_buff->fcs == GOOD_FCS) {
			/* Deliver frame */
			rx_buff->stats.rx_packets++;
			rx_buff->stats.rx_bytes += (rx_buff->len - 2);
			shirda_async_bump(tty, rx_buff);
			break;
		} else {
			/* Wrong CRC, discard frame!  */
			SHIRDA_DEBUGLOG("crc error\n");
			rx_buff->stats.rx_errors++;
			rx_buff->stats.rx_crc_errors++;
		}
		break;
	}
}
예제 #5
0
__u16 irda_calc_crc16( __u16 fcs, __u8 const *buf, size_t len) 
{
	while (len--)
                fcs = irda_fcs(fcs, *buf++);
	return fcs;
}
예제 #6
0
/*
 * Function async_wrap (tty, *tx_buff, buffsize)
 */
int async_wrap_tty(struct tty_struct *tty, __u8 *tx_buff, int buffsize)
{
	struct shirda_ldisc_admin_t *sp = tty->disc_data;
	int xbofs;
	int i;
	int n;
	union {
		__u16 value;
		__u8 bytes[2];
	} fcs;

	/* Initialize variables */
	fcs.value = INIT_FCS;
	n = 0;

	/*
	 *  Send  XBOF's for required min. turn time and for the negotiated
	 *  additional XBOFS
	 */

	xbofs = sp->qos.add_bof;

	SHIRDA_DEBUGLOG("abofs=%d\n", xbofs);

	/* Check that we never use more than 115 + 48 xbofs */
	if (xbofs > 163) {
		IRDALOG_WARNING("too many xbofs (%d)\n", xbofs);
		xbofs = 163;
	}

	memset(tx_buff + n, XBOF, xbofs);
	n += xbofs;

	/* Start of packet character BOF */
	tx_buff[n++] = BOF;

	SHIRDA_DEBUGLOG("tx_payload length=%d\n", sp->nr_tx_payload);
	/* Insert frame and calc CRC */
	for (i=0; i < sp->nr_tx_payload; i++) {
		/*
		 *  Check for the possibility of tx buffer overflow. We use
		 *  bufsize-5 since the maximum number of bytes that can be
		 *  transmitted after this point is 5.
		 */
		if(n >= (buffsize-5)) {
			IRDALOG_ERROR("tx buffer overflow (n=%d)\n", n);
			return -1;
		}

		n += stuff_byte(sp->tx_payload[i], tx_buff+n);
		fcs.value = irda_fcs(fcs.value, sp->tx_payload[i]);
		SHIRDA_DEBUGLOG("len=%04d:%04d, data=0x%02x, fcs=0x%04x\n",
					i, n, sp->tx_payload[i], fcs.value);
	}

	/* Insert CRC in little endian format (LSB first) */
	fcs.value = ~fcs.value;
#ifdef __LITTLE_ENDIAN
	n += stuff_byte(fcs.bytes[0], tx_buff+n);
	n += stuff_byte(fcs.bytes[1], tx_buff+n);
#else /* ifdef __BIG_ENDIAN */
	n += stuff_byte(fcs.bytes[1], tx_buff+n);
	n += stuff_byte(fcs.bytes[0], tx_buff+n);
#endif
	tx_buff[n++] = EOF;

	SHIRDA_DEBUGLOG("tx_buff length=%d\n", n);
	return n;
}
예제 #7
0
/*
 * Function async_wrap (skb, *tx_buff, buffsize)
 *
 *    Makes a new buffer with wrapping and stuffing, should check that
 *    we don't get tx buffer overflow.
 */
int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize)
{
	struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb;
	int xbofs;
	int i;
	int n;
	union {
		__u16 value;
		__u8 bytes[2];
	} fcs;

	/* Initialize variables */
	fcs.value = INIT_FCS;
	n = 0;

	/*
	 *  Send  XBOF's for required min. turn time and for the negotiated
	 *  additional XBOFS
	 */

	if (cb->magic != LAP_MAGIC) {
		/*
		 * This will happen for all frames sent from user-space.
		 * Nothing to worry about, but we set the default number of
		 * BOF's
		 */
		IRDA_DEBUG(1, "%s(), wrong magic in skb!\n", __FUNCTION__);
		xbofs = 10;
	} else
		xbofs = cb->xbofs + cb->xbofs_delay;

	IRDA_DEBUG(4, "%s(), xbofs=%d\n", __FUNCTION__, xbofs);

	/* Check that we never use more than 115 + 48 xbofs */
	if (xbofs > 163) {
		IRDA_DEBUG(0, "%s(), too many xbofs (%d)\n", __FUNCTION__,
			   xbofs);
		xbofs = 163;
	}

	memset(tx_buff + n, XBOF, xbofs);
	n += xbofs;

	/* Start of packet character BOF */
	tx_buff[n++] = BOF;

	/* Insert frame and calc CRC */
	for (i=0; i < skb->len; i++) {
		/*
		 *  Check for the possibility of tx buffer overflow. We use
		 *  bufsize-5 since the maximum number of bytes that can be
		 *  transmitted after this point is 5.
		 */
		if(n >= (buffsize-5)) {
			IRDA_ERROR("%s(), tx buffer overflow (n=%d)\n",
				   __FUNCTION__, n);
			return n;
		}

		n += stuff_byte(skb->data[i], tx_buff+n);
		fcs.value = irda_fcs(fcs.value, skb->data[i]);
	}

	/* Insert CRC in little endian format (LSB first) */
	fcs.value = ~fcs.value;
#ifdef __LITTLE_ENDIAN
	n += stuff_byte(fcs.bytes[0], tx_buff+n);
	n += stuff_byte(fcs.bytes[1], tx_buff+n);
#else /* ifdef __BIG_ENDIAN */
	n += stuff_byte(fcs.bytes[1], tx_buff+n);
	n += stuff_byte(fcs.bytes[0], tx_buff+n);
#endif
	tx_buff[n++] = EOF;

	return n;
}