ahdlc.c
上传用户:hepax88
上传日期:2007-01-03
资源大小:1101k
文件大小:3k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

  1. /* Asynchronous HDLC routines */
  2. #include "global.h"
  3. #include "ahdlc.h"
  4. #include "crc.h"
  5. #include "trace.h" /******/
  6. static uint8 *putbyte(uint8 *,uint8);
  7. void
  8. init_hdlc(hp,maxsize)
  9. struct ahdlc *hp;
  10. int maxsize;
  11. {
  12. hp->escaped = 0;
  13. hp->hunt = 0;
  14. hp->inframe = NULL;
  15. hp->maxsize = maxsize;
  16. hp->fcs = FCS_START;
  17. hp->rxframes = 0;
  18. hp->aborts = 0;
  19. hp->toobigs = 0;
  20. hp->crcerrs = 0;
  21. }
  22. /* Process incoming data. Return completed packets, NULL otherwise */
  23. struct mbuf *
  24. ahdlcrx(ap,c)
  25. struct ahdlc *ap; /* HDLC Receiver control block */
  26. uint8 c;
  27. {
  28. struct mbuf *bp;
  29. if(c == HDLC_ESC_ASYNC){
  30. ap->escaped = 1;
  31. return NULL;
  32. }
  33. if(c != HDLC_FLAG){
  34. if(ap->hunt)
  35. return NULL; /* Ignore until next packet */
  36. /* Normal character within packet */
  37. if(ap->escaped){
  38. c ^= HDLC_ESC_COMPL;
  39. ap->escaped = 0;
  40. }
  41. if(ap->inframe == NULL)
  42. ap->inframe = ambufw(ap->maxsize);
  43. if(ap->inframe->cnt == ap->maxsize){
  44. /* Frame too large */
  45. ap->toobigs++;
  46. #ifdef debug
  47. printf("FRAME TOO LARGE (>%u bytes)n",ap->maxsize);
  48. #endif
  49. free_p(&ap->inframe);
  50. ap->inframe = NULL;
  51. ap->escaped = 0;
  52. ap->fcs = FCS_START;
  53. ap->hunt = 1;
  54. return NULL;
  55. }
  56. /* Store character, update FCS */
  57. ap->inframe->data[ap->inframe->cnt++] = c;
  58. ap->fcs = FCS(ap->fcs,c);
  59. return NULL;
  60. }
  61. /* We get here only if the character is a flag */
  62. if(ap->escaped){
  63. /* ESC, FLAG is frame abort */
  64. ap->aborts++;
  65. #ifdef debug
  66. printf("AHDLC ABORT, cnt = %un",ap->inframe->cnt);
  67. #endif
  68. ap->hunt = 1;
  69. ap->escaped = 0;
  70. free_p(&ap->inframe);
  71. ap->inframe = NULL;
  72. ap->fcs = FCS_START;
  73. return NULL;
  74. }
  75. if(ap->hunt){
  76. /* Found flag in hunt mode. Reset for new frame */
  77. ap->hunt = 0;
  78. return NULL;
  79. }
  80. if(ap->inframe == NULL){
  81. /* Padding flags, ignore */
  82. return NULL;
  83. }
  84. if(ap->fcs != FCS_FINAL){
  85. /* CRC error */
  86. ap->crcerrs++;
  87. #ifdef debug
  88. printf("AHDLC CRC ERROR, cnt = %un",ap->inframe->cnt);
  89. hex_dump(stdout,&ap->inframe);
  90. #endif
  91. free_p(&ap->inframe);
  92. ap->inframe = NULL;
  93. ap->fcs = FCS_START;
  94. return NULL;
  95. }
  96. if(ap->inframe->cnt < 2){
  97. /* Runt frame */
  98. ap->runts++;
  99. #ifdef debug
  100. printf("AHDLC RUNT, cnt = %un",ap->inframe->cnt);
  101. #endif
  102. free_p(&ap->inframe);
  103. ap->inframe = NULL;
  104. ap->fcs = FCS_START;
  105. return NULL;
  106. }
  107. /* Normal end-of-frame */
  108. ap->rxframes++;
  109. bp = ap->inframe;
  110. ap->inframe = NULL;
  111. ap->fcs = FCS_START;
  112. bp->cnt -= 2;
  113. #ifdef debug
  114. printf("Normal AHDLC receive, len %un",bp->cnt);
  115. #endif
  116. return bp;
  117. }
  118. /* Encode a packet in asynchronous HDLC for transmission */
  119. struct mbuf *
  120. ahdlctx(bp)
  121. struct mbuf *bp;
  122. {
  123. struct mbuf *obp;
  124. uint8 *cp;
  125. int c;
  126. uint16 fcs;
  127. fcs = FCS_START;
  128. obp = ambufw(5+2*len_p(bp)); /* Allocate worst-case */
  129. cp = obp->data;
  130. while((c = PULLCHAR(&bp)) != -1){
  131. fcs = FCS(fcs,c);
  132. cp = putbyte(cp,c);
  133. }
  134. free_p(&bp); /* Shouldn't be necessary */
  135. fcs ^= 0xffff;
  136. cp = putbyte(cp,fcs);
  137. cp = putbyte(cp,fcs >> 8);
  138. *cp++ = HDLC_FLAG;
  139. obp->cnt = cp - obp->data;
  140. return obp;
  141. }
  142. static uint8 *
  143. putbyte(cp,c)
  144. uint8 *cp;
  145. uint8 c;
  146. {
  147. switch(c){
  148. case HDLC_FLAG:
  149. case HDLC_ESC_ASYNC:
  150. *cp++ = HDLC_ESC_ASYNC;
  151. *cp++ = c ^ HDLC_ESC_COMPL;
  152. break;
  153. default:
  154. *cp++ = c;
  155. }
  156. return cp;
  157. }