Windows NT 4.0 source code leak
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.

228 lines
5.6 KiB

4 years ago
  1. /*
  2. ************************************************************************
  3. *
  4. * CONVERT.c
  5. *
  6. * IRMINI Infrared Serial NDIS Miniport driver.
  7. *
  8. * (C) Copyright 1996 Microsoft Corp.
  9. *
  10. *
  11. * (ep)
  12. *
  13. *************************************************************************
  14. */
  15. #include "irmini.h"
  16. /*
  17. *************************************************************************
  18. * NdisToIrPacket
  19. *************************************************************************
  20. *
  21. *
  22. * Convert an NDIS Packet into an IR packet.
  23. * Write the IR packet into the provided buffer and report its actual size.
  24. *
  25. * If failing, *irPacketLen will contain the buffer size that
  26. * the caller should retry with (or 0 if a corruption was detected).
  27. *
  28. */
  29. BOOLEAN NdisToIrPacket( IrDevice *thisDev,
  30. PNDIS_PACKET Packet,
  31. UCHAR *irPacketBuf,
  32. UINT irPacketBufLen,
  33. UINT *irPacketLen
  34. )
  35. {
  36. static UCHAR contigPacketBuf[MAX_IRDA_DATA_SIZE];
  37. PNDIS_BUFFER ndisBuf;
  38. UINT i, ndisPacketBytes = 0, I_fieldBytes, totalBytes = 0;
  39. UINT ndisPacketLen, numExtraBOFs;
  40. SLOW_IR_FCS_TYPE fcs, tmpfcs;
  41. UCHAR fcsBuf[SLOW_IR_FCS_SIZE*2];
  42. UINT fcsLen=0;
  43. PNDIS_IRDA_PACKET_INFO packetInfo = GetPacketInfo(Packet);
  44. UCHAR nextChar;
  45. DBGOUT(("NdisToIrPacket() ..."));
  46. /*
  47. * Get the packet's entire length and its first NDIS buffer
  48. */
  49. NdisQueryPacket(Packet, NULL, NULL, &ndisBuf, &ndisPacketLen);
  50. /*
  51. * Make sure that the packet is big enough to be legal.
  52. * It consists of an A, C, and variable-length I field.
  53. */
  54. if (ndisPacketLen < SLOW_IR_ADDR_SIZE + SLOW_IR_CONTROL_SIZE){
  55. DBGERR(("packet too short in NdisToIrPacket (%d bytes)", ndisPacketLen));
  56. return FALSE;
  57. }
  58. else {
  59. I_fieldBytes = ndisPacketLen - SLOW_IR_ADDR_SIZE - SLOW_IR_CONTROL_SIZE;
  60. }
  61. /*
  62. * Make sure that we won't overwrite our contiguous buffer.
  63. * Make sure that the passed-in buffer can accomodate this packet's
  64. * data no matter how much it grows through adding ESC-sequences, etc.
  65. */
  66. if ((ndisPacketLen > MAX_IRDA_DATA_SIZE) ||
  67. (MAX_POSSIBLE_IR_PACKET_SIZE_FOR_DATA(I_fieldBytes) > irPacketBufLen)){
  68. /*
  69. * The packet is too large
  70. * Tell the caller to retry with a packet size large
  71. * enough to get past this stage next time.
  72. */
  73. DBGERR(("Packet too large in NdisToIrPacket (%d=%xh bytes), MAX_IRDA_DATA_SIZE=%d, irPacketBufLen=%d.",
  74. ndisPacketLen, ndisPacketLen, MAX_IRDA_DATA_SIZE, irPacketBufLen));
  75. *irPacketLen = ndisPacketLen;
  76. return FALSE;
  77. }
  78. /*
  79. * First, read the NDIS packet into a contiguous buffer.
  80. * We have to do this in two steps so that we can compute the
  81. * FCS BEFORE applying escape-byte transparency.
  82. */
  83. while (ndisBuf){
  84. UCHAR *bufData;
  85. UINT bufLen;
  86. NdisQueryBuffer(ndisBuf, (PVOID *)&bufData, &bufLen);
  87. if (ndisPacketBytes + bufLen > ndisPacketLen){
  88. /*
  89. * Packet was corrupt -- it misreported its size.
  90. */
  91. *irPacketLen = 0;
  92. return FALSE;
  93. }
  94. NdisMoveMemory((PVOID)(contigPacketBuf+ndisPacketBytes), (PVOID)bufData, bufLen);
  95. ndisPacketBytes += bufLen;
  96. NdisGetNextBuffer(ndisBuf, &ndisBuf);
  97. }
  98. /*
  99. * Do a sanity check on the length of the packet.
  100. */
  101. if (ndisPacketBytes != ndisPacketLen){
  102. /*
  103. * Packet was corrupt -- it misreported its size.
  104. */
  105. DBGERR(("Packet corrupt in NdisToIrPacket (buffer lengths don't add up to packet length)."));
  106. *irPacketLen = 0;
  107. return FALSE;
  108. }
  109. #ifdef DBG_ADD_PKT_ID
  110. if (addPktIdOn){
  111. static USHORT uniqueId = 0;
  112. *(USHORT *)(contigPacketBuf+ndisPacketBytes) = uniqueId++;
  113. ndisPacketBytes += sizeof(USHORT);
  114. }
  115. #endif
  116. /*
  117. * Compute the FCS on the packet BEFORE applying transparency fixups.
  118. * The FCS also must be sent using ESC-char transparency, so figure
  119. * out how large the fcs will really be.
  120. */
  121. fcs = ComputeFCS(contigPacketBuf, ndisPacketBytes);
  122. for (i = 0, tmpfcs = fcs, fcsLen = 0; i < SLOW_IR_FCS_SIZE; tmpfcs >>= 8, i++){
  123. UCHAR fcsbyte = tmpfcs & 0x00ff;
  124. switch (fcsbyte){
  125. case SLOW_IR_BOF:
  126. case SLOW_IR_EOF:
  127. case SLOW_IR_ESC:
  128. fcsBuf[fcsLen++] = SLOW_IR_ESC;
  129. fcsBuf[fcsLen++] = fcsbyte ^ SLOW_IR_ESC_COMP;
  130. break;
  131. default:
  132. fcsBuf[fcsLen++] = fcsbyte;
  133. break;
  134. }
  135. }
  136. /*
  137. * Now begin building the IR frame.
  138. *
  139. * This is the final format:
  140. *
  141. * BOF (1)
  142. * extra BOFs ...
  143. * NdisMediumIrda packet (what we get from NDIS):
  144. * Address (1)
  145. * Control (1)
  146. * FCS (2)
  147. * EOF (1)
  148. */
  149. /*
  150. * Prepend BOFs (extra BOFs + 1 actual BOF)
  151. */
  152. numExtraBOFs = packetInfo->ExtraBOFs;
  153. if (numExtraBOFs > MAX_NUM_EXTRA_BOFS){
  154. numExtraBOFs = MAX_NUM_EXTRA_BOFS;
  155. }
  156. for (i = totalBytes = 0; i < numExtraBOFs; i++){
  157. *(SLOW_IR_BOF_TYPE *)(irPacketBuf+totalBytes) = SLOW_IR_EXTRA_BOF;
  158. totalBytes += SLOW_IR_EXTRA_BOF_SIZE;
  159. }
  160. *(SLOW_IR_BOF_TYPE *)(irPacketBuf+totalBytes) = SLOW_IR_BOF;
  161. totalBytes += SLOW_IR_BOF_SIZE;
  162. /*
  163. * Copy the NDIS packet from our contiguous buffer,
  164. * applying escape-char transparency.
  165. */
  166. for (i = 0; i < ndisPacketBytes; i++){
  167. nextChar = contigPacketBuf[i];
  168. switch (nextChar){
  169. case SLOW_IR_BOF:
  170. case SLOW_IR_EOF:
  171. case SLOW_IR_ESC:
  172. irPacketBuf[totalBytes++] = SLOW_IR_ESC;
  173. irPacketBuf[totalBytes++] = nextChar ^ SLOW_IR_ESC_COMP;
  174. break;
  175. default:
  176. irPacketBuf[totalBytes++] = nextChar;
  177. break;
  178. }
  179. }
  180. /*
  181. * Add FCS, EOF.
  182. */
  183. NdisMoveMemory((PVOID)(irPacketBuf+totalBytes), (PVOID)fcsBuf, fcsLen);
  184. totalBytes += fcsLen;
  185. *(SLOW_IR_EOF_TYPE *)(irPacketBuf+totalBytes) = (UCHAR)SLOW_IR_EOF;
  186. totalBytes += SLOW_IR_EOF_SIZE;
  187. *irPacketLen = totalBytes;
  188. DBGOUT(("... NdisToIrPacket converted %d-byte ndis pkt to %d-byte irda pkt:", ndisPacketLen, *irPacketLen));
  189. return TRUE;
  190. }