⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ahdlc.c

📁 是瑞典科学院开发的世界最小的嵌入式操作系统,并且包括了TCP/IP协议,是最新版本
💻 C
字号:
/*																www.mycal.com			 *--------------------------------------------------------------------------- * ahdlc.c - Ahdlc receive and transmit processor for PPP engine. * *--------------------------------------------------------------------------- * Version   *		0.1 Original Version Jan 11, 1998 * *---------------------------------------------------------------------------  *   * Copyright (C) 1998, Mycal Labs www.mycal.com	 *   *--------------------------------------------------------------------------- *//* * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net * All rights reserved.  * * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in the  *    documentation and/or other materials provided with the distribution.  * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *      This product includes software developed by Mike Johnson/Mycal Labs *		www.mycal.net. * 4. The name of the author may not be used to endorse or promote *    products derived from this software without specific prior *    written permission.   * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   * * This file is part of the Mycal Modified uIP TCP/IP stack. * * $Id: ahdlc.c,v 1.1 2006/06/17 22:48:09 adamdunkels Exp $ * *//*			*/ /* include files 	*//*			*/  #include "net/uip.h"#include "ppp.h"#if 0#define DEBUG1(x)#else#include <stdio.h>#define DEBUG1(x) debug_printf x#endif#define	PACKET_TX_DEBUG	1/*--------------------------------------------------------------------------- * ahdlc flags bit defins, for ahdlc_flags variable ---------------------------------------------------------------------------*//* Escaped mode bit */#define AHDLC_ESCAPED		0x1/* Frame is ready bit */#define	AHDLC_RX_READY		0x2				#define	AHDLC_RX_ASYNC_MAP	0x4#define AHDLC_TX_ASYNC_MAP	0x8#define AHDLC_PFC		0x10#define AHDLC_ACFC		0x20/*--------------------------------------------------------------------------- * Private Local Globals *	10 bytes	- standard *			- with counters ---------------------------------------------------------------------------*//* running tx CRC */u16_t ahdlc_tx_crc;/* running rx CRC */u16_t ahdlc_rx_crc;/* number of rx bytes processed, cur frame */u16_t ahdlc_rx_count;/* ahdlc state flags, see above */u8_t ahdlc_flags;u8_t	ahdlc_tx_offline;/* * The following can be optimized out */u8_t *ahdlc_rx_buffer;			/* What to do here? +++ */u16_t ahdlc_max_rx_buffer_size;/* * Optional statistics counters. */#ifdef AHDLC_COUNTERSu8_t ahdlc_rx_tobig_error;#endif/*---------------------------------------------------------------------------*//* Simple and fast CRC16 routine for embedded processors. *	Just slightly slower than the table lookup method but consumes *	almost no space.  Much faster and smaller than the loop and *	shift method that is widely used in the embedded space.  *	Can be optimized even more in .ASM * *	data = (crcvalue ^ inputchar) & 0xff; *	data = (data ^ (data << 4)) & 0xff; *	crc = (crc >> 8) ^ ((data << 8) ^ (data <<3) ^ (data >> 4)) *//*---------------------------------------------------------------------------*/static u16_tcrcadd(u16_t crcvalue, u8_t c){  u16_t b;  b = (crcvalue ^ c) & 0xFF;  b = (b ^ (b << 4)) & 0xFF;  b = (b << 8) ^ (b << 3) ^ (b >> 4);    return ((crcvalue >> 8) ^ b);}/*---------------------------------------------------------------------------*//* ahdlc_init(buffer, buffersize) - this initializes the ahdlc engine to *	allow for rx frames. *//*---------------------------------------------------------------------------*/voidahdlc_init(u8_t *buffer, u16_t maxrxbuffersize){  ahdlc_flags = 0 | AHDLC_RX_ASYNC_MAP;  ahdlc_rx_buffer = buffer;  ahdlc_max_rx_buffer_size = maxrxbuffersize;  /* ahdlc_async_map = 0; */#ifdef AHDLC_COUNTERS  ahdlc_rx_tobig_error = 0;  ahdl_tx_offline = 0;#endif}/*---------------------------------------------------------------------------*//* ahdlc_rx_ready() - resets the ahdlc engine to the beginning of frame  *	state. *//*---------------------------------------------------------------------------*/voidahdlc_rx_ready(void){  ahdlc_rx_count = 0;  ahdlc_rx_crc = 0xffff;  ahdlc_flags |= AHDLC_RX_READY;}/*---------------------------------------------------------------------------*//* ahdlc receive function - This routine processes incoming bytes and tries *	to build a PPP frame. * *	Two possible reasons that ahdlc_rx will not process characters: *		o Buffer is locked - in this case ahdlc_rx returns 1, char *			sending routing should retry. *//*---------------------------------------------------------------------------*/u8_tahdlc_rx(u8_t c)   {      static u16_t protocol;    /* check to see if PPP packet is useable, we should have hardware     flow control set, but if host ignores it and sends us a char when     the PPP Receive packet is in use, discard the character. +++ */    if(ahdlc_flags & AHDLC_RX_READY) {    /* check to see if character is less than 0x20 hex we really       should set AHDLC_RX_ASYNC_MAP on by default and only turn it       off when it is negotiated off to handle some buggy stacks. */    if((c < 0x20) &&       ((ahdlc_flags & AHDLC_RX_ASYNC_MAP) == 0)) {      /* discard character */      DEBUG1(("Discard because char is < 0x20 hex and asysnc map is 0\n"));      return 0;    }    /* are we in escaped mode? */    if(ahdlc_flags & AHDLC_ESCAPED) {      /* set escaped to FALSE */      ahdlc_flags &= ~AHDLC_ESCAPED;	            /* if value is 0x7e then silently discard and reset receive packet */      if(c == 0x7e) {	ahdlc_rx_ready();	return 0;      }      /* incomming char = itself xor 20 */      c = c ^ 0x20;	    } else if(c == 0x7e) {      /* handle frame end */      if(ahdlc_rx_crc == CRC_GOOD_VALUE) {	DEBUG1(("\nReceiving packet with good crc value, len %d\n",ahdlc_rx_count));	/* we hae a good packet, turn off CTS until we are done with	   this packet */	/*CTS_OFF();*/	/* remove CRC bytes from packet */	ahdlc_rx_count -= 2;				/* lock PPP buffer */	ahdlc_flags &= ~AHDLC_RX_READY;	/*	 * upcall routine must fully process frame before return	 *	as returning signifies that buffer belongs to AHDLC again.	 */	if((c & 0x1) && (ahdlc_flags & PPP_PFC)) {	  /* Send up packet */	  ppp_upcall((u16_t)ahdlc_rx_buffer[0],		     (u8_t *)&ahdlc_rx_buffer[1],		     (u16_t)(ahdlc_rx_count - 1));	} else {	  /* Send up packet */	  ppp_upcall((u16_t)(ahdlc_rx_buffer[0] << 8 | ahdlc_rx_buffer[1]), 		     (u8_t *)&ahdlc_rx_buffer[2], (u16_t)(ahdlc_rx_count - 2));	}	ahdlc_tx_offline = 0;	// The remote side is alive	ahdlc_rx_ready();	return 0;      } else if(ahdlc_rx_count > 3) {		DEBUG1(("\nReceiving packet with bad crc value, was 0x%04x len %d\n",ahdlc_rx_crc, ahdlc_rx_count));#ifdef AHDLC_COUNTERS	++ahdlc_crc_error;#endif	/* Shouldn't we dump the packet and not pass it up? */	/*ppp_upcall((u16_t)ahdlc_rx_buffer[0],	  (u8_t *)&ahdlc_rx_buffer[0], (u16_t)(ahdlc_rx_count+2));	  dump_ppp_packet(&ahdlc_rx_buffer[0],ahdlc_rx_count);*/	      }      ahdlc_rx_ready();	      return 0;    } else if(c == 0x7d) {      /* handle escaped chars*/      ahdlc_flags |= PPP_ESCAPED;      return 0;    }        /* try to store char if not to big */    if(ahdlc_rx_count >= ahdlc_max_rx_buffer_size /*PPP_RX_BUFFER_SIZE*/) { #ifdef AHDLC_COUNTERS			      ++ahdlc_rx_tobig_error;#endif      ahdlc_rx_ready();    } else {      /* Add CRC in */      ahdlc_rx_crc = crcadd(ahdlc_rx_crc, c);      /* do auto ACFC, if packet len is zero discard 0xff and 0x03 */      if(ahdlc_rx_count == 0) {	if((c == 0xff) || (c == 0x03))	  return 0;      }      /* Store char */      ppp_rx_buffer[ahdlc_rx_count++] = c;    }		  } else {    /* we are busy and didn't process the character. */    DEBUG1(("Busy/not active\n"));    return 1;  }  return 0;}/*---------------------------------------------------------------------------*//* ahdlc_tx_char(char) - write a character to the serial device,  * escape if necessary. * * Relies on local global vars	:	ahdlc_tx_crc, ahdlc_flags. * Modifies local global vars	:	ahdlc_tx_crc. *//*---------------------------------------------------------------------------*/voidahdlc_tx_char(u16_t protocol, u8_t c){  /* add in crc */  ahdlc_tx_crc = crcadd(ahdlc_tx_crc, c);  /*   * See if we need to escape char, we always escape 0x7d and 0x7e, in the case   * of char < 0x20 we only support async map of default or none, so escape if   * ASYNC map is not set.  We may want to modify this to support a bitmap set   * ASYNC map.   */  if((c == 0x7d) || (c == 0x7e) ||      ((c < 0x20) && ((protocol == LCP) ||		     (ahdlc_flags & PPP_TX_ASYNC_MAP) == 0))) {    /* send escape char and xor byte by 0x20 */    ppp_arch_putchar(0x7d);    c ^= 0x20;  }  ppp_arch_putchar(c);}/*---------------------------------------------------------------------------*//* ahdlc_tx(protocol,buffer,len) - Transmit a PPP frame. *	Buffer contains protocol data, ahdlc_tx addes address, control and *	protocol data. * * Relies on local global vars	:	ahdlc_tx_crc, ahdlc_flags. * Modifies local global vars	:	ahdlc_tx_crc. *//*---------------------------------------------------------------------------*/u8_tahdlc_tx(u16_t protocol, u8_t *header, u8_t *buffer,	 u16_t headerlen, u16_t datalen){  u16_t i;  u8_t c;  DEBUG1(("\nAHDLC_TX - transmit frame, protocol 0x%04x, length %d  offline %d\n",protocol,datalen+headerlen,ahdlc_tx_offline));  if (AHDLC_TX_OFFLINE && (ahdlc_tx_offline++ > AHDLC_TX_OFFLINE)) {    ahdlc_tx_offline = 0;    DEBUG1(("\nAHDLC_TX to many outstanding TX packets => ppp_reconnect()\n"));    ppp_reconnect();    return 0;  }  #if PACKET_TX_DEBUG  DEBUG1(("\n"));  for(i = 0; i < headerlen; ++i) {    DEBUG1(("0x%02x ", header[i]));  }  for(i = 0; i < datalen; ++i) {    DEBUG1(("0x%02x ", buffer[i]));  }  DEBUG1(("\n\n"));#endif  /* Check to see that physical layer is up, we can assume is some     cases */    /* write leading 0x7e */  ppp_arch_putchar(0x7e);  /* set initial CRC value */  ahdlc_tx_crc = 0xffff;  /* send HDLC control and address if not disabled or of LCP frame type */  /*if((0==(ahdlc_flags & PPP_ACFC)) || ((0xc0==buffer[0]) && (0x21==buffer[1]))) */  if((0 == (ahdlc_flags & PPP_ACFC)) || (protocol == LCP)) {    ahdlc_tx_char(protocol, 0xff);    ahdlc_tx_char(protocol, 0x03);  }    /* Write Protocol */  ahdlc_tx_char(protocol,(u8_t)(protocol >> 8));  ahdlc_tx_char(protocol,(u8_t)(protocol & 0xff));  /* write header if it exists */  for(i = 0; i < headerlen; ++i) {    /* Get next byte from buffer */    c = header[i];    /* Write it...*/    ahdlc_tx_char(protocol, c);  }  /* Write frame bytes */  for(i = 0; i < datalen; ++i) {        /* Get next byte from buffer */    c = buffer[i];    /* Write it...*/    ahdlc_tx_char(protocol, c);  }	  /* send crc, lsb then msb */  i = ahdlc_tx_crc ^ 0xffff;  ahdlc_tx_char(protocol, (u8_t)(i & 0xff));  ahdlc_tx_char(protocol, (u8_t)((i >> 8) & 0xff));  /* write trailing 0x7e, probably not needed but it doesn't hurt*/  ppp_arch_putchar(0x7e);  return 0;}/*---------------------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -