Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
5.2 KiB

  1. /*
  2. ************************************************************************
  3. *
  4. * CONVERT.c
  5. *
  6. *
  7. * Portions Copyright (C) 1996-2001 National Semiconductor Corp.
  8. * All rights reserved.
  9. * Copyright (C) 1996-2001 Microsoft Corporation. All Rights Reserved.
  10. *
  11. *
  12. *
  13. *************************************************************************
  14. */
  15. #include "nsc.h"
  16. #include "convert.tmh"
  17. extern const USHORT fcsTable[];
  18. ULONG __inline EscapeSlowIrData(PUCHAR Dest, UCHAR SourceByte)
  19. {
  20. switch (SourceByte){
  21. case SLOW_IR_BOF:
  22. case SLOW_IR_EOF:
  23. case SLOW_IR_ESC:
  24. Dest[0] = SLOW_IR_ESC;
  25. Dest[1] = SourceByte ^ SLOW_IR_ESC_COMP;
  26. return 2;
  27. default:
  28. Dest[0] = SourceByte;
  29. return 1;
  30. }
  31. }
  32. /*
  33. *************************************************************************
  34. * NdisToIrPacket
  35. *************************************************************************
  36. *
  37. *
  38. * Convert an NDIS Packet into an IR packet.
  39. * Write the IR packet into the provided buffer and report its actual size.
  40. *
  41. * If failing, *irPacketLen will contain the buffer size that
  42. * the caller should retry with (or 0 if a corruption was detected).
  43. *
  44. */
  45. BOOLEAN NdisToIrPacket(
  46. PNDIS_PACKET Packet,
  47. UCHAR *irPacketBuf,
  48. UINT irPacketBufLen,
  49. UINT *irPacketLen
  50. )
  51. {
  52. PNDIS_BUFFER ndisBuf;
  53. UINT i, ndisPacketBytes = 0, I_fieldBytes, totalBytes = 0;
  54. UINT ndisPacketLen, numExtraBOFs;
  55. SLOW_IR_FCS_TYPE fcs;
  56. PNDIS_IRDA_PACKET_INFO packetInfo = GetPacketInfo(Packet);
  57. UCHAR nextChar;
  58. UCHAR *bufData;
  59. UINT bufLen;
  60. *irPacketLen=0;
  61. DBGOUT(("NdisToIrPacket() ..."));
  62. /*
  63. * Get the packet's entire length and its first NDIS buffer
  64. */
  65. NdisQueryPacket(Packet, NULL, NULL, &ndisBuf, &ndisPacketLen);
  66. /*
  67. * Make sure that the packet is big enough to be legal.
  68. * It consists of an A, C, and variable-length I field.
  69. */
  70. if (ndisPacketLen < IR_ADDR_SIZE + IR_CONTROL_SIZE){
  71. DBGERR(("packet too short in NdisToIrPacket (%d bytes)", ndisPacketLen));
  72. return FALSE;
  73. }
  74. else {
  75. I_fieldBytes = ndisPacketLen - IR_ADDR_SIZE - IR_CONTROL_SIZE;
  76. }
  77. /*
  78. * Make sure that we won't overwrite our contiguous buffer.
  79. * Make sure that the passed-in buffer can accomodate this packet's
  80. * data no matter how much it grows through adding ESC-sequences, etc.
  81. */
  82. if ((ndisPacketLen > MAX_IRDA_DATA_SIZE) ||
  83. (MAX_POSSIBLE_IR_PACKET_SIZE_FOR_DATA(I_fieldBytes) > irPacketBufLen)){
  84. /*
  85. * The packet is too large
  86. * Tell the caller to retry with a packet size large
  87. * enough to get past this stage next time.
  88. */
  89. DBGERR(("Packet too large in NdisToIrPacket (%d=%xh bytes), MAX_IRDA_DATA_SIZE=%d, irPacketBufLen=%d.",
  90. ndisPacketLen, ndisPacketLen, MAX_IRDA_DATA_SIZE, irPacketBufLen));
  91. *irPacketLen = ndisPacketLen;
  92. return FALSE;
  93. }
  94. if (!ndisBuf)
  95. {
  96. DBGERR(("No NDIS_BUFFER in NdisToIrPacket"));
  97. return FALSE;
  98. }
  99. NdisQueryBufferSafe(ndisBuf, (PVOID *)&bufData, &bufLen,NormalPagePriority);
  100. if (bufData == NULL) {
  101. DBGERR(("NdisQueryBufferSafeFailed"));
  102. return FALSE;
  103. }
  104. fcs = 0xffff;
  105. // Calculate FCS and write the new buffer in ONE PASS.
  106. /*
  107. * Now begin building the IR frame.
  108. *
  109. * This is the final format:
  110. *
  111. * BOF (1)
  112. * extra BOFs ...
  113. * NdisMediumIrda packet (what we get from NDIS):
  114. * Address (1)
  115. * Control (1)
  116. * FCS (2)
  117. * EOF (1)
  118. */
  119. // Prepend BOFs (extra BOFs + 1 actual BOF)
  120. numExtraBOFs = packetInfo->ExtraBOFs;
  121. if (numExtraBOFs > MAX_NUM_EXTRA_BOFS){
  122. numExtraBOFs = MAX_NUM_EXTRA_BOFS;
  123. }
  124. for (i = totalBytes = 0; i < numExtraBOFs; i++){
  125. *(SLOW_IR_BOF_TYPE *)(irPacketBuf+totalBytes) = SLOW_IR_EXTRA_BOF;
  126. totalBytes += SLOW_IR_EXTRA_BOF_SIZE;
  127. }
  128. *(SLOW_IR_BOF_TYPE *)(irPacketBuf+totalBytes) = SLOW_IR_BOF;
  129. totalBytes += SLOW_IR_BOF_SIZE;
  130. for (i=0; i<ndisPacketLen; i++)
  131. {
  132. ASSERT(bufData);
  133. nextChar = *bufData++;
  134. fcs = (fcs >> 8) ^ fcsTable[(fcs ^ nextChar) & 0xff];
  135. totalBytes += EscapeSlowIrData(&irPacketBuf[totalBytes], nextChar);
  136. if (--bufLen==0)
  137. {
  138. NdisGetNextBuffer(ndisBuf, &ndisBuf);
  139. if (ndisBuf)
  140. {
  141. NdisQueryBufferSafe(ndisBuf, (PVOID *)&bufData, &bufLen,NormalPagePriority);
  142. if (bufData == NULL) {
  143. return FALSE;
  144. }
  145. }
  146. else
  147. {
  148. bufData = NULL;
  149. }
  150. }
  151. }
  152. if (bufData!=NULL)
  153. {
  154. /*
  155. * Packet was corrupt -- it misreported its size.
  156. */
  157. DBGERR(("Packet corrupt in NdisToIrPacket (buffer lengths don't add up to packet length)."));
  158. *irPacketLen = 0;
  159. return FALSE;
  160. }
  161. fcs = ~fcs;
  162. // Now we escape the fcs onto the end.
  163. totalBytes += EscapeSlowIrData(&irPacketBuf[totalBytes], (UCHAR)(fcs&0xff));
  164. totalBytes += EscapeSlowIrData(&irPacketBuf[totalBytes], (UCHAR)(fcs>>8));
  165. // EOF
  166. *(SLOW_IR_EOF_TYPE *)&irPacketBuf[totalBytes] = SLOW_IR_EOF;
  167. totalBytes += SLOW_IR_EOF_SIZE;
  168. *irPacketLen = totalBytes;
  169. DBGOUT(("... NdisToIrPacket converted %d-byte ndis pkt to %d-byte irda pkt:", ndisPacketLen, *irPacketLen));
  170. return TRUE;
  171. }