<div>Files included in this package:</div>
<div>readme.txt      - The file you are reading<br>intrface.c      - The file which should be changed to support a new transport<br>hei.c           - Common source for HEI functions<br>hei.h           - Header for HEI functions<br>
defs.h          - Defines used by hei.c<br>function.h      - Defines used by hei.c</div>
<div>/* Some usefull stuff! */<br>#if !defined(_DEFS_H)<br>#define _DEFS_H</div>
<p>typedef int  BOOL;<br>#define FALSE 0<br>#define TRUE 1</p>
<p>typedef unsigned char BYTE;<br>typedef unsigned short WORD;<br>typedef unsigned long DWORD;</p>
<p>typedef unsigned int UINT;</p>
<p>#define LONG long<br>#define ULONG_MAX     0xffffffff    /* maximum unsigned long value */</p>
<p>#define LOBYTE(w) ((BYTE)(w))<br>#define HIBYTE(w) ((BYTE)(((UINT)(w) >> 8) & 0xFF))</p>
<p>#define LOWORD(l) ((WORD)(DWORD)(l))<br>#define HIWORD(l) ((WORD)((((DWORD)(l)) >> 16) & 0xFFFF))</p>
<p>#define MAKEWORD(a, b)      ((WORD)(((BYTE)(a)) | ((WORD)((BYTE)(b))) << 8))<br>#define MAKELONG(low, high) ((LONG)(((WORD)(low)) | (((DWORD)((WORD)(high))) << 16)))</p>
<p>#define max(a,b) (((a) > (b)) ? (a) : (b))<br>#define min(a,b) (((a) < (b)) ? (a) : (b))</p>
<p> </p>
<p>#define NULL    ((void *)0)</p>
<p>#define TimeDiff(StartTime, EndTime)  (((DWORD)EndTime > (DWORD)StartTime) ? ((DWORD)EndTime - (DWORD)StartTime) : ((DWORD)EndTime + ((DWORD)ULONG_MAX - (DWORD)StartTime) + 1))</p>
<div><br>#endif</div>
<div> </div>
<div> </div>
<div> </div>
<div>#define UDP_PORT_ID  0x7070</div>
<div><br>#pragma pack(1)<br>typedef struct<br> {<br> char *pOSBegin;<br> char *pOSEnd;<br> char *pOSRun;<br> WORD CRC;<br> WORD BootSignature;<br> WORD OSSignature;<br> BYTE Unused[14];<br> } OSDef;</div>
<div>     </div>
<div>/* Error/return val List */<br>#define HEI_NO_ERROR     0</div>
<div>#define ICMP_PKT_FOUND    65<br>#define ARP_PKT_FOUND    66<br>#define TYPE_NOT_HANDLED   67<br>#define LINK_SENSE_TRIGGERED  68</div>
<div>#define UNK_IP_PACKET    100<br>#define UNK_ETHERTYPE    101<br>#define UNK_PACKET_TYPE    102<br>#define UNK_802X_PACKET_TYPE  103<br>#define UNK_LLC_TYPE     104<br>#define CRC_DOES_NOT_MATCH   105<br>#define CRC_NO_DATA     106<br>
#define ENET_ADDR_REPROGRAMMED 107<br>#define NULL_DATA_POINTER   108<br>#define SIZE_ERROR     109<br>#define NOT_FOUND      110<br>#define INVALID_TYPE     111<br>#define RAM_ALREADY_LOCKED   112<br>#define INVALID_REQUEST    113<br>
#define TIMEOUT_ERROR    114<br>#define FLASH_PROGRAM_ERROR  115<br>#define INVALID_OS     116<br>#define INVALID_LOCATION   117<br>#define INVALID_SLOT_NUMBER  118<br>#define INVALID_DATA     119<br>#define MODULE_BUSY     120<br>
#define CHANNEL_FAILURE    121<br>#define UNUSED_CHANNELS_EXIST  122<br>#define INVALID_UDP_PORT   123<br>#define SHUTDOWN_OS     124<br>#define NOT_MY_IP_ADDRESS   125<br>#define PROTECTION_ERROR   126<br>#define UNK_TYPE_ERROR    127<br>
#define BACKPLANE_INIT_ERROR  128<br>#define UNK_RESPONSE     129<br>#define UNK_RXWX_FORMAT    130<br>#define UNK_ACK      131<br>#define UNK_NAK      132<br>#define RANGE_ERROR     133<br>#define LENGTH_WARNING    134<br>
#define INVALID_BASE_NUMBER   135<br>#define INVALID_MODULE_TYPE   136<br>#define INVALID_OFFSET    137<br>#define INVALID_BOOT_VER_FOR_OS  138<br>#define BROKEN_TRANSMITTER   139<br>#define INVALID_ADDRESS    140</div>
<div>#define CHANNELS_UNUSED_0   200<br>#define CHANNELS_UNUSED_1   201<br>#define CHANNELS_UNUSED_2        201<br>#define CHANNELS_UNUSED_3        203<br>#define CHANNELS_UNUSED_4        204<br>#define CHANNELS_UNUSED_5        205<br>
#define CHANNELS_UNUSED_6        206<br>#define CHANNELS_UNUSED_7        207<br>#define CHANNELS_UNUSED_8        208<br>#define CHANNELS_UNUSED_9        209<br>#define CHANNELS_UNUSED_10       210<br>#define CHANNELS_UNUSED_11       211<br>
#define CHANNELS_UNUSED_12       212<br>#define CHANNELS_UNUSED_13       213<br>#define CHANNELS_UNUSED_14       214<br>#define CHANNELS_UNUSED_15       215<br>#define CHANNELS_UNUSED_16       216</div>
<div>#pragma pack()</div>
<div> </div>
<div>/*<br>** HEI.C - Platform independent code for communicating with Host Automation Products<br>**   line of ethernet modules.<br>** <br>** Copyright (C) - 1996-1997 Host Automation Products, Inc.<br>**<br>*/<br>#include "windows.h"<br>
#include "defs.h"<br>#include <memory.h><br>#include <string.h><br>#include <ctype.h><br>#include "hei.h"</div>
<div>void (*pAsyncPacketHandler)(HEIDevice *pDevice, BYTE *pResponse, int ResponseLen) = 0;</div>
<div><br>/* Interface functions */<br>int HEIIOpen(void);<br>int HEIIClose(void);<br>int HEIIOpenDevice(HEITransport *pTransport, HEIDevice *pDevice);<br>int HEIICloseDevice(HEIDevice *pDevice);<br>int HEIIOpenTransport(HEITransport *pTransport);<br>
int HEIICloseTransport(HEITransport *pTransport);<br>int HEIIReceivePacket(HEIDevice *pDevice, BYTE *pResponse, int *pResponseSize);<br>int HEIISendPacket(HEIDevice *pDevice, BYTE *pPacket, WORD PacketSize);<br>DWORD HEIIGetCounter(void);</div>

<div>#define DEBUG_FILE 0</div>
<div>#if DEBUG_FILE<br>#include <stdio.h><br>#include <stdarg.h><br>#include "windows.h"</div>
<div>FILE *pOutFile=NULL;</div>
<div>void DebugString(char  *String, ...)<br> {<br> char  Buffer[200];</div>
<div> va_list ap;</div>
<div> va_start(ap, String);</div>
<div> wvsprintf(Buffer, String, ap);</div>
<div>    //OutputDebugString(Buffer);<br>    pOutFile = fopen("c:\\heiout.txt", "a+");</div>
<div> if (pOutFile)<br>  {<br>  fputs("\n", pOutFile);<br>  fputs(Buffer, pOutFile);<br>  fclose(pOutFile);<br>  }</div>
<div> va_end(ap);<br> }</div>
<div><br>#endif</div>
<div><br>__declspec(dllexport) int HEISetAsyncHandler(void (*pFun)(HEIDevice *pDevice, BYTE *pResponse, int ResponseLen))<br> {<br> pAsyncPacketHandler = pFun;<br> return 0;<br> }</div>
<div>__declspec(dllexport) int HEIGetAsyncHandler(void (**pFun)(HEIDevice *pDevice, BYTE *pResponse, int ResponseLen))<br> {<br> *pFun = pAsyncPacketHandler;<br> return 0;<br> }</div>
<div><br>/*<br>** This macro will return the difference between a start time (in milliseconds) and an end time (also in milliseconds).<br>** It handles the fact that a DWORD millisecond indicator will wrap every 49.XXX days.<br>
*/<br>#define TimeDiff(StartTime, EndTime)  (((DWORD)EndTime > (DWORD)StartTime) ? ((DWORD)EndTime - (DWORD)StartTime) : ((DWORD)EndTime + ((DWORD)ULONG_MAX - (DWORD)StartTime) + 1))</div>
<div>#define WordDiff(Start, End)  (((WORD)End > (WORD)Start) ? ((WORD)End - (WORD)Start) : ((WORD)End + ((WORD)0xFFFF - (WORD)Start) + 1))<br>         <br>#ifdef NOCRC<br>int DoCRC = 0;<br>#else         <br>int DoCRC = 1;<br>
#endif</div>
<div>#define EXTRA_TIME_FOR_SETUP_DATA 10</div>
<div>int DoEncrypt(Encryption *pEncrypt, BYTE *ptr, WORD Num);<br>__declspec(dllexport) int _SendPacket(HEIDevice *pDevice, BYTE *pPacket, WORD PacketSize, BYTE *pResponse, int *pResponseSize, BOOL WaitForResponse, BOOL ReturnWarnings);<br>
   </div>
<div>#if defined(SUPERVISOR)<br>int PrepareSupervisorPacket(HEIDevice *pDevice, BYTE *pPacket, WORD PacketSize);<br>#endif /* #if defined(SUPERVISOR) */</div>
<div><br>WORD CalcCRC(WORD    icrc, BYTE   *icp, WORD    icnt);<br>  <br>int InsertCRC(BYTE *pBuffer, WORD Len)<br> {<br> WORD *pWord = (WORD *) (pBuffer+5);<br> <br> if (DoCRC)<br>  {<br>  (*pWord) = CalcCRC(0, (BYTE *) (pBuffer+PACKET_HEADER_SIZE), (WORD) (Len - PACKET_HEADER_SIZE));<br>
  }<br> else<br>  {<br>  (*pWord) = 0;<br>  }<br>  <br> return 0;<br> }</div>
<div>BOOL CRCCorrect(BYTE *pBuffer, WORD Len)<br> {<br> if (!DoCRC)<br>  return TRUE;<br> else if (Len < PACKET_HEADER_SIZE)<br>  return FALSE;<br> else<br>  {<br>  WORD *pCRC = (WORD *) (pBuffer+5);<br>  WORD CRC;</div>

<div>  if (!*pCRC)<br>   return TRUE;</div>
<div>  CRC = CalcCRC(0, (BYTE *) (pBuffer+PACKET_HEADER_SIZE), (WORD) (Len - PACKET_HEADER_SIZE));</div>
<div>  return (CRC == (*pCRC));<br>  }<br> }</div>
<div><br>/* int GetResponse(HEIDevice *pDevice, BYTE *pResponse, int *pResponseSize, WORD ExtraTime=0, BOOL ProcessTimeout=TRUE, BOOL CheckAppVal=TRUE)*/<br>__declspec(dllexport) int GetResponse(HEIDevice *pDevice, BYTE *pResponse, int *pResponseSize, WORD ExtraTime, BOOL ProcessTimeout, BOOL CheckAppVal)<br>
 {<br> unsigned short ThisAppVal = pDevice->LastAppVal;<br> DWORD DeviceTimeout = pDevice->Timeout;<br> int SavedSize = *pResponseSize;<br> int Error;</div>
<div> DWORD Timeout = DeviceTimeout + ExtraTime;<br> DWORD StartTime = HEIIGetCounter();</div>
<div> while (1) <br>  {<br>  *pResponseSize = SavedSize;</div>
<div>  Error = HEIIReceivePacket(pDevice, pResponse, pResponseSize);<br>  <br>  if (!Error && (*pResponseSize))<br>   {<br>   /* We have a packet to look at. */<br>   /* Check the App Val. */<br>   WORD *pWord = (WORD *) (pResponse+3);<br>
     <br>   if (*pWord == ThisAppVal || !ThisAppVal || !CheckAppVal)<br>    {<br>    int Retval;<br>    <br>    if (!CheckAppVal)<br>     pDevice->LastAppVal = *pWord;</div>
<div>    Retval = 0;</div>
<div>    if (CRCCorrect((BYTE *) pResponse, (WORD) *pResponseSize))<br>     {<br>     /* We have our response! */<br>     }<br>    else <br>     {<br>     pDevice->BadCRCCount++;<br>     Retval =  HEIE_CRC_MISMATCH;<br>
     }<br>       <br>    return Retval;<br>    }<br>   else<br>    {<br>    if (pAsyncPacketHandler)<br>     {<br>     (*pAsyncPacketHandler)(pDevice, pResponse, *pResponseSize);<br>     }</div>
<div>    pDevice->LatePacketCount++; <br>    continue;<br>    }<br>   }<br>  else if (Error && Error != HEIE_NO_RESPONSE)<br>   {<br>   return Error;<br>   }<br>  else if (!ProcessTimeout)<br>   {<br>   /* No more packets to look at. */<br>
   return HEIE_NO_RESPONSE;<br>   }<br>   <br>  if (ProcessTimeout && (TimeDiff(StartTime, HEIIGetCounter()) >= Timeout))<br>   {<br>   /* Timeout! */<br>   break;<br>   }<br>  }<br>   <br> *pResponseSize = 0;<br>
 return HEIE_TIMEOUT;<br> }</div>
<div><br>static unsigned short AppVal = 1;</div>
<div>__declspec(dllexport) int HEIGetResponse(HEIDevice *pDevice, BYTE *pResponse, int *pResponseSize, BOOL CheckAppVal)<br> {<br> int Retval;<br> <br>#if DEBUG_FILE<br> DebugString("In GetResponse %u", AppVal);<br>
#endif </div>
<div> Retval = GetResponse(pDevice, pResponse, pResponseSize, 0, FALSE, CheckAppVal);<br> <br>#if DEBUG_FILE<br> DebugString("Leaving GetResponse %u -> %d (0x%X)", AppVal, Retval, Retval);<br>#endif </div>
<div> return Retval;<br> }<br> <br>int WriteERMCommandData(HEIDevice *pDevice, WORD Base, WORD Slot, BYTE *pData, WORD NumBytes, WORD Offset)<br> {<br> return HEIWriteERMData(pDevice, Base, Slot, DATA_COMMAND, pData, NumBytes, Offset);<br>
 }</div>
<div>int ReadERMCommandData(HEIDevice *pDevice, WORD Base, WORD Slot, BYTE *pData, WORD NumBytes, WORD Offset)<br> {<br> return HEIReadERMData(pDevice, Base, Slot, DATA_COMMAND, pData, NumBytes, Offset);<br> }</div>
<div><br>#if HEIAPIVERSION>=3<br>int _SendProxyPacket(HEIDevice *pDevice, BYTE *pPacket, WORD PacketSize, BYTE *pResponse, int *pResponseSize, BOOL WaitForResponse, BOOL ReturnWarnings)<br> {<br> int Retval = 0;<br> WORD DataOffset = pDevice->DataOffset;<br>
 WORD SubTotal = PacketSize - DataOffset;<br> BYTE *pCmd = pPacket+PacketSize-SubTotal;</div>
<div> // Disable proxying.<br> pDevice->UseProxy = FALSE;</div>
<div> Retval = WriteERMCommandData(pDevice, pDevice->ProxyBase, pDevice->ProxySlot, pCmd, SubTotal, 0);</div>
<div> if (Retval)<br>  {<br> // printf("\nError %d (0x%X) from WriteERMCommandData", Retval, Retval);<br>  }<br> else<br>  {<br>  BYTE Extra[10];<br>  WORD ExtraLen;<br>  WORD *pWord;</div>
<div>  pWord = (WORD *) &Extra[0];</div>
<div>  *pWord++ = pDevice->ProxyDevNum;<br>  *pWord++ = 0;  // CmdOffset<br>  *pWord++ = SubTotal;  // CmdLength<br>  *pWord++ = 0;  // RspOffset;<br>  *pWord++ = 0x800; // RspLength<br>  ExtraLen = 10;</div>
<div>  Retval = HEIDoERMCommandEx(pDevice, pDevice->ProxyBase, pDevice->ProxySlot, COMMAND_PROCESS_COMMAND_BUFFER, Extra, ExtraLen);</div>
<div>  if (Retval)<br>   {<br> //  printf("Error %d (0x%X) from call to WPLCDoERMCommandEx", Retval, Retval);<br>   }<br>  else<br>   {<br>   // Read response from command buffer.<br>   BYTE ResponseBuffer[4];<br>
   Retval = ReadERMCommandData(pDevice, pDevice->ProxyBase, pDevice->ProxySlot, ResponseBuffer, 4, 0);</div>
<div>   if (Retval)<br>    {<br> //   printf("\nError %d (0x%X) from ReadERMCommandData", Retval, Retval);<br>    }<br>   else<br>    {<br>    WORD *pError = (WORD *) &ResponseBuffer[0];<br>    WORD *pLen = (WORD *) &ResponseBuffer[2];</div>

<div>    if (*pError)<br>     {<br> //    printf("\nCommand Error: %d  Len: %d", *pError, *pLen);<br>     }<br>    else<br>     {<br>     Retval = ReadERMCommandData(pDevice, pDevice->ProxyBase, pDevice->ProxySlot, pResponse+PACKET_HEADER_SIZE, *pLen, 4);</div>

<div>     if (Retval)<br>      {<br> //     printf("\nError %d (0x%X) from ReadERMCommandData", Retval, Retval);<br>      }<br>     else<br>      {<br>      // Fix pResponse[0] - pResponse[PACKET_HEADER_SIZE-1]<br>
      (*pResponseSize) = (*pLen) + PACKET_HEADER_SIZE;<br>      }<br>     }<br>    }<br>   }<br>  }</div>
<div> // Reenable proxying.<br> pDevice->UseProxy = TRUE;<br> return Retval;<br> }<br>#endif</div>
<div> <br>/*int SendPacket(HEIDevice *pDevice, BYTE *pPacket, WORD PacketSize, BYTE *pResponse, int *pResponseSize, BOOL WaitForResponse=TRUE, BOOL ReturnWarnings=FALSE)*/<br>__declspec(dllexport) int _SendPacket(HEIDevice *pDevice, BYTE *pPacket, WORD PacketSize, BYTE *pResponse, int *pResponseSize, BOOL WaitForResponse, BOOL ReturnWarnings)<br>
 {<br>#if HEIAPIVERSION>=3<br> if (pDevice->UseProxy == TRUE)<br>  {<br>  // Proxy this command to the device.<br>  //printf("\nUse proxy.");<br>  return _SendProxyPacket(pDevice, pPacket, PacketSize, pResponse, pResponseSize, WaitForResponse, ReturnWarnings);<br>
  }<br>#endif<br>  {<br>  BYTE *ptr;<br>  WORD *pWord;<br>  unsigned short ThisAppVal;<br>  unsigned short *pWordAppVal;<br>  BYTE *pBegin = pPacket;<br>  WORD PreHeaderBytes = pDevice->DataOffset - PACKET_HEADER_SIZE;<br>
  WORD Retry;</div>
<div>  if (pDevice->UseAddressedBroadcast)<br>   PreHeaderBytes -= 7;<br>    <br>  pPacket += PreHeaderBytes;<br>    <br>  ptr = pPacket;<br>    <br>  if (pDevice->UseAddressedBroadcast)<br>   {<br>   pPacket[PACKET_HEADER_SIZE] = FUN_ADDRESSED_BROADCAST;<br>
   memcpy(&pPacket[PACKET_HEADER_SIZE+1], pDevice->ENetAddress, 6);<br>   }<br>   <br>  *ptr++ = 'H';<br>  *ptr++ = 'A';<br>  *ptr   = 'P';<br>    <br>  /* Calculate CRC */<br>  InsertCRC(pPacket, (WORD) (PacketSize-PreHeaderBytes));<br>
   <br>  /* Insert the number of bytes which were checksumed. */<br>  pWord = (WORD *) (pPacket+7);<br>   <br>  *pWord = (WORD) PacketSize - PreHeaderBytes - PACKET_HEADER_SIZE; /* This is the bytes to follow/checksum */<br>
   <br>  /* Do encryption (if required) */<br>  if (pDevice->_pTransport->Encrypt.Algorithm)<br>   DoEncrypt(&pDevice->_pTransport->Encrypt, pPacket+5, (WORD) (PacketSize-5-PreHeaderBytes));<br>   <br>  pWordAppVal = (unsigned short *) (pPacket+3);<br>
    <br>     <br> #if defined(SUPERVISOR)<br>  PrepareSupervisorPacket(pDevice, pPacket, PacketSize);<br> #endif /* #if defined(SUPERVISOR) */</div>
<div>  for (Retry = 0; Retry<=pDevice->Retrys; Retry++)<br>      {<br>   int ResponseSize = *pResponseSize;<br>   int Error;<br>     <br>   ThisAppVal = AppVal++;<br>   pDevice->LastAppVal = ThisAppVal;<br>     <br>
   if (!AppVal)<br>    AppVal++;<br>   <br>   if (Retry)<br>    pDevice->RetryCount++;<br>      <br>   /* Insert the app value. */<br>   *pWordAppVal = ThisAppVal;<br>   <br>   Error = HEIISendPacket(pDevice, pBegin, PacketSize);<br>
     <br>   if (Error)<br>    {<br>    *pResponseSize = 0;<br>    return Error;<br>    }<br>     <br>   if (!WaitForResponse)<br>    {<br>    *pResponseSize = 0;<br>    return HEIE_NO_RESPONSE;<br>    }</div>
<div>   Error = GetResponse(pDevice, pResponse, &ResponseSize, 0, TRUE, TRUE);</div>
<div>   if (!Error)<br>    {<br>    *pResponseSize = ResponseSize;</div>
<div>    if (Retry != 0 && ReturnWarnings)<br>     return HEIW_RETRY;</div>
<div>    return 0;   /* Success! */<br>    }<br>   else if (Error != HEIE_TIMEOUT)<br>    return Error;<br>   }<br>   <br>  *pResponseSize = 0;<br>  return HEIE_TIMEOUT;<br>  }<br> }</div>
<div><br>__declspec(dllexport) int SendPacketTwoResponses(HEIDevice *pDevice, BYTE *pPacket, WORD PacketSize, BYTE *pResponse, int *pResponseSize, <br>         BOOL WaitForResponse, BOOL ReturnWarnings, WORD Bytes2Verify, BYTE *pVerifyData, <br>
         WORD ExtraTime, BOOL ProcessTimeout, BOOL CheckAppVal)<br> {<br> WORD SaveRetryCount = pDevice->RetryCount;<br> WORD SaveRetrys = pDevice->Retrys;<br> int SaveResponseSize = *pResponseSize;</div>
<div>#if HEIAPIVERSION>=3<br> if (pDevice->UseProxy == TRUE)<br>  {<br>  // Proxy this command to the device.<br>  //printf("\nUse proxy.");<br>  return _SendProxyPacket(pDevice, pPacket, PacketSize, pResponse, pResponseSize, WaitForResponse, ReturnWarnings);<br>
  }<br>#endif</div>
<div> while (TRUE)<br>  {<br>  int Error = _SendPacket(pDevice, pPacket, PacketSize,pResponse, pResponseSize, WaitForResponse, ReturnWarnings);</div>
<div>  if (Error && !(Error & HEIW_FIRST_WARNING))<br>   {<br>   /* Restore retrys value */<br>   pDevice->Retrys = SaveRetrys;<br>   return Error;<br>   }</div>
<div>  /* Check and make sure we got an ack. */<br>  if (Bytes2Verify)<br>   {<br>   BYTE *pRet = (pResponse+PACKET_HEADER_SIZE);<br> <br>   while (Bytes2Verify)<br>    {<br>    if (*pRet++ != *pVerifyData++)<br>     {<br>
     /* Restore retrys value */<br>     pDevice->Retrys = SaveRetrys;<br>     return HEIE_INVALID_RESPONSE;<br>     }</div>
<div>    Bytes2Verify--;<br>    }<br>   }</div>
<div>  /* Restore size of response buffer. */<br>  *pResponseSize = SaveResponseSize;</div>
<div>  Error = GetResponse(pDevice, pResponse, pResponseSize, ExtraTime, ProcessTimeout, CheckAppVal);</div>
<div>  if (Error == HEIE_TIMEOUT)<br>   {<br>   WORD TotalRetrys;</div>
<div>   /* Perform a retry */<br>   pDevice->RetryCount++;</div>
<div>   /* See how many retrys we have already done. */<br>   TotalRetrys = WordDiff(SaveRetryCount, pDevice->RetryCount);</div>
<div>   if (TotalRetrys >= SaveRetrys)<br>    {<br>    /* Restore retrys value */<br>    pDevice->Retrys = SaveRetrys;</div>
<div>    return Error;<br>    }</div>
<div>   /* Prepare to go again. */<br>   *pResponseSize = SaveResponseSize;</div>
<div>   /* Adjust number of retrys left to do. */<br>   pDevice->Retrys = SaveRetrys - TotalRetrys;<br>   }<br>  else<br>   {<br>   /* Restore retrys value */<br>   pDevice->Retrys = SaveRetrys;</div>
<div>   if (!Error && pDevice->RetryCount != SaveRetryCount)<br>    Error = HEIW_RETRY;</div>
<div>   if (Error)<br>    return Error;</div>
<div>   return HEIE_NULL;<br>   }<br>  }<br> }</div>
<div><br>/* Transport Stuff */<br>__declspec(dllexport) int HEIOpenTransport(HEITransport *pTransport, WORD Ver, ENetAddress *pSourceAddress)<br>/* __declspec(dllexport) int HEIOpenTransport(HEITransport *pTransport, WORD Ver, DWORD NetworkAddress)*/<br>
 {<br> int Retval;<br> <br>#if DEBUG_FILE<br> DebugString("In HEIOpenTransport");<br>#endif<br> if (HEIAPIVERSION != Ver)<br>  return HEIE_VER_MISMATCH;</div>
<div> if (!pTransport)<br>  return HEIE_NULL_TRANSPORT;<br>  <br> pTransport->Encrypt.Algorithm = HEIEN_NONE;<br> /*pTransport->NetworkAddress = NetworkAddress;*/<br> pTransport->pSourceAddress = pSourceAddress;<br>
 <br> Retval = HEIIOpenTransport(pTransport);<br> <br>#if DEBUG_FILE<br> DebugString("Leaving HEIOpenTransport", Retval);<br>#endif<br> <br> return Retval;<br> }<br> <br> <br>__declspec(dllexport) int HEICloseTransport(HEITransport *pTransport)<br>
 {<br> if (!pTransport)<br>  return HEIE_NULL_TRANSPORT;<br>  <br> return HEIICloseTransport(pTransport);<br> }</div>
<div>__declspec(dllexport) int HEIOpenDevice<br>  (<br>  HEITransport *pTransport, <br>  HEIDevice *pDevice, <br>  WORD Ver, <br>  WORD iTimeout, <br>  WORD iRetrys, <br>  BOOL UseBroadcast<br>  )<br> {<br> int Retval;<br>
 <br>#if 0<br>  {<br>  char Buffer[200];</div>
<div>  wsprintf(Buffer, "Timeout: %d  Retrys: %d  UseBroadCast: %d", iTimeout, iRetrys, UseBroadcast);</div>
<div>  MessageBox(NULL, Buffer, "HEIOpenDevice", 0);<br>  }<br>#endif</div>
<div><br>#if DEBUG_FILE<br> DebugString("In HEIOpenDevice");<br>#endif<br> <br> if (HEIAPIVERSION != Ver)<br>  return HEIE_VER_MISMATCH;</div>
<div> if (!pTransport)<br>  return HEIE_NULL_TRANSPORT;<br>  <br> if (!pDevice)<br>  return HEIE_INVALID_DEVICE;</div>
<div> pDevice->_dwParam    = 0;<br> pDevice->Timeout    = iTimeout;<br> pDevice->Retrys    = iRetrys;<br> pDevice->UseAddressedBroadcast = UseBroadcast;<br> pDevice->UseBroadcast  = UseBroadcast;<br> pDevice->pData     = 0;<br>
 pDevice->SizeOfData   = 0;<br> pDevice->DataOffset   = PACKET_HEADER_SIZE;<br> pDevice->pBuffer    = 0;<br> pDevice->RetryCount   = 0;<br> pDevice->BadCRCCount   = 0;<br> pDevice->LatePacketCount = 0; <br>
 pDevice->ParallelPackets = FALSE;<br> pDevice->_pTransport = pTransport;</div>
<div>#if HEIAPIVERSION==3<br> pDevice->UseProxy = 0;<br> pDevice->ProxyBase = 0;<br> pDevice->ProxySlot = 0;<br> pDevice->ProxyDevNum = 0;<br> memset(pDevice->Reserved, 0, sizeof(pDevice->Reserved));  /* Reserved bytes, set to zero */<br>
#endif</div>
<div> if (pDevice->UseAddressedBroadcast)<br>  pDevice->DataOffset += 7;</div>
<div> Retval = HEIIOpenDevice(pTransport, pDevice);<br> <br>#if DEBUG_FILE<br> DebugString("Leaving HEIOpenDevice", Retval);<br>#endif<br> return Retval;<br> }</div>
<div>__declspec(dllexport) int HEICloseDevice(HEIDevice *pDevice)<br> {<br> int Retval = HEIE_NULL;</div>
<div> if (!pDevice)<br>  return HEIE_INVALID_DEVICE;<br> <br> if (pDevice->_pTransport)<br>  {<br>  Retval = HEIICloseDevice(pDevice);<br>  pDevice->_pTransport = (HEITransport *) NULL;<br>  }<br> <br> return Retval;<br>
 }</div>
<div><br>__declspec(dllexport) int HEIOpen(WORD Ver)<br> {<br> if (HEIAPIVERSION != Ver)<br>  return HEIE_VER_MISMATCH;<br> <br> return HEIIOpen();<br> }</div>
<div>__declspec(dllexport) int HEIClose()<br> {<br> return HEIIClose();<br> }</div>
<div><br>int DoEncrypt(Encryption *pEncrypt, BYTE *ptr, WORD Num)<br> {<br> switch (pEncrypt->Algorithm)<br>  {<br>  case 1:  /* Private key encryption (XOR) */<br>   {<br>   BYTE *keyptr = pEncrypt->Key;<br>   WORD x;<br>
   <br>   for (x=0; x<Num; x++)<br>    {<br>    *ptr++ ^= *keyptr++;<br>    <br>    if (!*keyptr)<br>     keyptr = pEncrypt->Key;<br>    }<br>    <br>   return 0;<br>   }<br>   <br>  default:<br>   return -1;<br>  }<br>
 }</div>
<div>int OpenQueryableDevice(HEITransport *pTransport, HEIDevice *pDevice, WORD Ver)<br> {<br> /* Open a device which I can use for broadcasting a packet. */<br> int RetVal = HEIOpenDevice(pTransport, pDevice, Ver, 20, 0, TRUE);</div>

<div> if (!RetVal)<br>  {<br>  pDevice->UseAddressedBroadcast = FALSE;    /* Don't want to use 'Addressed' Broadcast, just Broadcast! */<br>  pDevice->DataOffset -= 7;  /* We are not using addressed broadcast. */<br>
  pDevice->wParam = 0;<br>  }</div>
<div> return RetVal;<br> }<br> <br> <br>DWORD QueryTimeout = 600;</div>
<div>__declspec(dllexport) DWORD HEISetQueryTimeout(DWORD NewTimeout)<br> {<br> DWORD Save = QueryTimeout;</div>
<div> QueryTimeout = NewTimeout;</div>
<div> return Save;<br> }</div>
<div>__declspec(dllexport) DWORD HEIGetQueryTimeout()<br> {<br> return QueryTimeout;<br> }</div>
<div><br>int DoQuery(HEITransport *pTransport, HEIDevice *pDevice, HEIDevice *pDevices, WORD *pNumDevices, WORD Ver, BYTE *pBuffer, WORD BufferSize)<br> {<br> BYTE RetBuffer[600];<br> int ResponseSize = sizeof(RetBuffer);<br>
 BYTE FromAddress[20];     <br> int Error;<br> WORD Count = 0;<br> DWORD Timeout = QueryTimeout;<br> DWORD StartTime;<br> int Retval;</div>
<div> pDevice->pData = FromAddress;<br> pDevice->SizeOfData = sizeof(FromAddress);</div>
<div> Error = _SendPacket(pDevice, pBuffer, BufferSize, RetBuffer, &ResponseSize, TRUE, FALSE);</div>
<div> StartTime = HEIIGetCounter();<br> Retval = HEIE_NULL;</div>
<div> while (1) <br>  {<br>  switch ((WORD) Error)<br>   {<br>   case HEIE_NULL:<br>    {<br>    /* No Error, so process packet. */<br>    if (RetBuffer[0] == 'H' && RetBuffer[1] == 'A' && (RetBuffer[2] == 'P' || RetBuffer[2] == 'A') &&<br>
     RetBuffer[PACKET_HEADER_SIZE] == 0x55 &&<br>     (BYTE) RetBuffer[PACKET_HEADER_SIZE+1] == 0xAA)<br>     {<br>     if (Count < (*pNumDevices))<br>      {<br>      memcpy(pDevices[Count].Address.Raw, pDevice->pData, pDevice->SizeOfData);<br>
      memcpy(pDevices[Count].ENetAddress, (char *) (RetBuffer+PACKET_HEADER_SIZE+2), 6);</div>
<div>      if (pTransport->Protocol == HEIP_IP)<br>       {<br>       if (RetBuffer[PACKET_HEADER_SIZE+8] == 1)<br>        pDevices[Count].Address.Raw[19] = 1; /* The modules IP address is not initialized. */<br>       else <br>
        pDevices[Count].Address.Raw[19] = 0;<br>       }</div>
<div>      Count++;<br>      }<br>     else<br>      {<br>      Count++;<br>      Retval = HEIE_BUFFER_TOO_SMALL;<br>      }<br>     }</div>
<div>    break;<br>    }</div>
<div>   case HEIE_TIMEOUT:<br>    break;<br>    <br>   case HEIW_RETRY:<br>    break;</div>
<div>   default:<br>    {<br>    /* Other error, so bail out. */<br>    pDevice->pData = 0;<br>    pDevice->SizeOfData = 0;<br>    return Error;<br>    }<br>   }</div>
<div>  if (TimeDiff(StartTime, HEIIGetCounter()) < Timeout)<br>   {<br>   ResponseSize = sizeof(RetBuffer);<br>   pDevice->SizeOfData = sizeof(FromAddress);<br>   Error = GetResponse(pDevice, RetBuffer, &ResponseSize, 0, TRUE, TRUE);<br>
   }<br>  else<br>   break;<br>  }</div>
<div> *pNumDevices = Count;<br> pDevice->pData = 0;<br> pDevice->SizeOfData = 0;<br> return Retval;<br> } </div>
<div><br>__declspec(dllexport) int HEIQueryDevices(HEITransport *pTransport, HEIDevice *pDevices, WORD *pNumDevices, WORD Ver)<br> {<br> HEIDevice qDevice;<br> WORD DataOffset;<br> BYTE Buffer[100];<br> WORD Total;<br> int Retval;<br>
 int Error;</div>
<div> if (pTransport->Protocol == HEIP_SERIAL)<br>  {<br>  *pNumDevices = 0;<br>  return HEIE_NULL;<br>  }</div>
<div> Error = OpenQueryableDevice(pTransport, &qDevice, Ver);<br> <br> if (Error)<br>  return Error;</div>
<div> /* Build the buffer.   */<br> DataOffset = qDevice.DataOffset;</div>
<div> Buffer[DataOffset] = FUN_POLLING_ALL;   /* This is the function code! */</div>
<div> Total = DataOffset+1;</div>
<div> Retval = DoQuery(pTransport, &qDevice, pDevices, pNumDevices, Ver, Buffer, Total);</div>
<div> HEICloseDevice(&qDevice);<br> <br> return Retval; <br> }</div>
<div>__declspec(dllexport) int HEIQueryDeviceData(HEITransport *pTransport, HEIDevice *pDevices, WORD *pNumDevices, WORD Ver, WORD DataType, BYTE *pData, WORD SizeofData)<br> {<br> HEIDevice qDevice;<br> WORD DataOffset;<br>
 BYTE Buffer[600];<br> WORD *pWord;<br> WORD Total;<br> int Retval;<br> <br> int Error = OpenQueryableDevice(pTransport, &qDevice, Ver);<br> <br> if (Error)<br>  return Error;</div>
<div> /* Build the buffer.   */<br> DataOffset = qDevice.DataOffset;</div>
<div> Buffer[DataOffset] = FUN_QUERY_SETUP_DATA;   /* This is the function code! */<br> Buffer[DataOffset+1] = 0;</div>
<div> pWord = (WORD *) (Buffer+DataOffset+2);<br>   <br> if (SizeofData > 512)<br>   SizeofData = 512;</div>
<div> *pWord++ = DataType;<br> *pWord = SizeofData;<br> <br> memcpy(Buffer+DataOffset+6, pData, SizeofData);</div>
<div> Total = qDevice.DataOffset+6+SizeofData;</div>
<div> Retval = DoQuery(pTransport, &qDevice, pDevices, pNumDevices, Ver, Buffer, Total);</div>
<div> HEICloseDevice(&qDevice);<br> <br> return Retval; <br> }</div>
<div><br>/* SUPPORT INFORMATION */<br>__declspec(dllexport) int HEIReadSupportInfo(HEIDevice *pDevice, BYTE *pSupportInfo, WORD SizeOfSupportInfo)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br>
 WORD Total;<br> int NumBytes;<br> int Error;<br> int Retval;</div>
<div> Buffer[DataOffset] = (BYTE) FUN_READ_SUPPORT_INFO;    /* This is the function code! */</div>
<div> Total = DataOffset+1;</div>
<div> NumBytes = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  NumBytes -= PACKET_HEADER_SIZE;</div>
<div>  if ((WORD) NumBytes > SizeOfSupportInfo)<br>   {<br>   Retval = HEIE_BUFFER_TOO_SMALL;<br>   NumBytes = SizeOfSupportInfo;<br>   }</div>
<div>  memcpy(pSupportInfo, RetBuffer+PACKET_HEADER_SIZE, NumBytes);<br>  }<br> else<br>  {<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;<br>  }</div>
<div> return Retval;<br> }</div>
<div><br>/* VERSION INFORMATION */<br>__declspec(dllexport) int HEIReadVersionInfo(HEIDevice *pDevice, BYTE *pVerInfo, WORD SizeVerInfo)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br>
 WORD Total;<br> int Error;<br> int Retval;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = (BYTE) FUN_READ_VER_INFO;    /* This is the function code! */</div>
<div> Total = DataOffset+1;</div>
<div> NumBytes = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  NumBytes -= PACKET_HEADER_SIZE;</div>
<div>  if ((WORD) NumBytes > SizeVerInfo)<br>   {<br>   Retval = HEIE_BUFFER_TOO_SMALL;<br>   NumBytes = SizeVerInfo;<br>   }</div>
<div>  memcpy(pVerInfo, RetBuffer+PACKET_HEADER_SIZE, NumBytes);<br>  }<br> else<br>  {<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;<br>  }</div>
<div> return Retval;<br> }</div>
<div><br>/* BASE DEFINITION */<br>__declspec(dllexport) int HEIReadBaseDef(HEIDevice *pDevice, BYTE *pBaseDefInfo, WORD *pSizeOfBaseDefInfo)<br> {<br> BYTE Buffer[300];<br> BYTE RetBuffer[1000];<br> WORD DataOffset = pDevice->DataOffset;<br>
 WORD Total;<br> int Error;<br> int Retval;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = FUN_READ_BASE_DEF;    /* This is the function code! */</div>
<div> Total = DataOffset+1;</div>
<div> if (pBaseDefInfo && *pBaseDefInfo == 0xB1)<br>  {<br>  Buffer[DataOffset+1] = *pBaseDefInfo;<br>  Total++;<br>  }</div>
<div> NumBytes = sizeof(RetBuffer);</div>
<div> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  NumBytes -= PACKET_HEADER_SIZE;</div>
<div>  if ((WORD) NumBytes > *pSizeOfBaseDefInfo)<br>   {<br>   Retval = HEIE_BUFFER_TOO_SMALL;<br>   NumBytes = *pSizeOfBaseDefInfo;<br>   }</div>
<div>  memcpy(pBaseDefInfo, RetBuffer+PACKET_HEADER_SIZE, NumBytes);<br>  (*pSizeOfBaseDefInfo) = NumBytes;<br>  }<br> else<br>  {<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;<br>  (*pSizeOfBaseDefInfo) = 0;<br>  }</div>
<div> return Retval;<br> }</div>
<div>__declspec(dllexport) int HEIRescanBase(HEIDevice *pDevice, DWORD Flags, BYTE *pBaseDefInfo, WORD *pSizeOfBaseDefInfo)<br> {<br> BYTE Buffer[300];<br> BYTE RetBuffer[1000];<br> WORD DataOffset = pDevice->DataOffset;<br>
 WORD Total;<br> int Error;<br> int Retval;<br> int NumBytes;<br> DWORD *pDWord;</div>
<div> Buffer[DataOffset] = FUN_INIT_BASE_DEF;    /* This is the function code! */<br> pDWord = (DWORD *) &Buffer[DataOffset+1];<br> *pDWord = Flags;</div>
<div> Total = DataOffset+5;</div>
<div> NumBytes = sizeof(RetBuffer);</div>
<div> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  NumBytes -= PACKET_HEADER_SIZE;</div>
<div>  if ((WORD) NumBytes > *pSizeOfBaseDefInfo)<br>   {<br>   Retval = HEIE_BUFFER_TOO_SMALL;<br>   NumBytes = *pSizeOfBaseDefInfo;<br>   }</div>
<div>  memcpy(pBaseDefInfo, RetBuffer+PACKET_HEADER_SIZE, NumBytes);<br>  (*pSizeOfBaseDefInfo) = NumBytes;<br>  }<br> else<br>  {<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;<br>  (*pSizeOfBaseDefInfo) = 0;<br>  }</div>
<div> return Retval;<br> }</div>
<div>__declspec(dllexport) int HEIInitBaseDef(HEIDevice *pDevice, BYTE *pBaseDefInfo, WORD *pSizeOfBaseDefInfo)<br> {<br> BYTE Buffer[300];<br> BYTE RetBuffer[600];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br>
 int Error;<br> int Retval;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = FUN_INIT_BASE_DEF;    /* This is the function code! */</div>
<div> Total = DataOffset+1;</div>
<div> NumBytes = sizeof(RetBuffer);</div>
<div> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  NumBytes -= PACKET_HEADER_SIZE;</div>
<div>  if ((WORD) NumBytes > *pSizeOfBaseDefInfo)<br>   {<br>   Retval = HEIE_BUFFER_TOO_SMALL;<br>   NumBytes = *pSizeOfBaseDefInfo;<br>   }</div>
<div>  memcpy(pBaseDefInfo, RetBuffer+PACKET_HEADER_SIZE, NumBytes);<br>  (*pSizeOfBaseDefInfo) = NumBytes;<br>  }<br> else<br>  {<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;<br>  (*pSizeOfBaseDefInfo) = 0;<br>  }</div>
<div> return Retval;<br> }</div>
<div>__declspec(dllexport) int HEIWriteBaseDef(HEIDevice *pDevice, BYTE *pInputBaseDef, WORD SizeOfInputBaseDef, BYTE *pOutputBaseDef, WORD *pSizeOfOutputBaseDef)<br> {<br> BYTE Buffer[600];<br> BYTE RetBuffer[600];<br> WORD DataOffset = pDevice->DataOffset;<br>
 WORD Total;<br> int Error;<br> int Retval;<br> int NumBytes;<br> WORD *pWord;</div>
<div> Buffer[DataOffset] = FUN_WRITE_BASE_DEF;    /* This is the function code! */<br> Buffer[DataOffset+1] = 0;<br> <br> pWord = (WORD *) &Buffer[DataOffset+2];<br> *pWord = SizeOfInputBaseDef;</div>
<div> Total = DataOffset+4+SizeOfInputBaseDef;</div>
<div> if (Total > sizeof(Buffer))<br>  {<br>  return HEIE_DATA_TOO_LARGE;<br>  }<br> <br> memcpy(Buffer+DataOffset+4, pInputBaseDef, SizeOfInputBaseDef);</div>
<div><br> NumBytes = sizeof(RetBuffer);</div>
<div> Error = SendPacketTwoResponses(pDevice, Buffer, Total, RetBuffer, &NumBytes, <br>         TRUE, FALSE, <br>         0, NULL, <br>         30000, TRUE, TRUE);</div>
<div><br>#if 0<br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;<br>  <br> NumBytes = sizeof(RetBuffer);<br> Error = GetResponse(pDevice, RetBuffer, &NumBytes, 30000, TRUE, TRUE);<br>
#endif</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;<br> <br> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  short int *pInt = (short int *) (RetBuffer+PACKET_HEADER_SIZE);<br>  <br>  if (*pInt)<br>   Retval = *pInt;<br>  else if (pOutputBaseDef)<br>   {<br>   NumBytes -= (PACKET_HEADER_SIZE+2);<br>
 <br>   if ((WORD) NumBytes > *pSizeOfOutputBaseDef)<br>    {<br>    Retval = HEIE_BUFFER_TOO_SMALL;<br>    NumBytes = *pSizeOfOutputBaseDef;<br>    }<br> <br>   memcpy(pOutputBaseDef, RetBuffer+PACKET_HEADER_SIZE+2, NumBytes);<br>
   (*pSizeOfOutputBaseDef) = NumBytes;<br>   }<br>  }<br> else<br>  {<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;<br>  <br>  if (pOutputBaseDef && pSizeOfOutputBaseDef)<br>   (*pSizeOfOutputBaseDef) = 0;<br>  }</div>
<div> return Retval;<br> }</div>
<div>/* DEVICE DEFINITION */<br>__declspec(dllexport) int HEIReadDeviceDef(HEIDevice *pDevice, BYTE *pDeviceDefInfo, WORD SizeOfDeviceDefInfo)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br>
 WORD Total;<br> int Error;<br> int Retval;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = (BYTE) FUN_READ_DEVICE_INFO;    /* This is the function code! */</div>
<div> Total = DataOffset+1;</div>
<div> NumBytes = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;<br>   <br> if (NumBytes)<br>  {<br>  NumBytes -= PACKET_HEADER_SIZE;</div>
<div>  if ((WORD) NumBytes > SizeOfDeviceDefInfo)<br>   {<br>   Retval = HEIE_BUFFER_TOO_SMALL;<br>   NumBytes = SizeOfDeviceDefInfo;<br>   }</div>
<div>  memcpy(pDeviceDefInfo, RetBuffer+PACKET_HEADER_SIZE, NumBytes);<br>  }<br> else<br>  {<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;<br>  }</div>
<div> return Retval;<br> }</div>
<div><br>/* SETUP */<br>__declspec(dllexport) int HEIReadSetupData(HEIDevice *pDevice, WORD SetupType, BYTE *pData, WORD *pSizeofData)<br> {<br> BYTE Buffer[100];<br> BYTE RetBuffer[600];<br> WORD DataOffset = pDevice->DataOffset;<br>
 WORD Total;<br> int Error;<br> int Retval;<br> int NumBytes;<br> WORD *pWord;</div>
<div> Buffer[DataOffset] = (BYTE) FUN_READ_SETUP_DATA;    /* This is the function code! */<br> Buffer[DataOffset+1] = 0;</div>
<div> pWord = (WORD *) &Buffer[DataOffset+2];<br> *pWord = SetupType;</div>
<div> Total = DataOffset+4;</div>
<div> NumBytes = sizeof(RetBuffer);</div>
<div> pDevice->Timeout += EXTRA_TIME_FOR_SETUP_DATA;<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> pDevice->Timeout -= EXTRA_TIME_FOR_SETUP_DATA;</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  short int *pInt = (short int *) (RetBuffer+PACKET_HEADER_SIZE);</div>
<div>  NumBytes -= (PACKET_HEADER_SIZE+2);</div>
<div>  if ((WORD) NumBytes > *pSizeofData)<br>   {<br>   Retval = HEIE_BUFFER_TOO_SMALL;<br>   NumBytes = *pSizeofData;<br>   }</div>
<div>  if (*pInt)<br>   Retval = *pInt;</div>
<div>  (*pSizeofData) = NumBytes;</div>
<div>  memcpy(pData, RetBuffer+PACKET_HEADER_SIZE+2, NumBytes);<br>  }<br> else<br>  {<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;<br>  }</div>
<div> return Retval;<br> }</div>
<div>__declspec(dllexport) int HEIWriteSetupData(HEIDevice *pDevice, WORD SetupType, BYTE *pData, WORD SizeofData)<br> {<br> BYTE Buffer[600];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD *pWord;<br>
 WORD Total;<br> int Error;<br> int Retval;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = (BYTE) FUN_WRITE_SETUP_DATA;    /* This is the function code! */<br> Buffer[DataOffset+1] = 0;</div>
<div> pWord = (WORD *) &Buffer[DataOffset+2];<br> *pWord = SetupType;</div>
<div> Total = DataOffset+4+SizeofData;</div>
<div> if (Total > sizeof(Buffer))<br>  {<br>#if 0<br>  BYTE Text[200];</div>
<div>  wsprintf(Text, "Total=%d  DataOffset=%d  SizeofData=%d  SizeofBuffer=%d",<br>   Total, DataOffset, SizeofData, sizeof(Buffer));<br>  MessageBox(NULL, Text, "HEIWriteSetupData", 0);<br>#endif<br>
  return HEIE_DATA_TOO_LARGE;<br>  }</div>
<div> memcpy(&Buffer[DataOffset+4], pData, SizeofData);</div>
<div> NumBytes = sizeof(RetBuffer);<br>  <br> pDevice->Timeout += EXTRA_TIME_FOR_SETUP_DATA;</div>
<div> Error = SendPacketTwoResponses(pDevice, Buffer, Total, RetBuffer, &NumBytes, <br>         TRUE, FALSE,<br>         0, NULL, <br>         30000, TRUE, TRUE);</div>
<div> pDevice->Timeout -= EXTRA_TIME_FOR_SETUP_DATA;</div>
<div>#if 0<br> pDevice->Timeout += EXTRA_TIME_FOR_SETUP_DATA;</div>
<div> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> pDevice->Timeout -= EXTRA_TIME_FOR_SETUP_DATA;</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> NumBytes = sizeof(RetBuffer);<br> Error = GetResponse(pDevice, RetBuffer, &NumBytes, 30000, TRUE, TRUE);<br>#endif</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  short int *pInt = (short int *) (RetBuffer+PACKET_HEADER_SIZE);</div>
<div>  if (*pInt)<br>   Retval = *pInt;<br>  }<br> else<br>  {<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;<br>  }</div>
<div> return Retval;<br> }</div>
<div>__declspec(dllexport) int HEIDeleteSetupData(HEIDevice *pDevice, WORD SetupType)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD *pWord;<br> WORD Total;<br>
 int Error;<br> int Retval;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = (BYTE) FUN_DELETE_SETUP_DATA;    /* This is the function code! */<br> Buffer[DataOffset+1] = 0;</div>
<div> pWord = (WORD *) &Buffer[DataOffset+2];<br> *pWord = SetupType;</div>
<div> Total = DataOffset+4;</div>
<div> NumBytes = sizeof(RetBuffer);</div>
<div> pDevice->Timeout += EXTRA_TIME_FOR_SETUP_DATA;</div>
<div> Error = SendPacketTwoResponses(pDevice, Buffer, Total, RetBuffer, &NumBytes, <br>         TRUE, FALSE,<br>         0, NULL, <br>         30000, TRUE, TRUE);</div>
<div> pDevice->Timeout -= EXTRA_TIME_FOR_SETUP_DATA;<br> <br> <br>#if 0<br> pDevice->Timeout += EXTRA_TIME_FOR_SETUP_DATA;</div>
<div> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> pDevice->Timeout -= EXTRA_TIME_FOR_SETUP_DATA;</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> NumBytes = sizeof(RetBuffer);</div>
<div> Error = GetResponse(pDevice, RetBuffer, &NumBytes, 30000, TRUE, TRUE);<br>#endif</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  short int *pInt = (short int *) (RetBuffer+PACKET_HEADER_SIZE);</div>
<div>  if (*pInt)<br>   Retval = *pInt;<br>  }<br> else<br>  {<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;<br>  }</div>
<div> return Retval;<br> }</div>
<div>__declspec(dllexport) int HEIEnumSetupData(HEIDevice *pDevice, WORD *pData, WORD *pSizeofDataInWords)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[600];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br>
 int Error;<br> int Retval;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = (BYTE) FUN_ENUM_SETUP_DATA;    /* This is the function code! */</div>
<div> Total = DataOffset+1;</div>
<div> NumBytes = sizeof(RetBuffer);</div>
<div> pDevice->Timeout += EXTRA_TIME_FOR_SETUP_DATA;<br> <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> pDevice->Timeout -= EXTRA_TIME_FOR_SETUP_DATA;</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  /*int NumWords; */<br>  short int *pInt = (short int *) (RetBuffer+PACKET_HEADER_SIZE);<br>  short int *pNumWords = (short int *) (RetBuffer+PACKET_HEADER_SIZE+2);</div>
<div>  if ((WORD) *pNumWords > *pSizeofDataInWords)<br>   {<br>   Retval = HEIE_BUFFER_TOO_SMALL;<br>   *pNumWords = *pSizeofDataInWords;<br>   }</div>
<div>  if (*pInt)<br>   Retval = *pInt;</div>
<div>  (*pSizeofDataInWords) = *pNumWords;</div>
<div>  memcpy((char *) pData, (char *) (RetBuffer+PACKET_HEADER_SIZE+4), *pNumWords * 2);<br>  }<br> else<br>  {<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;<br>  }</div>
<div> return Retval;<br> }</div>
<div> </div>
<div>/* IO ACCESS */<br>__declspec(dllexport) int HEIReadIO(HEIDevice *pDevice, BYTE *pData, WORD *DataSize)<br> {<br> BYTE Buffer[100];<br> BYTE RetBuffer[1200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br>
 int Error;<br> int Retval;<br> int NumBytes;<br> <br> Buffer[DataOffset] = FUN_READ_IO; /* This is the function code! */</div>
<div> Total = DataOffset+1;</div>
<div> if (pData && *pData == 0xB1)<br>  {<br>  Buffer[DataOffset+1] = *pData;<br>  Total++;<br>  }</div>
<div> NumBytes = sizeof(RetBuffer);<br> //NumBytes = *DataSize;</div>
<div> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, (pDevice->ParallelPackets) ? FALSE : TRUE, TRUE);</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  short int *pInt = (short int *) &RetBuffer[PACKET_HEADER_SIZE];</div>
<div>  NumBytes -= PACKET_HEADER_SIZE;<br>  NumBytes -= 2;</div>
<div>  if ((WORD) NumBytes > *DataSize)<br>   {<br>   Retval = HEIE_BUFFER_TOO_SMALL;<br>   NumBytes = *DataSize;<br>   }</div>
<div>  if (*pInt)<br>   Retval = (*pInt) | 0x8000;</div>
<div>  memcpy(pData, RetBuffer+PACKET_HEADER_SIZE+2, NumBytes);<br>  (*DataSize) = NumBytes;<br>  }<br> else<br>  {<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;<br>  (*DataSize) = 0;<br>  }</div>
<div> return Retval;<br> }</div>
<div><br>__declspec(dllexport) int HEIWriteIO(HEIDevice *pDevice, BYTE *pData, WORD SizeofData, BYTE *pReturnData, WORD *pSizeofReturnData)<br> {<br> BYTE Buffer[1200];<br> BYTE RetBuffer[1200];<br> WORD DataOffset = pDevice->DataOffset;<br>
 WORD Total;<br> int Error;<br> int Retval;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = FUN_WRITE_IO;    /* This is the function code! */<br> <br> Total = DataOffset+1+SizeofData;</div>
<div> if (Total > sizeof(Buffer))<br>  return HEIE_DATA_TOO_LARGE;</div>
<div> memcpy(Buffer+DataOffset+1, pData, SizeofData);</div>
<div> NumBytes = sizeof(RetBuffer);<br> //NumBytes = *pSizeofReturnData;<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, (pDevice->ParallelPackets) ? FALSE : TRUE, TRUE);</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  short int *pInt = (short int *) &RetBuffer[PACKET_HEADER_SIZE];</div>
<div>  if (pReturnData && pSizeofReturnData)<br>   {<br>   NumBytes -= PACKET_HEADER_SIZE;<br>   NumBytes -= 2;</div>
<div>   if ((WORD) NumBytes > *pSizeofReturnData)<br>    {<br>    Retval = HEIE_BUFFER_TOO_SMALL;<br>    NumBytes = *pSizeofReturnData;<br>    }</div>
<div>   memcpy(pReturnData, RetBuffer+PACKET_HEADER_SIZE+2, NumBytes);<br>   (*pSizeofReturnData) = NumBytes;<br>   }</div>
<div>  if (*pInt)<br>   Retval = (*pInt) | 0x8000;<br>  }<br> else<br>  {<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;</div>
<div>  if (pSizeofReturnData)<br>   (*pSizeofReturnData) = 0;<br>  }</div>
<div> return Retval;<br> }</div>
<div><br>__declspec(dllexport) int HEIWriteIONoRead(HEIDevice *pDevice, BYTE *pData, WORD SizeofData)<br> {<br> BYTE Buffer[1200];<br> BYTE RetBuffer[1200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br>
 int Error;<br> int Retval;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = FUN_WRITE_IO_NO_READ;    /* This is the function code! */<br> <br> Total = DataOffset+1+SizeofData;</div>
<div> if (Total > sizeof(Buffer))<br>  return HEIE_DATA_TOO_LARGE;</div>
<div> memcpy(Buffer+DataOffset+1, pData, SizeofData);</div>
<div> NumBytes = sizeof(RetBuffer);<br> //NumBytes = *pSizeofReturnData;<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, (pDevice->ParallelPackets) ? FALSE : TRUE, TRUE);</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  short int *pInt = (short int *) &RetBuffer[PACKET_HEADER_SIZE];</div>
<div>  if (*pInt)<br>   Retval = (*pInt) | 0x8000;<br>  }<br> else<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;</div>
<div> return Retval;<br> }</div>
<div><br>__declspec(dllexport) int HEIPetDevice(HEIDevice *pDevice)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = FUN_PET_LINK;<br> Buffer[DataOffset+1] = 0;</div>
<div> Total = DataOffset+2;</div>
<div> NumBytes = sizeof(RetBuffer);</div>
<div> return _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);<br> }</div>
<div>__declspec(dllexport) int HEIReadEthernetStats(HEIDevice *pDevice, BYTE *pData, WORD *DataSize, BOOL Clear)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br>
 int Error;<br> int Retval;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = FUN_READ_ETHERNET_STATS;   /* This is the function code! */<br> Buffer[DataOffset+1] = 0;<br> Buffer[DataOffset+2] = Clear ? 1 : 0;</div>
<div> Total = DataOffset+3;</div>
<div> NumBytes = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  NumBytes -= PACKET_HEADER_SIZE;</div>
<div>  if ((WORD) NumBytes > *DataSize)<br>   {<br>   Retval = HEIE_BUFFER_TOO_SMALL;<br>   NumBytes = *DataSize;<br>   }</div>
<div>  memcpy(pData, RetBuffer+PACKET_HEADER_SIZE, NumBytes);<br>  (*DataSize) = NumBytes;<br>  }<br> else<br>  {<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;<br>  (*DataSize) = 0;<br>  }</div>
<div> return Retval;<br> }</div>
<div><br>__declspec(dllexport) int HEIReadModuleStatus(HEIDevice *pDevice, BYTE *pData, WORD *DataSize, BOOL Reset)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[600];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br>
 int Error;<br> int Retval;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = FUN_READ_MODULE_STATUS;   /* This is the function code! */</div>
<div> if (pData && *pData == 0xB1)<br>  Buffer[DataOffset+1] = 1;<br> else<br>  Buffer[DataOffset+1] = 0;</div>
<div> Buffer[DataOffset+2] = Reset ? 1 : 0;</div>
<div> Total = DataOffset+3;</div>
<div> NumBytes = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  short int *pInt = (short int *) &RetBuffer[PACKET_HEADER_SIZE];</div>
<div>  NumBytes -= PACKET_HEADER_SIZE;<br>  NumBytes -= 2;</div>
<div>  if ((WORD) NumBytes > *DataSize)<br>   {<br>   Retval = HEIE_BUFFER_TOO_SMALL;<br>   NumBytes = *DataSize;<br>   }</div>
<div>  if (*pInt)<br>   Retval = *pInt;</div>
<div>  memcpy(pData, RetBuffer+PACKET_HEADER_SIZE+2, NumBytes);<br>  (*DataSize) = NumBytes;<br>  }<br> else<br>  {<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;<br>  (*DataSize) = 0;<br>  }</div>
<div> return Retval;<br> }<br> <br> <br>/* CCM STUFF */<br>#define CCM_READ   0x1E<br>#define CCM_WRITE   0x20<br> <br>__declspec(dllexport) int HEICCMRequest(HEIDevice *pDevice, BOOL bWrite, BYTE DataType, WORD Address, WORD DataLen, BYTE *pData)<br>
 {<br> BYTE Buffer[320];<br> BYTE RetBuffer[320];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br> int Error;<br> int NumBytes;<br> BYTE *pRet;<br> short int *pError;<br> BYTE VerifyData[2];<br> <br>#if DEBUG_FILE<br>
 DebugString("In HEICCMRequest %u", AppVal);<br>#endif  </div>
<div> if(DataLen > 256)<br>  return HEIE_INVALID_REQUEST;<br>   <br>   /* Function */<br> Buffer[DataOffset] = FUN_CCM_REQUEST;<br> <br> /* Unused */<br> Buffer[DataOffset+1] = 0;</div>
<div> /* Request Code. */<br> Buffer[DataOffset+2] = 0x01;<br> <br> /* Direction */<br> Buffer[DataOffset+3] = bWrite ? CCM_WRITE : CCM_READ;<br> <br> /* Length */<br> Buffer[DataOffset+4] = (DataLen == 256) ? 0 : (BYTE)DataLen;<br>
 <br> /* LSB of Address */<br> Buffer[DataOffset+5] = (BYTE) (Address & 0xFF);<br> <br> /* MSB of Address */<br> Buffer[DataOffset+6] = (BYTE) ((Address>>8) & 0xFF);<br> <br> /* Data Type */<br> Buffer[DataOffset+7] = DataType;</div>

<div> Total = DataOffset+8;</div>
<div> if (bWrite) <br>  {<br>  /* We are writing. */<br>  memcpy(&Buffer[DataOffset+8], pData, DataLen);<br>  Total += DataLen;<br>  }</div>
<div> NumBytes = sizeof(RetBuffer);</div>
<div><br> VerifyData[0] = FUN_ACK;<br> VerifyData[1] = FUN_CCM_REQUEST;<br> Error = SendPacketTwoResponses(pDevice, Buffer, Total, RetBuffer, &NumBytes, <br>         (pDevice->ParallelPackets) ? FALSE : TRUE, TRUE, <br>
         2, VerifyData, <br>         0, TRUE, TRUE);</div>
<div> if (Error == HEIE_INVALID_RESPONSE)<br>  {<br>  short int *pError = (short int *) (RetBuffer+PACKET_HEADER_SIZE+2);<br>#if DEBUG_FILE<br>  DebugString("Error %d (0x%X) from HEICCMRequest %u", *pError, *pError, AppVal);<br>
#endif  <br>  return *pError;<br>  }</div>
<div><br>#if 0<br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, (pDevice->ParallelPackets) ? FALSE : TRUE, TRUE);</div>
<div> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  {<br>#if DEBUG_FILE<br>  DebugString("Error %d (0x%X) from HEICCMRequest %u", Error, Error, AppVal);<br>#endif  <br>  return Error;<br>  }</div>

<div> /* Check and make sure we got an ack. */<br> pRet = (RetBuffer+PACKET_HEADER_SIZE);<br> <br> if (*pRet != FUN_ACK || (*(pRet+1) != FUN_CCM_REQUEST))<br>  {<br>  short int *pError = (short int *) (RetBuffer+PACKET_HEADER_SIZE+2);<br>
#if DEBUG_FILE<br>  DebugString("Error %d (0x%X) from HEICCMRequest %u", *pError, *pError, AppVal);<br>#endif  <br>  return *pError;<br>  }</div>
<div> NumBytes = sizeof(RetBuffer);<br> Error = GetResponse(pDevice, RetBuffer, &NumBytes, 0, TRUE, TRUE);<br>#endif</div>
<div><br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  {<br>#if DEBUG_FILE<br>  DebugString("Error %d (0x%X) from HEICCMRequest %u", Error, Error, AppVal);<br>#endif  <br>  return Error;<br>  }</div>

<div> NumBytes -= PACKET_HEADER_SIZE;</div>
<div> pRet = (RetBuffer + PACKET_HEADER_SIZE);</div>
<div> if (*pRet != FUN_RESPONSE || *(pRet+1) != FUN_CCM_REQUEST)<br>  {<br>#if DEBUG_FILE<br>  Error = HEIE_INVALID_RESPONSE;<br>  DebugString("Error %d (0x%X) from HEICCMRequest %u", Error, Error, AppVal);<br>
#endif  <br>  return HEIE_INVALID_RESPONSE;<br>  }<br> <br> pError = (short int *) (RetBuffer+PACKET_HEADER_SIZE+2);<br> <br> if (*pError)<br>  {<br>#if DEBUG_FILE<br>  DebugString("Error %d (0x%X) from HEICCMRequest %u", *pError, *pError, AppVal);<br>
#endif  <br>  return *pError;<br>  }<br>  <br> NumBytes -= 4;</div>
<div> if(!bWrite && NumBytes != (int)DataLen)<br>  {<br>#if DEBUG_FILE<br>  Error = HEIE_INVALID_REQUEST;<br>  DebugString("Error %d (0x%X) from HEICCMRequest %u", Error, Error, AppVal);<br>#endif  <br>
  return HEIE_INVALID_REQUEST;<br>  }<br> <br> memcpy(pData, RetBuffer+PACKET_HEADER_SIZE+4, DataLen);</div>
<div>#if DEBUG_FILE<br> DebugString("Leaving HEICCMRequest %u", AppVal);<br>#endif  <br> <br> return HEIE_NULL;<br> }</div>
<div><br>__declspec(dllexport) int HEIKSEQRequest(HEIDevice *pDevice, WORD DataLenIn, BYTE *pData, WORD *pDataLen)<br> {<br> BYTE Buffer[320];<br> BYTE RetBuffer[320];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br>
 int Error;<br> int NumBytes;<br> BYTE *pRet;<br> short int *pError;<br> int Retval;<br> BYTE VerifyData[2];</div>
<div>#if DEBUG_FILE<br> DebugString("In HEIKSEQRequest %u", AppVal);<br>#endif  </div>
<div> if(DataLenIn > 256)<br>  return HEIE_INVALID_REQUEST;</div>
<div> /* Function */<br> Buffer[DataOffset] = FUN_KSEQ_REQUEST;<br> <br> /* Unused */<br> Buffer[DataOffset+1] = 0;</div>
<div> /* Request Code. */<br> Buffer[DataOffset+2] = (DataLenIn == 256) ? 0 : (BYTE)DataLenIn;<br> <br> /* Unused */<br> Buffer[DataOffset+3] = 0;<br> <br> /* Copy task code data. */<br> memcpy(&Buffer[DataOffset+4], pData, DataLenIn);</div>

<div> Total = DataOffset+4+DataLenIn;</div>
<div> NumBytes = sizeof(RetBuffer);</div>
<div><br> VerifyData[0] = FUN_ACK;<br> VerifyData[1] = FUN_KSEQ_REQUEST;<br> Error = SendPacketTwoResponses(pDevice, Buffer, Total, RetBuffer, &NumBytes, <br>         (pDevice->ParallelPackets) ? FALSE : TRUE, TRUE, <br>
         2, VerifyData, <br>         0, TRUE, TRUE);</div>
<div> if (Error == HEIE_INVALID_RESPONSE)<br>  {<br>  short int *pError = (short int *) (RetBuffer+PACKET_HEADER_SIZE+2);<br>  return *pError;<br>  }</div>
<div>#if 0<br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, (pDevice->ParallelPackets) ? FALSE : TRUE, TRUE);</div>
<div> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> /* Check and make sure we got an ack. */<br> pRet = (RetBuffer+PACKET_HEADER_SIZE);<br> <br> if (*pRet != FUN_ACK || (*(pRet+1) != FUN_KSEQ_REQUEST))<br>  {<br>  short int *pError = (short int *) (RetBuffer+PACKET_HEADER_SIZE+2);<br>
  return *pError;<br>  }</div>
<div> NumBytes = sizeof(RetBuffer);<br> Error = GetResponse(pDevice, RetBuffer, &NumBytes, 0, TRUE, TRUE);<br>#endif</div>
<div> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;<br> <br> NumBytes -= PACKET_HEADER_SIZE;</div>
<div> pRet = (RetBuffer + PACKET_HEADER_SIZE);</div>
<div> if (*pRet != FUN_RESPONSE || *(pRet+1) != FUN_KSEQ_REQUEST)<br>  {<br>  return HEIE_INVALID_RESPONSE;<br>  }<br> <br> pError = (short int *) (RetBuffer+PACKET_HEADER_SIZE+2);<br> <br> if (*pError)<br>  return *pError;<br>
  <br> NumBytes -= 4;<br> <br>  Retval = HEIE_NULL;</div>
<div> if ((WORD) NumBytes > *pDataLen)<br>  {<br>  Retval = HEIE_BUFFER_TOO_SMALL;<br>  NumBytes = *pDataLen;<br>  }<br> <br> memcpy(pData, RetBuffer+PACKET_HEADER_SIZE+4, NumBytes);<br> *pDataLen = NumBytes;<br> <br>
#if DEBUG_FILE<br> DebugString("Leaving HEIKSEQRequest", Retval);<br>#endif  <br> <br> return Retval;<br> }</div>
<div>// Returns number of bytes not written.<br>__declspec(dllexport) int HEIWriteComm(HEIDevice *pDevice, WORD Num2Write, BYTE *pData)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br>
 WORD Total;<br> WORD *pWord;<br> int Error;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = FUN_SERIAL_PORT;<br> Buffer[DataOffset+1] = SPF_WRITE_COMM;<br> pWord = (WORD *) &Buffer[DataOffset+2];<br> *pWord = Num2Write;</div>
<div> if (Num2Write > (sizeof(Buffer) - DataOffset - 4))<br>  return HEIE_DATA_TOO_LARGE;</div>
<div> memcpy(Buffer+DataOffset+4, pData, Num2Write);</div>
<div> Total = DataOffset+4+Num2Write;</div>
<div> NumBytes = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> //if (Error) return Error;<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> if (NumBytes)<br>  return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));<br> else<br>  return HEIE_ZERO_BYTES_RECEIVED;<br> }</div>
<div>__declspec(dllexport) int HEIReadComm(HEIDevice *pDevice, WORD *pNum2Read, BYTE *pData)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br> WORD *pWord;<br>
 int Error;<br> int Retval;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = FUN_SERIAL_PORT;<br> Buffer[DataOffset+1] = SPF_READ_COMM;<br> pWord = (WORD *) &Buffer[DataOffset+2];<br> *pWord = *pNum2Read;</div>
<div> Total = DataOffset+4;</div>
<div> NumBytes = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> //if (Error) return Error;<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  short int *pInt = (short int *) (RetBuffer+PACKET_HEADER_SIZE);<br>  short int *pNumReturned = (short int *) (RetBuffer+PACKET_HEADER_SIZE+2);</div>
<div>  if (*pInt)<br>   Retval = *pInt;</div>
<div>  (*pNum2Read) = *pNumReturned;</div>
<div>  memcpy(pData, RetBuffer+PACKET_HEADER_SIZE+4, *pNumReturned);<br>  }<br> else<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;</div>
<div> return Retval;<br> }</div>
<div>__declspec(dllexport) int HEIGetRXAvailable(HEIDevice *pDevice, WORD *pAvailable)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br> int Error;<br>
 int NumBytes;</div>
<div> Buffer[DataOffset] = FUN_SERIAL_PORT;<br> Buffer[DataOffset+1] = SPF_RX_AVAILABLE;</div>
<div> Total = DataOffset+2;</div>
<div> NumBytes = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> //if (Error) return Error;<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> if (NumBytes)<br>  {<br>  *pAvailable = *((WORD *) (RetBuffer+PACKET_HEADER_SIZE+2));<br>  return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));<br>  }<br> else<br>  return HEIE_ZERO_BYTES_RECEIVED;<br> }</div>
<div>__declspec(dllexport) int HEIFlushRXQueue(HEIDevice *pDevice)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br> int Error;<br> int NumBytes;</div>

<div> Buffer[DataOffset] = FUN_SERIAL_PORT;<br> Buffer[DataOffset+1] = SPF_RX_FLUSH;</div>
<div> Total = DataOffset+2;</div>
<div> NumBytes = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> //if (Error) return Error;<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> if (NumBytes)<br>  return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));<br> else<br>  return HEIE_ZERO_BYTES_RECEIVED;<br> }</div>
<div><br>__declspec(dllexport) int HEISetupSerialPort(HEIDevice *pDevice, SerialSetup *pSetup, BOOL WriteToFlash)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br>
 int Error;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = FUN_SERIAL_PORT;<br> Buffer[DataOffset+1] = SPF_SETUP;<br> Buffer[DataOffset+2] = (BYTE) WriteToFlash;<br> Buffer[DataOffset+3] = 0;</div>
<div> memcpy(Buffer+DataOffset+4, pSetup, sizeof(SerialSetup));</div>
<div> Total = DataOffset+4+sizeof(SerialSetup);</div>
<div> NumBytes = sizeof(RetBuffer);</div>
<div> if (WriteToFlash)<br>  {<br>  pDevice->Timeout += EXTRA_TIME_FOR_SETUP_DATA;</div>
<div>  Error = SendPacketTwoResponses(pDevice, Buffer, Total, RetBuffer, &NumBytes, <br>          TRUE, FALSE,<br>          0, NULL, <br>          30000, TRUE, TRUE);</div>
<div>  pDevice->Timeout -= EXTRA_TIME_FOR_SETUP_DATA;<br>  }<br> else<br>  {<br>  Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);<br>  }</div>
<div> //if (Error) <br> // return Error;<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div>#if 0<br> if (WriteToFlash)<br>  pDevice->Timeout += EXTRA_TIME_FOR_SETUP_DATA;<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> if (WriteToFlash)<br>  pDevice->Timeout -= EXTRA_TIME_FOR_SETUP_DATA;</div>
<div> if (Error) return Error;</div>
<div> if (WriteToFlash)<br>  {<br>  NumBytes = sizeof(RetBuffer);<br>  Error = GetResponse(pDevice, RetBuffer, &NumBytes, 30000, TRUE, TRUE);<br>  }<br>#endif</div>
<div> if (NumBytes)<br>  return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));<br> else<br>  return HEIE_ZERO_BYTES_RECEIVED;<br> }<br> <br>__declspec(dllexport) int HEIReadSerialPortSetup(HEIDevice *pDevice, SerialSetup *pSetup)<br>
 {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br> int Error;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = FUN_SERIAL_PORT;<br> Buffer[DataOffset+1] = SPF_READ_SETUP;<br> Buffer[DataOffset+2] = 0;<br> Buffer[DataOffset+3] = 0;</div>
<div> Total = DataOffset+4;</div>
<div> NumBytes = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> //if (Error) return Error;<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> if (NumBytes)<br>  {<br>  // Copy data into user buffer.<br>  memcpy(pSetup, RetBuffer+PACKET_HEADER_SIZE, sizeof(SerialSetup));<br>  return 0;<br>  }<br> else<br>  return HEIE_ZERO_BYTES_RECEIVED;<br> }<br> </div>

<div>__declspec(dllexport) int HEIGetTXLeft(HEIDevice *pDevice, WORD *pLeft)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br> int Error;<br> //int Retval;<br>
 int NumBytes;</div>
<div> Buffer[DataOffset] = FUN_SERIAL_PORT;<br> Buffer[DataOffset+1] = SPF_TX_LEFT;</div>
<div> Total = DataOffset+2;</div>
<div> NumBytes = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> //if (Error) return Error;<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> //Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  *pLeft = *((WORD *) (RetBuffer+PACKET_HEADER_SIZE+2));<br>  return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));<br>  }<br> else<br>  return HEIE_ZERO_BYTES_RECEIVED;<br> }</div>
<div>/* PLC MEMORY STUFF */<br>__declspec(dllexport) int HEIReadMemory(HEIDevice *pDevice, WORD Type, DWORD Offset, WORD NumBytes, BYTE *pBuffer)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[600];<br> WORD DataOffset = pDevice->DataOffset;<br>
 WORD Total;<br> int Error;<br> int Num;<br> WORD *pWord;<br> DWORD *pDWord;</div>
<div> Buffer[DataOffset] = FUN_READ_MEMORY;<br> Buffer[DataOffset+1] = 0;<br> <br> pWord = (WORD *) &Buffer[DataOffset+2];<br> *pWord++ = Type;<br> *pWord++ = NumBytes;<br> pDWord = (DWORD *) &Buffer[DataOffset+6];<br>
 *pDWord++ = Offset;</div>
<div> Total = DataOffset+10;</div>
<div> Num = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &Num, TRUE, FALSE);</div>
<div> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> //if (Error) <br> // return Error;</div>
<div> if (Num)<br>  {<br>  short int *pError = (short int *) (RetBuffer+PACKET_HEADER_SIZE);<br>  <br>  if (!((*pError) & 0x0FFF) || (*pError == HEIE_LENGTH_WARNING))<br>   {<br>   // Copy the memory.<br>   memcpy(pBuffer, RetBuffer+PACKET_HEADER_SIZE+2, NumBytes);<br>
   }<br>  <br>  return *pError;<br>  }<br> else<br>  return HEIE_ZERO_BYTES_RECEIVED;<br>  <br>/* return 0; */<br> }<br> <br>__declspec(dllexport) int HEIWriteMemory(HEIDevice *pDevice, WORD Type, DWORD Offset, WORD NumBytes, BYTE *pBuffer)<br>
 {<br> BYTE Buffer[600];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br> int Error;<br> int Num;<br> WORD *pWord;<br> DWORD *pDWord;</div>
<div> if (NumBytes > 512)<br>  return HEIE_DATA_TOO_LARGE;</div>
<div> Buffer[DataOffset] = FUN_WRITE_MEMORY;<br> Buffer[DataOffset+1] = 0;<br> <br> pWord = (WORD *) &Buffer[DataOffset+2];<br> *pWord++ = Type;<br> *pWord++ = NumBytes;<br> pDWord = (DWORD *) &Buffer[DataOffset+6];<br>
 *pDWord++ = Offset;<br> <br> memcpy(Buffer+DataOffset+10, pBuffer, NumBytes);</div>
<div> Total = DataOffset+10+NumBytes;</div>
<div> Num = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &Num, TRUE, FALSE);</div>
<div> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;<br> //if (Error) return Error;</div>
<div> if (Num)<br>  return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));<br> else<br>  return HEIE_ZERO_BYTES_RECEIVED;<br>  <br> /* return 0; */<br> }<br> </div>
<div>__declspec(dllexport) int HEIAccessMemory(HEIDevice *pDevice, MemRef MemRefs[], WORD NumRefs)<br> {<br> WORD DataOffset = pDevice->DataOffset;<br> BYTE Buffer[600];<br> BYTE RetBuffer[600];<br> BYTE *pSendData;<br>
 WORD x;<br> WORD *pWord;<br> WORD ReadSize = 2 + 2;     // Returned error value is 2 bytes long<br>           // Returned num MemRefs is 2 bytes long<br> WORD TotalSize = 4 + DataOffset;  // Header info is 4 bytes long<br>
 int Num;<br> int Error;</div>
<div> Buffer[DataOffset] = FUN_ACCESS_MEMORY;<br> Buffer[DataOffset+1] = 0;<br> pWord = (WORD *) &Buffer[DataOffset+2];<br> *pWord = NumRefs;</div>
<div> pSendData = &Buffer[DataOffset+4];</div>
<div> for (x=0; x<NumRefs; x++)<br>  {<br>  memcpy(pSendData, &MemRefs[x], sizeof(MemRefDetail));<br>  TotalSize += sizeof(MemRefDetail);<br>  pSendData += sizeof(MemRefDetail);</div>
<div>  if (MemRefs[x].Detail.Direction == ACCESS_READ)<br>   {<br>   // Read request.<br>   ReadSize += (MemRefs[x].Detail.NumBytes + sizeof(MemRefDetail));<br>   }<br>  else if (MemRefs[x].Detail.Direction == ACCESS_WRITE)<br>
   {<br>   // Write request.<br>   memcpy(pSendData, MemRefs[x].pBuffer, MemRefs[x].Detail.NumBytes);<br>   TotalSize += MemRefs[x].Detail.NumBytes;<br>   pSendData += MemRefs[x].Detail.NumBytes;<br>   }<br>  else<br>   {<br>
   return HEIE_INVALID_REQUEST;<br>   }</div>
<div>  if ((TotalSize > sizeof(Buffer)) || (ReadSize > sizeof(RetBuffer)))<br>   {<br>   return HEIE_DATA_TOO_LARGE;<br>   }<br>  }</div>
<div> // Ready to send.<br> Num = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, TotalSize, RetBuffer, &Num, TRUE, FALSE);</div>
<div> //if (Error) return Error;<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> if (Num)<br>  {<br>  short int *pError = (short int *) (RetBuffer+PACKET_HEADER_SIZE);<br>  short int *pNum = (short int *) (RetBuffer+PACKET_HEADER_SIZE+2);<br>  <br>  //if (!*pError && *pNum)<br>  if (!((*pError) & 0x0FFF) && *pNum)<br>
   {<br>   // No errors, and we have some read requests returned.<br>   WORD x;<br>   MemRefDetail *pReturnDetail = (MemRefDetail *) (RetBuffer+PACKET_HEADER_SIZE+4);</div>
<div>   for (x=0; x<NumRefs; x++)<br>    {<br>    // Find a read request.<br>    if (MemRefs[x].Detail.Direction == ACCESS_READ)<br>     {<br>     // Read request; Make sure it matches.<br>     if (MemRefs[x].Detail.Type  == pReturnDetail->Type && <br>
      MemRefs[x].Detail.Offset == pReturnDetail->Offset &&<br>      MemRefs[x].Detail.NumBytes == pReturnDetail->NumBytes)<br>      {<br>      // Requests match, so copy data.<br>      BYTE *pData = (BYTE *) pReturnDetail;<br>
      pData += sizeof(MemRefDetail);</div>
<div>      memcpy(MemRefs[x].pBuffer, pData, MemRefs[x].Detail.NumBytes);</div>
<div>      // Reset for next one.<br>      pData += MemRefs[x].Detail.NumBytes;<br>      pReturnDetail = (MemRefDetail *) pData;<br>      }<br>     else<br>      {<br>      // Requests don't match, so return error.<br>
      return HEIE_INVALID_RESPONSE;<br>      }<br>     }<br>    }<br>   }<br>  <br>  return *pError;<br>  }<br> else<br>  return HEIE_ZERO_BYTES_RECEIVED;<br> }</div>
<div><br>__declspec(dllexport) int HEIENumMemory(HEIDevice *pDevice, WORD *pSizeofDataInTypes, MemoryTypeDef *pData)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[600];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br>
 int Error;<br> int Retval;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = (BYTE) FUN_ENUM_MEMORY;    /* This is the function code! */</div>
<div> Total = DataOffset+1;</div>
<div> NumBytes = sizeof(RetBuffer);</div>
<div> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> /* Check for error and not warning. */<br> //if (Error)<br> // return Error;<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  /*int NumTypes; */<br>  short int *pInt = (short int *) (RetBuffer+PACKET_HEADER_SIZE);<br>  short int *pNumTypes = (short int *) (RetBuffer+PACKET_HEADER_SIZE+2);</div>
<div>  if ((WORD) *pNumTypes > *pSizeofDataInTypes)<br>   {<br>   Retval = HEIE_BUFFER_TOO_SMALL;<br>   *pNumTypes = *pSizeofDataInTypes;<br>   }</div>
<div>  if (*pInt)<br>   Retval = *pInt;</div>
<div>  (*pSizeofDataInTypes) = *pNumTypes;</div>
<div>  memcpy((char *) pData, (char *) (RetBuffer+PACKET_HEADER_SIZE+4), (*pNumTypes) * sizeof(MemoryTypeDef));<br>  }<br> else<br>  {<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;<br>  }</div>
<div> return Retval;<br> }</div>
<div>//BYTE SharedRamArea = 0;</div>
<div>__declspec(dllexport) int HEIReadSharedRAM(HEIDevice *pDevice, WORD Base, WORD Slot, WORD Address, WORD Bytes2Read, BYTE *pBuffer)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[600];<br> WORD DataOffset = pDevice->DataOffset;<br>
 WORD Total;<br> int Error;<br> int Num;<br> WORD *pWord;<br> BYTE SharedRamArea = 0;</div>
<div> Buffer[DataOffset] = FUN_READ_SHARED_RAM;</div>
<div> if (Address & 0x8000)<br>  {<br>  SharedRamArea = 1;<br>  Address &= 0x7FFF;<br>  }</div>
<div> Buffer[DataOffset+1] = SharedRamArea;<br> <br> pWord = (WORD *) &Buffer[DataOffset+2];<br> *pWord++ = Base;<br> *pWord++ = Slot;<br> *pWord++ = Address;<br> *pWord++ = Bytes2Read;</div>
<div> Total = DataOffset+10;</div>
<div> Num = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &Num, TRUE, FALSE);</div>
<div> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;<br> //if (Error) <br> // return Error;</div>
<div> if (Num)<br>  {<br>  short int *pError = (short int *) (RetBuffer+PACKET_HEADER_SIZE);<br>  <br>  //if (!*pError || (*pError == LENGTH_WARNING))<br>  if (!((*pError) & 0x0FFF) || (*pError == HEIE_LENGTH_WARNING))<br>
   {<br>   // Copy the memory.<br>   memcpy(pBuffer, RetBuffer+PACKET_HEADER_SIZE+2, Bytes2Read);<br>   }<br>  <br>  return *pError;<br>  }<br> else<br>  return HEIE_ZERO_BYTES_RECEIVED;<br>  <br> /* return 0; */<br> }<br>
 </div>
<div>__declspec(dllexport) int HEIWriteSharedRAM(HEIDevice *pDevice, WORD Base, WORD Slot, WORD Address, WORD Bytes2Write, BYTE *pBuffer)<br> {<br> BYTE Buffer[600];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br>
 WORD Total;<br> int Error;<br> int Num;<br> WORD *pWord;<br> BYTE SharedRamArea = 0;</div>
<div> if (Bytes2Write > 256)<br>  return HEIE_DATA_TOO_LARGE;</div>
<div> Buffer[DataOffset] = FUN_WRITE_SHARED_RAM;</div>
<div> if (Address & 0x8000)<br>  {<br>  SharedRamArea = 1;<br>  Address &= 0x7FFF;<br>  }</div>
<div> Buffer[DataOffset+1] = SharedRamArea;<br> <br> pWord = (WORD *) &Buffer[DataOffset+2];<br> *pWord++ = Base;<br> *pWord++ = Slot;<br> *pWord++ = Address;<br> *pWord++ = Bytes2Write;<br> <br> memcpy(Buffer+DataOffset+10, pBuffer, Bytes2Write);</div>

<div> Total = DataOffset+10+Bytes2Write;</div>
<div> Num = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &Num, TRUE, FALSE);</div>
<div> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;<br> //if (Error) return Error;</div>
<div> if (Num)<br>  return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));<br> else<br>  return HEIE_ZERO_BYTES_RECEIVED;<br>  <br> /* return 0; */<br> }</div>
<div><br>/*<br>** Calculate, 16 Bit CRC<br>*/<br>/* number of bits in CRC: don't change it.  */<br>#define W 16</div>
<div>/* this the number of bits per char: don't change it. */<br>#define B 8</div>
<div>static unsigned short crctab[1<<B] = { <br>    0x0000,  0x1021,  0x2042,  0x3063,  0x4084,  0x50a5,  0x60c6,  0x70e7,<br>    0x8108,  0x9129,  0xa14a,  0xb16b,  0xc18c,  0xd1ad,  0xe1ce,  0xf1ef,<br>    0x1231,  0x0210,  0x3273,  0x2252,  0x52b5,  0x4294,  0x72f7,  0x62d6,<br>
    0x9339,  0x8318,  0xb37b,  0xa35a,  0xd3bd,  0xc39c,  0xf3ff,  0xe3de,<br>    0x2462,  0x3443,  0x0420,  0x1401,  0x64e6,  0x74c7,  0x44a4,  0x5485,<br>    0xa56a,  0xb54b,  0x8528,  0x9509,  0xe5ee,  0xf5cf,  0xc5ac,  0xd58d,<br>
    0x3653,  0x2672,  0x1611,  0x0630,  0x76d7,  0x66f6,  0x5695,  0x46b4,<br>    0xb75b,  0xa77a,  0x9719,  0x8738,  0xf7df,  0xe7fe,  0xd79d,  0xc7bc,<br>    0x48c4,  0x58e5,  0x6886,  0x78a7,  0x0840,  0x1861,  0x2802,  0x3823,<br>
    0xc9cc,  0xd9ed,  0xe98e,  0xf9af,  0x8948,  0x9969,  0xa90a,  0xb92b,<br>    0x5af5,  0x4ad4,  0x7ab7,  0x6a96,  0x1a71,  0x0a50,  0x3a33,  0x2a12,<br>    0xdbfd,  0xcbdc,  0xfbbf,  0xeb9e,  0x9b79,  0x8b58,  0xbb3b,  0xab1a,<br>
    0x6ca6,  0x7c87,  0x4ce4,  0x5cc5,  0x2c22,  0x3c03,  0x0c60,  0x1c41,<br>    0xedae,  0xfd8f,  0xcdec,  0xddcd,  0xad2a,  0xbd0b,  0x8d68,  0x9d49,<br>    0x7e97,  0x6eb6,  0x5ed5,  0x4ef4,  0x3e13,  0x2e32,  0x1e51,  0x0e70,<br>
    0xff9f,  0xefbe,  0xdfdd,  0xcffc,  0xbf1b,  0xaf3a,  0x9f59,  0x8f78,<br>    0x9188,  0x81a9,  0xb1ca,  0xa1eb,  0xd10c,  0xc12d,  0xf14e,  0xe16f,<br>    0x1080,  0x00a1,  0x30c2,  0x20e3,  0x5004,  0x4025,  0x7046,  0x6067,<br>
    0x83b9,  0x9398,  0xa3fb,  0xb3da,  0xc33d,  0xd31c,  0xe37f,  0xf35e,<br>    0x02b1,  0x1290,  0x22f3,  0x32d2,  0x4235,  0x5214,  0x6277,  0x7256,<br>    0xb5ea,  0xa5cb,  0x95a8,  0x8589,  0xf56e,  0xe54f,  0xd52c,  0xc50d,<br>
    0x34e2,  0x24c3,  0x14a0,  0x0481,  0x7466,  0x6447,  0x5424,  0x4405,<br>    0xa7db,  0xb7fa,  0x8799,  0x97b8,  0xe75f,  0xf77e,  0xc71d,  0xd73c,<br>    0x26d3,  0x36f2,  0x0691,  0x16b0,  0x6657,  0x7676,  0x4615,  0x5634,<br>
    0xd94c,  0xc96d,  0xf90e,  0xe92f,  0x99c8,  0x89e9,  0xb98a,  0xa9ab,<br>    0x5844,  0x4865,  0x7806,  0x6827,  0x18c0,  0x08e1,  0x3882,  0x28a3,<br>    0xcb7d,  0xdb5c,  0xeb3f,  0xfb1e,  0x8bf9,  0x9bd8,  0xabbb,  0xbb9a,<br>
    0x4a75,  0x5a54,  0x6a37,  0x7a16,  0x0af1,  0x1ad0,  0x2ab3,  0x3a92,<br>    0xfd2e,  0xed0f,  0xdd6c,  0xcd4d,  0xbdaa,  0xad8b,  0x9de8,  0x8dc9,<br>    0x7c26,  0x6c07,  0x5c64,  0x4c45,  0x3ca2,  0x2c83,  0x1ce0,  0x0cc1,<br>
    0xef1f,  0xff3e,  0xcf5d,  0xdf7c,  0xaf9b,  0xbfba,  0x8fd9,  0x9ff8,<br>    0x6e17,  0x7e36,  0x4e55,  0x5e74,  0x2e93,  0x3eb2,  0x0ed1,  0x1ef0<br>    };</div>
<div>WORD CalcCRC(WORD    icrc,<br>            BYTE   *icp,<br>            WORD    icnt)<br> {<br> register WORD crc = icrc;<br> register BYTE *cp = icp;<br> register WORD cnt = icnt;</div>
<div> while( cnt-- )<br>  crc = (crc<<B) ^ crctab[(crc>>(W-B)) ^ *cp++];</div>
<div> return( crc );<br> }</div>
<div> </div>
<div>/*<br>**<br>** WinPLC Specific Functions<br>**<br>*/<br>__declspec(dllexport) int WPLCSetOSLoad(HEIDevice *pDevice, int Val)<br> {<br> BYTE Buffer[100];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br>
 WORD Total;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = FUN_SET_OS_LOAD;<br> Buffer[DataOffset+1] = ~FUN_SET_OS_LOAD;<br> memcpy(&Buffer[DataOffset+2], &Val, sizeof(int));</div>
<div> Total = DataOffset+2+sizeof(int);<br> NumBytes = sizeof(RetBuffer);</div>
<div> return _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);<br> }</div>
<div><br>__declspec(dllexport) int WPLCReboot(HEIDevice *pDevice)<br> {<br> BYTE Buffer[100];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = FUN_REBOOT;<br> Buffer[DataOffset+1] = ~FUN_REBOOT;</div>
<div> Total = DataOffset+2;<br> NumBytes = sizeof(RetBuffer);</div>
<div> return _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);<br> }</div>
<div>__declspec(dllexport) int HEIReboot(HEIDevice *pDevice)<br> {<br> BYTE Buffer[100];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = FUN_REBOOT;<br> Buffer[DataOffset+1] = ~FUN_REBOOT;</div>
<div> Total = DataOffset+2;<br> NumBytes = sizeof(RetBuffer);</div>
<div> return _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);<br> }</div>
<div><br>__declspec(dllexport) int WPLCRunProgram(HEIDevice *pDevice, BYTE *pProgram)<br> {<br> BYTE Buffer[500];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> BYTE *pArgs, *pData;<br> WORD Total;<br>
 int NumBytes;<br> short int *pError;</div>
<div> memset(Buffer, 0, sizeof(Buffer));<br> Buffer[DataOffset] = FUN_RUN_PROGRAM;<br> Buffer[DataOffset+1] = ~FUN_RUN_PROGRAM;</div>
<div> pArgs = pProgram;</div>
<div> if (!*pArgs)<br>  return -1;</div>
<div> // Skip whitespace at front.<br> while (*pArgs == ' ')<br>  pArgs++;</div>
<div> pData = &Buffer[DataOffset+2];</div>
<div> // Copy program name.<br> while (*pArgs && (*pArgs != ' '))<br>  {<br>  *pData++ = *pArgs++;<br>  }</div>
<div> while (isspace(*pArgs))<br>  pArgs++;</div>
<div> strcpy((char *) &Buffer[DataOffset+66], (char *) pArgs);</div>
<div> Total = DataOffset+2+64+strlen((char *) pArgs)+1;</div>
<div> NumBytes = sizeof(RetBuffer);</div>
<div> _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> pError = (short int *) (RetBuffer+PACKET_HEADER_SIZE);</div>
<div> return *pError;<br> }</div>
<div><br>/*<br>**<br>** THIS IS THE MODIFIED SERIAL PORT FUNCTIONS THAT ACCEPT A BYTE FOR THE PORT NUMBER<br>**<br>*/</div>
<div>__declspec(dllexport) int HEIWriteCommEx(HEIDevice *pDevice, BYTE Port, WORD Num2Write, BYTE *pData)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br>
 WORD *pWord;<br> int Error;<br> int NumBytes;</div>
<div> //Port = (Port - 1) << 4;<br> Buffer[DataOffset] = FUN_SERIAL_PORT;<br> Buffer[DataOffset+1] = SPF_WRITE_COMM + 0x80; //Port;<br> Buffer[DataOffset+2] = Port-1;<br> pWord = (WORD *) &Buffer[DataOffset+3];<br>
 *pWord = Num2Write;</div>
<div> if (Num2Write > (sizeof(Buffer) - DataOffset - 5))<br>  return HEIE_DATA_TOO_LARGE;</div>
<div> memcpy(Buffer+DataOffset+5, pData, Num2Write);</div>
<div> Total = DataOffset+5+Num2Write;</div>
<div> NumBytes = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> //if (Error) return Error;<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> if (NumBytes)<br>  return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));<br> else<br>  return HEIE_ZERO_BYTES_RECEIVED;<br> }</div>
<div>__declspec(dllexport) int HEIReadCommEx(HEIDevice *pDevice, BYTE Port, WORD *pNum2Read, BYTE *pData)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];</div>
<div> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br> WORD *pWord;<br> int Error;<br> int Retval;<br> int NumBytes;</div>
<div> //Port = (Port - 1) << 4;<br> Buffer[DataOffset] = FUN_SERIAL_PORT;<br> Buffer[DataOffset+1] = SPF_READ_COMM + 0x80; //Port;<br> Buffer[DataOffset+2] = Port-1;<br> pWord = (WORD *) &Buffer[DataOffset+3];<br>
 *pWord = *pNum2Read;</div>
<div> Total = DataOffset+5;</div>
<div> NumBytes = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> //if (Error) return Error;<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  short int *pInt = (short int *) (RetBuffer+PACKET_HEADER_SIZE);<br>  short int *pNumReturned = (short int *) (RetBuffer+PACKET_HEADER_SIZE+2);</div>
<div>  if (*pInt)<br>   Retval = *pInt;</div>
<div>  (*pNum2Read) = *pNumReturned;</div>
<div>  memcpy(pData, RetBuffer+PACKET_HEADER_SIZE+4, *pNumReturned);<br>  }<br> else<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;</div>
<div> return Retval;<br> }</div>
<div>__declspec(dllexport) int HEIGetRXAvailableEx(HEIDevice *pDevice, BYTE Port, WORD *pAvailable)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br> int Error;<br>
 int NumBytes;</div>
<div> //Port = (Port - 1) << 4;<br> Buffer[DataOffset] = FUN_SERIAL_PORT;<br> Buffer[DataOffset+1] = SPF_RX_AVAILABLE + 0x80; //Port;<br> Buffer[DataOffset+2] = Port-1;</div>
<div> Total = DataOffset+3;</div>
<div> NumBytes = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> //if (Error) return Error;<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> if (NumBytes)<br>  {<br>  *pAvailable = *((WORD *) (RetBuffer+PACKET_HEADER_SIZE+2));<br>  return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));<br>  }<br> else<br>  return HEIE_ZERO_BYTES_RECEIVED;<br> }</div>
<div>__declspec(dllexport) int HEIFlushRXQueueEx(HEIDevice *pDevice, BYTE Port)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br> int Error;<br> int NumBytes;</div>

<div> //Port = (Port - 1) << 4;<br> Buffer[DataOffset] = FUN_SERIAL_PORT;<br> Buffer[DataOffset+1] = SPF_RX_FLUSH + 0x80; //Port;<br> Buffer[DataOffset+2] = Port-1;</div>
<div> Total = DataOffset+3;</div>
<div> NumBytes = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> //if (Error) return Error;<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> if (NumBytes)<br>  return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));<br> else<br>  return HEIE_ZERO_BYTES_RECEIVED;<br> }</div>
<div>__declspec(dllexport) int HEIFlushTXQueueEx(HEIDevice *pDevice, BYTE Port)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br> int Error;<br> int NumBytes;</div>

<div> //Port = (Port - 1) << 4;<br> Buffer[DataOffset] = FUN_SERIAL_PORT;<br> Buffer[DataOffset+1] = SPF_TX_FLUSH + 0x80; //Port;<br> Buffer[DataOffset+2] = Port-1;</div>
<div> Total = DataOffset+3;</div>
<div> NumBytes = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> //if (Error) return Error;<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> if (NumBytes)<br>  return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));<br> else<br>  return HEIE_ZERO_BYTES_RECEIVED;<br> }</div>
<div>__declspec(dllexport) int HEISetupSerialPortEx(HEIDevice *pDevice, BYTE Port, SerialSetup *pSetup, BOOL WriteToFlash)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br>
 WORD Total;<br> int Error;<br> int NumBytes;</div>
<div> //Port = (Port - 1) << 4;<br> Buffer[DataOffset] = FUN_SERIAL_PORT;<br> Buffer[DataOffset+1] = SPF_SETUP + 0x80; //Port;<br> Buffer[DataOffset+2] = Port-1;<br> Buffer[DataOffset+3] = (BYTE) WriteToFlash;<br> Buffer[DataOffset+4] = 0;</div>

<div> memcpy(Buffer+DataOffset+5, pSetup, sizeof(SerialSetup));</div>
<div> Total = DataOffset+5+sizeof(SerialSetup);</div>
<div> NumBytes = sizeof(RetBuffer);</div>
<div> if (WriteToFlash)<br>  {<br>  pDevice->Timeout += EXTRA_TIME_FOR_SETUP_DATA;</div>
<div>  Error = SendPacketTwoResponses(pDevice, Buffer, Total, RetBuffer, &NumBytes, <br>          TRUE, FALSE,<br>          0, NULL, <br>          30000, TRUE, TRUE);</div>
<div>  pDevice->Timeout -= EXTRA_TIME_FOR_SETUP_DATA;<br>  }<br> else<br>  {<br>  Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);<br>  }</div>
<div> //if (Error) <br> // return Error;<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> if (NumBytes)<br>  return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));<br> else<br>  return HEIE_ZERO_BYTES_RECEIVED;<br> }<br> <br>__declspec(dllexport) int HEIReadSerialPortSetupEx(HEIDevice *pDevice, BYTE Port, SerialSetup *pSetup)<br>
 {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br> int Error;<br> int NumBytes;</div>
<div> //Port = (Port - 1) << 4;<br> Buffer[DataOffset] = FUN_SERIAL_PORT;<br> Buffer[DataOffset+1] = SPF_READ_SETUP + 0x80; //Port;<br> Buffer[DataOffset+2] = Port-1;<br> Buffer[DataOffset+3] = 0;<br> Buffer[DataOffset+4] = 0;</div>

<div> Total = DataOffset+5;</div>
<div> NumBytes = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> //if (Error) return Error;<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> if (NumBytes)<br>  {<br>  // Copy data into user buffer.<br>  memcpy(pSetup, RetBuffer+PACKET_HEADER_SIZE, sizeof(SerialSetup));<br>  return 0;<br>  }<br> else<br>  return HEIE_ZERO_BYTES_RECEIVED;<br> }<br> </div>

<div>__declspec(dllexport) int HEIGetTXLeftEx(HEIDevice *pDevice, BYTE Port, WORD *pLeft)<br> {<br> BYTE Buffer[200];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD Total;<br> int Error;<br>
 //int Retval;<br> int NumBytes;</div>
<div> //Port = (Port - 1) << 4;<br> Buffer[DataOffset] = FUN_SERIAL_PORT;<br> Buffer[DataOffset+1] = SPF_TX_LEFT + 0x80; //Port;<br> Buffer[DataOffset+2] = Port-1;</div>
<div> Total = DataOffset+3;</div>
<div> NumBytes = sizeof(RetBuffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE, FALSE);</div>
<div> //if (Error) return Error;<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> //Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  *pLeft = *((WORD *) (RetBuffer+PACKET_HEADER_SIZE+2));<br>  return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));<br>  }<br> else<br>  return HEIE_ZERO_BYTES_RECEIVED;<br> }</div>
<div>__declspec(dllexport) int HEIAccessComm(HEIDevice *pDevice, WORD SendDataSize, BYTE *pSendData, WORD *pReturnDataSize, BYTE *pReturnData)<br> {<br> BYTE Buffer[1500];<br> WORD DataOffset = pDevice->DataOffset;<br>
 WORD Total;<br> WORD *pWord;<br> int Error;<br> int NumBytes;<br> int Retval;</div>
<div> Buffer[DataOffset] = FUN_SERIAL_PORT;<br> Buffer[DataOffset+1] = SPF_ACCESS_COMM;<br> pWord = (WORD *) &Buffer[DataOffset+2];<br> *pWord = SendDataSize;</div>
<div> if (SendDataSize > (sizeof(Buffer) - DataOffset - 4))<br>  return HEIE_DATA_TOO_LARGE;</div>
<div> memcpy(Buffer+DataOffset+4, pSendData, SendDataSize);</div>
<div> Total = DataOffset+4+SendDataSize;</div>
<div> NumBytes = sizeof(Buffer);<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, Buffer, &NumBytes, TRUE, FALSE);</div>
<div> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  short int *pInt = (short int *) (Buffer+PACKET_HEADER_SIZE);<br>  short int *pNumReturned = (short int *) (Buffer+PACKET_HEADER_SIZE+2);</div>
<div>  if (*pInt)<br>   Retval = *pInt;</div>
<div>  if (pReturnData && pReturnDataSize)<br>   {<br>   if (*pNumReturned > *pReturnDataSize)<br>    {<br>    Retval = HEIE_BUFFER_TOO_SMALL;<br>    }<br>   else<br>    {<br>    (*pReturnDataSize) = *pNumReturned;<br>
    }</div>
<div>   memcpy(pReturnData, Buffer+PACKET_HEADER_SIZE+4, *pReturnDataSize);<br>   }<br>  }<br> else<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;</div>
<div> return Retval;<br> }</div>
<div><br>__declspec(dllexport) int HEIWriteEZethernetPgmSpace(HEIDevice *pDevice, BYTE *pData, WORD SizeofData)<br> {<br> BYTE Buffer[600];<br> BYTE RetBuffer[200];<br> WORD DataOffset = pDevice->DataOffset;<br> WORD *pWord;<br>
 WORD Total;<br> int Error;<br> int Retval;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = (BYTE)FUN_USER_CONFIG_PANEL; /* This is the function code! */<br> Buffer[DataOffset+1] = 0;</div>
<div> pWord = (WORD *) &Buffer[DataOffset+2];</div>
<div> Total = DataOffset+4+SizeofData;</div>
<div> // FYI: Incoming size should never be greater than 316 bytes.<br> //      60 bytes control + 255 Max AVG packet size + 1 byte for <br> //      the start character. <br> if (Total > sizeof(Buffer) || SizeofData > 316)<br>
  return HEIE_DATA_TOO_LARGE;</div>
<div> (void)memcpy(&Buffer[DataOffset+4], pData, SizeofData);</div>
<div> NumBytes = sizeof(RetBuffer);<br>  <br> pDevice->Timeout += EXTRA_TIME_FOR_SETUP_DATA;</div>
<div> Error = SendPacketTwoResponses(pDevice, Buffer, Total, RetBuffer, &NumBytes, <br>         TRUE, FALSE,<br>         0, NULL, <br>         30000, TRUE, TRUE);</div>
<div> pDevice->Timeout -= EXTRA_TIME_FOR_SETUP_DATA;</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  short int *pInt = (short int *) (RetBuffer+PACKET_HEADER_SIZE);</div>
<div>  if (*pInt)<br>   Retval = *pInt;<br>  }<br> else<br>  {<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;<br>  }</div>
<div> return Retval;<br> }</div>
<div><br>/*<br>** ERM Functions.<br>*/<br>#define FUN_COMMAND  6<br>#define FUN_READ_DATA 7 <br>#define FUN_WRITE_DATA 8</div>
<div>#define FUN_STATUS_INWORK 1<br>#define FUN_STATUS_DONE  2<br>#define FUN_STATUS_ERROR 3</div>
<div>__declspec(dllexport) int HEIWriteERMData(HEIDevice *pDevice, WORD Base, WORD Slot, BYTE DataType, BYTE *pData, WORD NumBytes, WORD Offset)<br> {<br> WORD Data[6];<br> WORD *pOffset;<br> WORD *pExtended;<br> WORD *pNumBytes;<br>
 int Index = 0;</div>
<div> // Common header<br> Data[Index++] = 0;      // Function + Status (ClearFunction until all other data is written)<br> Data[Index++] = 0;      // Error </div>
<div> // Function specific header<br> Data[Index++] = DataType;    // Data type <br> pOffset = (WORD *) &Data[Index++]; // Pointer to Offset<br> pNumBytes = (WORD *) &Data[Index++];// Pointer to num bytes<br> pExtended = (WORD *) &Data[Index++]; // Pointer to extended</div>

<div> *pOffset = Offset;<br> *pNumBytes = 256;<br> *pExtended = 0;</div>
<div><br> while (NumBytes)<br>  {<br>  int Error;</div>
<div>  //memcpy(&Data[11], pOutputData, *pNumBytes);<br>  if (*pNumBytes > NumBytes)<br>   *pNumBytes = NumBytes;</div>
<div>  Data[0] = 0;<br>  Data[1] = 0;</div>
<div>  // Write Header first.<br>  Error = HEIWriteSharedRAM(pDevice, Base, Slot, 0x30 + 0x8000, sizeof(Data), (BYTE *) Data);</div>
<div>  if (Error)<br>   {<br>   //printf("\nError %d (0x%X) from HEIWriteSharedRAM", Error, Error);<br>   return Error;<br>   }</div>
<div>  // Next write data.<br>  Error = HEIWriteSharedRAM(pDevice, Base, Slot, 0x30+sizeof(Data) + 0x8000, *pNumBytes, pData);</div>
<div>  if (Error)<br>   {<br>   //printf("\nError %d (0x%X) from HEIWriteSharedRAM", Error, Error);<br>   return Error;<br>   }</div>
<div>  // Now write the REAL command.<br>  Data[0] = FUN_WRITE_DATA;</div>
<div>  Error = HEIWriteSharedRAM(pDevice, Base, Slot, 0x30+ 0x8000, 1, (BYTE *) Data);</div>
<div>  if (Error)<br>   {<br>   //printf("\nError %d (0x%X) from HEIWriteSharedRAM", Error, Error);<br>   return Error;<br>   }<br>  else<br>   {<br>   // Wait for it to complete.<br>   DWORD StartTime = HEIIGetCounter();<br>
   BOOL Done = FALSE;</div>
<div>   do<br>    {<br>    BYTE bData[4];<br>    Error = HEIReadSharedRAM(pDevice, Base, Slot, 0x30+ 0x8000, 4, (BYTE *) bData);</div>
<div>    if (Error)<br>     {<br>     //printf("\nError %d (0x%X) from HEIReadSharedRAM", Error, Error);<br>     return Error;<br>     }<br>    else<br>     {<br>     if ((bData[1] & 0xFF) == FUN_STATUS_DONE)<br>
      {<br>      Done = TRUE;<br>      }<br>     else if ((bData[1] & 0xFF) == FUN_STATUS_ERROR)<br>      {<br>      return bData[2];  // Return Error<br>      }<br>     }<br>    } while (!Done && TimeDiff(StartTime, HEIIGetCounter()) < pDevice->Timeout);</div>

<div>   if (!Done)<br>    {<br>    //printf("\nTimeout waiting for request to complete.");<br>    return HEIE_TIMEOUT;<br>    }<br>   }</div>
<div>  pData += *pNumBytes;<br>  (*pOffset) += *pNumBytes;<br>  NumBytes -= *pNumBytes;<br>  }</div>
<div>#if 0<br> if ((DataType == DATA_OUTPUT) && (Flags & 0x01))<br>  {<br>  return WPLCDoERMCommand(Base, Slot, COMMAND_PROCESS_IO, 0, 0);<br>  }<br>#endif</div>
<div> return 0;<br> }</div>
<div>__declspec(dllexport) int HEIReadERMData(HEIDevice *pDevice, WORD Base, WORD Slot, BYTE DataType, BYTE *pData, WORD NumBytes, WORD Offset)<br> {<br> WORD Data[6];<br> WORD *pOffset;<br> WORD *pNumBytes;<br> WORD *pExtended;<br>
 int Index = 0;</div>
<div> // Common header<br> Data[Index++] = 0;      // Function + Status (ClearFunction until all other data is written)<br> Data[Index++] = 0;      // Error </div>
<div> // Function specific header<br> Data[Index++] = DataType;    // Data type <br> pOffset = (WORD *) &Data[Index++]; // Pointer to Offset<br> pNumBytes = (WORD *) &Data[Index++];// Pointer to num bytes<br> pExtended = (WORD *) &Data[Index++]; // Pointer to extended</div>

<div> *pOffset = Offset;  <br> *pNumBytes = 256;<br> *pExtended = 0;</div>
<div> //RETAILMSG(1, (TEXT("\r\nWPLCReadERMData Base: %d Slot: %d  Type: %d  Num: %d"), Base, Slot, DataType, NumBytes));</div>
<div> while (NumBytes)<br>  {<br>  int Error;</div>
<div>  Data[0] = 0;<br>  Data[1] = 0;</div>
<div>  if (*pNumBytes > NumBytes)<br>   {<br>   *pNumBytes = NumBytes;<br>   }</div>
<div>  Error = HEIWriteSharedRAM(pDevice, Base, Slot, 0x30+0x8000, sizeof(Data), (BYTE *) Data);</div>
<div>  if (Error)<br>   {<br>   //printf("\nError %d (0x%X) from HEIWriteSharedRAM", Error, Error);<br>   return Error;<br>   }</div>
<div>  // Now write the REAL command.<br>  Data[0] = FUN_READ_DATA;</div>
<div>  Error = HEIWriteSharedRAM(pDevice, Base, Slot, 0x30+0x8000, 2, (BYTE *) Data);</div>
<div>  if (Error)<br>   {<br>   //printf("\nError %d (0x%X) from HEIWriteSharedRAM", Error, Error);<br>   return Error;<br>   }<br>  else<br>   {<br>   // Wait for it to complete.<br>   DWORD StartTime = HEIIGetCounter();<br>
   BOOL Done = FALSE;</div>
<div>   do <br>    {<br>    BYTE bData[4];</div>
<div>    Error = HEIReadSharedRAM(pDevice, Base, Slot, 0x30+0x8000, 4, bData);</div>
<div>    if (Error)<br>     {<br>     //printf("\nError %d (0x%X) from HEIReadSharedRAM", Error, Error);<br>     return Error;<br>     }<br>    else<br>     {<br>   //RETAILMSG(1, (TEXT("\r\nbData: 0x%X 0x%X 0x%X 0x%X"), bData[0], bData[1], bData[2], bData[3]));</div>

<div>     //if (((Data[0]>>8) & 0xFF) == FUN_STATUS_DONE)<br>     if (bData[1] == FUN_STATUS_DONE)<br>      {<br>      // Read the rest of the data.<br>      Error = HEIReadSharedRAM(pDevice, Base, Slot, 0x30+sizeof(Data)+0x8000, *pNumBytes, pData);</div>

<div>      if (Error)<br>       {<br>       //printf("\nError %d (0x%X) from HEIReadSharedRAM", Error, Error);<br>       return Error;<br>       }</div>
<div>      Done = TRUE;<br>      }<br>     //else if (((Data[0]>>8) & 0xFF) == FUN_STATUS_ERROR)<br>     else if (bData[1] == FUN_STATUS_ERROR)<br>      {<br>      return Data[2];<br>     // memcpy(pInputData, &Data[11], *pNumBytes);<br>
      }<br>     }<br>    } while (!Done && TimeDiff(StartTime, HEIIGetCounter()) < pDevice->Timeout);</div>
<div>   if (!Done)<br>    {<br>    //printf("\nTimeout waiting for request to complete.");<br>    return HEIE_TIMEOUT;<br>    }<br>   }</div>
<div>  pData += *pNumBytes;<br>  (*pOffset) += *pNumBytes;<br>  NumBytes -= *pNumBytes;<br>  }</div>
<div> return 0;<br> }</div>
<div>__declspec(dllexport) int HEIDoERMCommand(HEIDevice *pDevice, WORD Base, WORD Slot, WORD Command)<br> {<br> DWORD StartTime;<br> WORD Data[3];<br> int Index = 0;<br> int Error;</div>
<div> // Common header<br> Data[Index++] = 0; // Command and Status (Set Command to zero until rest of data is written)<br> Data[Index++] = 0;      // Error<br> <br> // Function specific header<br> Data[Index++] = Command;</div>

<div> Error = HEIWriteSharedRAM(pDevice, Base, Slot, 0x30 + 0x8000, sizeof(Data), (BYTE *) Data);</div>
<div> if (Error)<br>  {<br>  //printf("\nError %d (0x%X) from HEIWriteSharedRAM", Error, Error);<br>  return Error;<br>  }</div>
<div> // Now write the REAL command.<br> Data[0] = FUN_COMMAND;</div>
<div> Error = HEIWriteSharedRAM(pDevice, Base, Slot, 0x30+0x8000, 2, (BYTE *) Data);</div>
<div> if (Error)<br>  {<br>  //printf("\nError %d (0x%X) from HEIWriteSharedRAM", Error, Error);<br>  return Error;<br>  }</div>
<div>  // Wait for it to complete.<br> StartTime = HEIIGetCounter();</div>
<div> while (TimeDiff(StartTime, HEIIGetCounter()) < pDevice->Timeout)<br>  {<br>  BYTE bData[4];<br>  Error = HEIReadSharedRAM(pDevice, Base, Slot, 0x30+0x8000, 4, (BYTE *) bData);</div>
<div>  if (!Error)<br>   {<br>   if ((bData[1] & 0xFF) == FUN_STATUS_DONE)<br>    return 0;<br>   else if ((bData[1] & 0xFF) == FUN_STATUS_ERROR)<br>    return bData[2];<br>   }<br>  }</div>
<div> return HEIE_TIMEOUT;<br> }</div>
<div><br>__declspec(dllexport) int HEIDoERMCommandEx(HEIDevice *pDevice, WORD Base, WORD Slot, WORD Command, BYTE *pExtra, WORD ExtraLen)<br> {<br> DWORD StartTime;<br> BYTE Data[300];<br> int Index = 0;<br> int Error;<br>
 WORD *pCommand;<br> BOOL Done;</div>
<div> // Common header<br> Data[Index++] = 0; // Command and Status (Set Command to zero until rest of data is written)<br> Data[Index++] = 0;      // Error<br> Data[Index++] = 0; // Command and Status (Set Command to zero until rest of data is written)<br>
 Data[Index++] = 0;      // Error<br> <br> // Function specific header<br> pCommand = (WORD *) &Data[Index];<br> *pCommand = Command;<br> Index += 2;</div>
<div> memcpy(&Data[Index], pExtra, ExtraLen);</div>
<div> Error = HEIWriteSharedRAM(pDevice, Base, Slot, 0x30 + 0x8000,  (WORD)(ExtraLen + 6), Data);</div>
<div> if (Error)<br>  {<br>  //printf("\nError %d (0x%X) from HEIWriteSharedRAM", Error, Error);<br>  return Error;<br>  }</div>
<div> // Now write the REAL command.<br> Data[0] = FUN_COMMAND;<br> Data[1] = 0;</div>
<div> Error = HEIWriteSharedRAM(pDevice, Base, Slot, 0x30+0x8000, 2, (BYTE *) Data);</div>
<div> if (Error)<br>  {<br>  //printf("\nError %d (0x%X) from HEIWriteSharedRAM", Error, Error);<br>  return Error;<br>  }</div>
<div>  // Wait for it to complete.<br> Done = FALSE;<br> StartTime = HEIIGetCounter();</div>
<div> do<br>  {<br>  BYTE bData[4];<br>  Error = HEIReadSharedRAM(pDevice, Base, Slot, 0x30+0x8000, 4, bData);</div>
<div>  if (!Error)<br>   {<br>   if (bData[1] == FUN_STATUS_DONE)<br>    Done = TRUE;<br>   else if (bData[1] == FUN_STATUS_ERROR)<br>    return (int) (((WORD) bData[2]) + (((WORD) bData[3]) << 8));<br>   }<br>  } while (!Done && TimeDiff(StartTime, HEIIGetCounter()) < pDevice->Timeout);</div>

<div> if (!Done)<br>  return HEIE_TIMEOUT;</div>
<div> return 0;<br> }</div>
<div><br>NODELIST *EZGetNodeList(unsigned short int *TotalEZ)<br>{</div>
<div>    static NODELIST EZList[200];  <br>    static HEIDevice HEIDevices[100];<br>    static HEITransport   TP;<br>    unsigned short int i, j;   // Index variables <br>    int Error, MaxDevices, MaxEZDevices;     </div>

<div>    WORD  Timeout   = 100;<br>    WORD  Retrys    = 2;    <br>    WORD  SizeofData;<br>    BOOL  Broadcast = FALSE; <br>    BYTE  Data[500]; <br> BYTE *pData = Data;<br>    DeviceDef dd;<br>  WORD NumDevices;</div>
<div>    HEITransport *tp = &TP;    <br>    ENetAddress  *pSourceAddress = (ENetAddress *)NULL;    </div>
<div> tp->Transport = HEIT_WINSOCK;  <br>    tp->Protocol  = HEIP_IPX;</div>
<div>    *TotalEZ = 0;   // Set to zero until proven otherwise.</div>
<div> Error = HEIOpenTransport(tp, HEIAPIVERSION, pSourceAddress); <br>    if (Error)<br> {<br>        //printf("Error returned from HEIOpenTransport()\n");  <br>        return (NODELIST *)NULL;      <br> }</div>

<div>    MaxDevices   = sizeof(HEIDevices) / sizeof(HEIDevice);    <br>    MaxEZDevices = sizeof(EZList)     / sizeof(NODELIST);<br> NumDevices = MaxEZDevices;</div>
<div> Error = HEIQueryDevices(tp, HEIDevices, &NumDevices, HEIAPIVERSION);<br> if (Error)<br> {<br>        //printf("Error returned from HEIQueryDevices()\n");  <br>        (void)HEIClose();<br>        return (NODELIST *)NULL;<br>
 }<br>           <br>    j = 0;<br>    for (i = 0; i < NumDevices; i++)<br>    { <br>        if (i > MaxDevices)<br>        {<br>            goto ReturnIncompleteList; <br>        }</div>
<div>        Error = HEIOpenDevice(tp, &HEIDevices[i], HEIAPIVERSION, Timeout, Retrys, Broadcast);<br>        if (Error)<br>        {<br>            //printf("IsDeviceEZEthernet: Error %d returned from HEIOpenDevice\n", Error);<br>
            return (NODELIST *)NULL;<br>        } </div>
<div>     Error = HEIReadDeviceDef(&HEIDevices[i], (BYTE *) &dd, sizeof(dd));<br>        if (Error)<br>        {        <br>            //printf("IsDeviceEZEthernet: Error returned from HEIReadDeviceDef\n");<br>
            goto ErrorHandler;<br>        }</div>
<div>        if (dd.ModuleType == MT_AVG_DISP)<br>        {<br>            if (j >= MaxEZDevices)<br>                goto ErrorHandler;</div>
<div>            SizeofData = sizeof(WORD);<br>            Error = HEIReadSetupData( &HEIDevices[i], DT_NODE_NUMBER, pData, &SizeofData);<br>      if (Error)<br>      {<br>                //printf("Error %d returned from HEIReadSetupData1\n", Error);<br>
                goto ErrorHandler;<br>            }<br>      else<br>            { <br>                 (void)memcpy(EZList[j].Node_ID, pData, sizeof(WORD));<br>      }  </div>
<div>            // Get the Node Name <br>      SizeofData = sizeof(EZList[0].Name);<br>            Error = HEIReadSetupData(&HEIDevices[i], DT_NODE_NAME, pData, &SizeofData); <br>      if (Error)<br>      {                    <br>
                //printf("Error returned from HEIReadSetupData2\n");           <br>                goto ErrorHandler;<br>            }<br>            else<br>            {<br>             (void)memcpy(EZList[j].Name, pData, SizeofData);<br>
            }</div>
<div>            EZList[j].pDevice = &HEIDevices[i];<br>            j++;<br>        }<br>        else<br>        {<br>            // Close the device since it is not an EZ_Ethernet.<br>            (void)HEICloseDevice(&HEIDevices[i]);<br>
        }</div>
<div>    }   // End of for</div>
<div><br>    if (j == 0)<br>    {<br>        goto ErrorHandler;<br>    }<br>    else<br>    {    <br>        (void)HEIClose();<br>        *TotalEZ = j;<br>        return EZList;<br>    }<br>    <br>    ReturnIncompleteList: <br>
        // If we have process the maximum number of devices we can<br>        // do, return a list of what we got.       <br>        (void)HEIClose();        <br>        *TotalEZ = j;<br>     return EZList;</div>
<div>    ErrorHandler:               <br>        (void)HEICloseDevice(&HEIDevices[i]);<br>        (void)HEIClose();<br>     return (NODELIST *)NULL;</div>
<div>}</div>
<div><br>BOOL EZSendPacket(HEIDevice *pDevice, PGM_BUF *pBuffer, BYTE *Error_message, unsigned short int Len)<br>{</div>
<div>    int Error;</div>
<div>#if TC_DEBUG<br>    int i;</div>
<div>    printf("EZSendPacket: Incoming buffer has:\n");<br>    for (i = 0; i < Len; i++)<br>        printf("%c", pBuffer->PgmData[i]);<br>    printf("\n");<br>#endif</div>
<div>    Error = HEIWriteEZethernetPgmSpace(pDevice, (BYTE *)pBuffer->PgmData, Len );</div>
<div> switch (Error)<br>    {<br>        case HEIE_DATA_TOO_LARGE:<br>        {<br>            (void)memcpy(&Error_message, "Message size too large", 81);<br>            return FALSE;<br>        }<br>       <br>
        case HEIE_ZERO_BYTES_RECEIVED:<br>        {<br>            (void)memcpy(&Error_message, "Attempted to send zero-length message", 81);<br>             return FALSE;<br>        }</div>
<div>        case -1:<br>        {<br>            // printf("Error %X returned from  HEIWriteEZethernetPgmSpace!\n", Error);<br>             (void)memcpy(&Error_message, "HEIWriteEZethernetPgmSpace call failed with -1", 81);        <br>
             return FALSE;<br>        }</div>
<div>        case NO_ERROR:<br>        {             <br>              //printf("Successfull send from HEIWriteEZethernetPgmSpace\n");<br>              Error_message[0] = '\0';<br>              return TRUE;<br>
        }</div>
<div>            <br>        default:<br>        {<br>             //printf("Error %X returned from  HEIWriteEZethernetPgmSpace!\n", Error);<br>             (void)memcpy(&Error_message, "HEIWriteEZethernetPgmSpace call failed with unknown error", 81);        <br>
             return FALSE;<br>        }</div>
<div>    }</div>
<div> return TRUE;<br>}</div>
<div> </div>
<div>int WPLCWriteERMData(HEIDevice *pDevice, WORD Base, WORD Slot, BYTE DataType, BYTE *pData, WORD NumBytes, WORD Offset)<br> {<br> return HEIWriteERMData(pDevice, Base, Slot, DataType, pData, NumBytes, Offset);<br> }</div>

<div>int WPLCReadERMData(HEIDevice *pDevice, WORD Base, WORD Slot, BYTE DataType, BYTE *pData, WORD NumBytes, WORD Offset)<br> {<br> return HEIReadERMData(pDevice, Base, Slot, DataType, pData, NumBytes, Offset);<br> }</div>

<div>int WPLCDoERMCommand(HEIDevice *pDevice, WORD Base, WORD Slot, WORD Command)<br> {<br> return HEIDoERMCommand(pDevice, Base, Slot, Command);<br> }</div>
<div>int WPLCDoERMCommandEx(HEIDevice *pDevice, WORD Base, WORD Slot, WORD Command, BYTE *pExtra, WORD ExtraLen)<br> {<br> return HEIDoERMCommandEx(pDevice, Base, Slot, Command, pExtra, ExtraLen);<br> }</div>
<div><br>__declspec(dllexport) int SetCRCMode(int Mode)<br> {<br> int Old = DoCRC;</div>
<div> DoCRC = Mode;</div>
<div> return Old;<br> }</div>
<div><br>/* CONFIG DATA ACCESS */<br>__declspec(dllexport) int HEIReadConfigData(HEIDevice *pDevice, BYTE *pData, WORD *DataSize)<br> {<br> BYTE Buffer[100];<br> BYTE RetBuffer[1200];<br> WORD DataOffset = pDevice->DataOffset;<br>
 WORD Total;<br> int Error;<br> int Retval;<br> int NumBytes;<br> <br> Buffer[DataOffset] = FUN_READ_CONFIG_DATA; /* This is the function code! */</div>
<div> Total = DataOffset+1;</div>
<div> if (pData && *pData == 0xB1)<br>  {<br>  Buffer[DataOffset+1] = *pData;<br>  Total++;<br>  }</div>
<div> NumBytes = sizeof(RetBuffer);</div>
<div> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, (pDevice->ParallelPackets) ? FALSE : TRUE, TRUE);</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  short int *pInt = (short int *) &RetBuffer[PACKET_HEADER_SIZE];</div>
<div>  NumBytes -= PACKET_HEADER_SIZE;<br>  NumBytes -= 2;</div>
<div>  if ((WORD) NumBytes > *DataSize)<br>   {<br>   Retval = HEIE_BUFFER_TOO_SMALL;<br>   NumBytes = *DataSize;<br>   }</div>
<div>  if (*pInt)<br>   Retval = (*pInt) | 0x8000;</div>
<div>  memcpy(pData, RetBuffer+PACKET_HEADER_SIZE+2, NumBytes);<br>  (*DataSize) = NumBytes;<br>  }<br> else<br>  {<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;<br>  (*DataSize) = 0;<br>  }</div>
<div> return Retval;<br> }</div>
<div><br>__declspec(dllexport) int HEIWriteConfigData(HEIDevice *pDevice, BYTE *pData, WORD SizeofData, BYTE *pReturnData, WORD *pSizeofReturnData)<br> {<br> BYTE Buffer[1200];<br> BYTE RetBuffer[1200];<br> WORD DataOffset = pDevice->DataOffset;<br>
 WORD Total;<br> int Error;<br> int Retval;<br> int NumBytes;</div>
<div> Buffer[DataOffset] = FUN_WRITE_CONFIG_DATA;    /* This is the function code! */<br> <br> Total = DataOffset+1+SizeofData;</div>
<div> if (Total > sizeof(Buffer))<br>  return HEIE_DATA_TOO_LARGE;</div>
<div> memcpy(Buffer+DataOffset+1, pData, SizeofData);</div>
<div> NumBytes = sizeof(RetBuffer);<br> //NumBytes = *pSizeofReturnData;<br>  <br> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, (pDevice->ParallelPackets) ? FALSE : TRUE, TRUE);</div>
<div> /* Check for error and not warning. */<br> if (Error && !(Error & HEIW_FIRST_WARNING))<br>  return Error;</div>
<div> Retval = Error;</div>
<div> if (NumBytes)<br>  {<br>  short int *pInt = (short int *) &RetBuffer[PACKET_HEADER_SIZE];</div>
<div>  if (pReturnData && pSizeofReturnData)<br>   {<br>   NumBytes -= PACKET_HEADER_SIZE;<br>   NumBytes -= 2;</div>
<div>   if ((WORD) NumBytes > *pSizeofReturnData)<br>    {<br>    Retval = HEIE_BUFFER_TOO_SMALL;<br>    NumBytes = *pSizeofReturnData;<br>    }</div>
<div>   memcpy(pReturnData, RetBuffer+PACKET_HEADER_SIZE+2, NumBytes);<br>   (*pSizeofReturnData) = NumBytes;<br>   }</div>
<div>  if (*pInt)<br>   Retval = (*pInt) | 0x8000;<br>  }<br> else<br>  {<br>  Retval = HEIE_ZERO_BYTES_RECEIVED;</div>
<div>  if (pSizeofReturnData)<br>   (*pSizeofReturnData) = 0;<br>  }</div>
<div> return Retval;<br> }</div>
<div> </div>
<div>/* <br>**<br>**  HOST ETHERNET INTERFACE (HEI) - HEADER FILE<br>** <br>** Copyright 1996-2001 - Host Automation Products, Inc.<br>*<br>*/<br>#if !defined(__HEI_H)<br>#define __HEI_H</div>
<div><br>/* Force structure alignment on single byte boundary */<br>#pragma pack(1)</div>
<div>#if !defined(P_ERMA) & !defined(P_ECOM)  & !defined(EBC) & !defined(P_ERMA) & !defined(BOOTER) & !defined(PROFIBUS)<br>typedef struct <br> {<br> unsigned IgnoreUserMain : 1;<br> unsigned IgnoreVbUserMain : 1;<br>
 unsigned IgnoreDebugMsg : 1;<br> unsigned UnusedBits : 29;<br> BYTE UnusedBytes[28];<br> } StartupSettings;<br>#endif</div>
<div>typedef struct<br> {<br> WORD SizeofEthernetStats;<br> DWORD MissedFrameCount;<br> DWORD TransmitCollisionCount;<br> DWORD DiscardedPackets;<br> DWORD BadCRCCount;                             <br> <br> DWORD UnknownTypeCount;<br>
 DWORD SendErrorCount;<br> } EthernetStats;     </div>
<div>typedef struct<br> {<br> BYTE Version;<br> BYTE Bytes2Follow;<br> <br>#if defined (ANSI_C)<br> BYTE UnusedBytess[16];       /* Support Info */<br>#else <br> BYTE SUP_FUN_POLLING     : 1;   /* Polling one base */<br>
 BYTE SUP_FUN_READ_VER_INFO   : 1;    /* Version Info */<br> BYTE SUP_FUN_READ_SUPPORT_INFO  : 1;   /* Support Info */<br> BYTE SUP_FUN_READ_DEVICE_INFO  : 1;   /* Device Info  */<br> BYTE SUP_FUN_POLLING_ALL   : 1;    /* Polling all bases (returns ethernet address) */<br>
 BYTE SUP_FUN_WRITE_IO    : 1;   /* Write IO base */<br> BYTE SUP_FUN_READ_IO    : 1;   /* Read IO Base */<br> BYTE SUP_FUN_READ_BASE_DEF   : 1;    /* ReadBaseDef */<br> <br> BYTE SUP_FUN_ENUM_SETUP_DATA  : 1;   /* Enumerate setup data */<br>
 BYTE SUP_FUN_READ_SETUP_DATA     : 1;   /* Read setup data */<br> BYTE SUP_FUN_WRITE_SETUP_DATA  : 1;   /* Write setup data */<br> BYTE SUP_FUN_DELETE_SETUP_DATA  : 1;    /* Delete setup data */<br> BYTE SUP_FUN_READ_ETHERNET_STATS : 1;    /* Read ethernet statistics */<br>
 BYTE SUP_FUN_PET_LINK    : 1;    /* Used to keep the link sense timer from firing in the absense of ReadIO or WriteIO messages */<br> BYTE SUP_FUN_ADDRESSED_BROADCAST : 1;    /* Used to broadcast to a particular ethernet address. */<br>
 BYTE SUP_FUN_READ_MODULE_STATUS  : 1;   /* Read module status short BYTEs */<br> <br> BYTE SUP_FUN_EXTENDED    : 1;   /* Extended function */<br> BYTE SUP_FUN_QUERY_SETUP_DATA  : 1;   /* Query for particular data type/value */<br>
 BYTE SUP_FUN_INIT_BASE_DEF    : 1;   /* Initialize base def from backplane. */<br> BYTE SUP_FUN_DATA_BROADCAST   : 1;   /* Broadcast to a particular data type */<br> BYTE SUP_FUN_CCM_REQUEST   : 1;   /* Perform CCM Request */<br>
 BYTE SUP_FUN_KSEQ_REQUEST   : 1;   /* Perform KSEQ Request */<br> BYTE SUP_FUN_BACKPLANE_REQUEST  : 1;   /* Perform backplane request */<br> BYTE SUP_FUN_WRITE_BASE_DEF   : 1;   /* Write Base Def */<br> <br> BYTE SUP_FUN_EXTEND_RESPONSE  : 1;   /* Extends the response packet. */<br>
 BYTE SUP_FUN_ACK     : 1;   /* Acknowledge */<br> BYTE SUP_FUN_NAK     : 1;   /* NOT Acknowledge */<br> BYTE SUP_FUN_RESPONSE     : 1;   /* Response */<br> BYTE SUP_FUN_SERIAL_PORT   : 1;   /* Execute serial port function (see below) */<br>
 BYTE SUP_FUN_WRITE_MEMORY   : 1;   /* Write a particular memory type */<br> BYTE SUP_FUN_READ_MEMORY   : 1;   /* Read a particular memory type */<br> BYTE SUP_FUN_ENUM_MEMORY   : 1;   /* Get list of all memory types */</div>

<div> BYTE SUP_FUN_READ_SHARED_RAM  : 1;   /* Read shared ram */<br> BYTE SUP_FUN_WRITE_SHARED_RAM  : 1;   /* Write shared ram */<br> BYTE SUP_FUN_ACCESS_MEMORY   : 1;   /* Access (read/write) multiple memory types */<br>
 BYTE SUP_FUN_COMM_RESPONSE   : 1;   /* Response to PLC generated COMM request */<br> BYTE SUP_FUN_COMM_REQ_ACK   : 1;   /* Function from PLC generated COMM request */<br> BYTE SUP_FUN_WRITE_IO_NO_READ  : 1;   /* Write IO base with returned read */<br>
 BYTE SUP_FUN_COMM_NO_REQ_ACK  : 1;  /* Function from PLC generated COMM request */<br> BYTE SUP_FUN_RUN_PROGRAM   : 1;   /* Function to execute a program */</div>
<div> BYTE SUP_FUN_REMOTE_API    : 1;  /* Function to execute a function on remote device */<br> BYTE SUP_FUN_NOTIFY     : 1;  /* Indicates a notification */<br> BYTE SUP_FUN_COMPLETION    : 1;  /* Indicates completion of some activity */<br>
 BYTE SUP_FUN_SET_OS_LOAD   : 1;  /* Set Load OS Parm. */<br> BYTE SUP_FUN_REBOOT     : 1;  /* Reboot OS   */<br> BYTE SUP_FUN_EXTEND_RESPONSE_FIX : 1; /* Fixed version that extends the response packet. */<br> BYTE SUP_NEW_STYLE_IO    : 1; /* This device supports new style I/O requests */<br>
 BYTE SUP_HOT_SWAP      : 1; /* True if this device supports hot swap */</div>
<div> BYTE SUP_TCP_IP      : 1;  /* TRUE if this device supports TCP/IP */<br> BYTE SUP_HTTP       : 1;  /* TRUE if this device supports HTTP */<br> BYTE Reserved       : 6; <br> <br> BYTE UnusedBytes[9];       /* Unused */<br>
#endif <br> } SupportDef;</div>
<div><br>/* Defines for Flags in WPLCSystemInformation structure */<br>#define WPLC_FLAG_BATT_LOW 0x01</div>
<div>/* Masks for LED indicator */<br>#define WPLC_LED_POWER 0x01<br>#define WPLC_LED_RUN  0x02</div>
<div><br>typedef struct<br> {<br> DWORD Flags;   /* Bit 0: Battery Low indicator.  */<br>        /* Bit 1-31: Unused      */<br> DWORD RAMSize;   /* Total size of RAM in WinPLC */<br> DWORD FlashSize;  /* Total size of Flash memory in WinPLC */<br>
 DWORD BattRAMSize; /* Total size of Battery-backed ram in WinPLC */<br> DWORD DipSwitches; /* Status of dip switches */<br>        /* Note: Dip Switches #6 & #7 are reserved for system use. */<br> DWORD LEDs;    /* LED status indicator (see WPLC_LED_XXXX defines) */</div>

<div> DWORD OSSize;   /* Size of the WinPLC OS Image */</div>
<div> DWORD FFSTotal;  /* Total size of the WinPLC flashed based file system */<br> DWORD FFSFree;   /* Free size of the WinPLC flashed based file system */</div>
<div> DWORD RAMPercentFree; /* Percent of RAM that is free. */<br> DWORD RAMPhysicalFree; /* Physical RAM that is free.  */</div>
<div> DWORD VendorID;   /* Vendor ID from the WinPLC */</div>
<div> DWORD CPUClockFrequency;<br> BYTE  ENetAddress[6]; </div>
<div> BYTE Unused[198];<br> } WPLCSystemInformation;<br> </div>
<div><br>/* ERM Defs */<br>#define BIT_INPUT  0<br>#define BIT_OUTPUT 1<br>#define WORD_INPUT 2<br>#define WORD_OUTPUT 3</div>
<div>/* sERMDevice (128 bytes each) */<br>typedef struct<br> {<br> BYTE AddressMode;  /* Defines format of address field (see AM_XXX below)    */<br> BYTE Protocol;   /* HEIP_HOST, HEIP_IPX, or HEIP_IP, 0 == Unused      */</div>

<div> struct<br>  {<br>  union<br>   {<br>   /* Use this for AM_ETHER addressing (Protocol: HEIP_IPX or HEIP_HOST) */<br>   BYTE EtherAddr[6];  /* Ethernet network address */</div>
<div>   /* Use this for AM_NODENUM addressing (Protocol: HEIP_IPX or HEIP_HOST or HEIP_IP) */<br>   DWORD Nodenum;</div>
<div>   /* Use this for AM_IPADDR addressing (Protocol: HEIP_IPX or HEIP_HOST or HEIP_IP) */<br>   BYTE IPAddr[4];<br>#if defined (ANSI_C)<br>   } AM;<br>#else<br>   };<br>#endif</div>
<div>  BYTE Netnum[4]; /* Used for HEIP_IPX protocol; HEIP_IP   */<br>  WORD Port;   /* Used for HEIP_IPX and HEIP_IP protocols */<br>  union<br>   {<br>   BYTE FrameType; /* Used for HEIP_IPX protocol (See FT_XXXX) */<br>
   BYTE GatewayAddress[4]; /* Gateway to use for this device (0's for no gateway) */<br>#if defined (ANSI_C)<br>   } AM2;<br>#else<br>   };<br>#endif<br>  /* BYTE Reserved[3];*/<br>  } Address;</div>
<div> WORD Timeout;      /* Timeout time for this device           */<br> WORD Retrys;      /* Number of time to retry a request before reporting error.   */<br> BYTE ModuleIDs[32];    /* Module ID's for each slot in the device       */<br>
 WORD Flags;       /* See ERM_FLAG_??? defines            */<br> WORD DataOffsets[4];    /* Data offsets for each type (BIT_INPUT, BIT_OUTPUT,    */<br>           /* WORD_INPUT, WORD_OUTPUT) if with a PLC        */<br> WORD DataSizes[4];    /* Data sizes (in bytes) for each type if with a PLC    */<br>
 WORD WatchDog;      /* Watchdog timeout value to use for this device     */<br> WORD PetFrequency;    /* Freq to pet the device to keep WatchDog from firing   */<br>           /* Specified in milliseconds.  If zero no pets will be done  */<br>
 WORD FailuresBeforeStandby; /* Number of consecutive failures to put device in     */<br>           /* standby mode.                */<br> BYTE Reserved[50];    /* Reserved (set to zero)             */<br> } sERMDevice;</div>

<div>/* Address mode 0 is undefined */<br>#define AM_NODENUM 1<br>#define AM_NAME    2  /* Not supported in ERM module. */<br>#define AM_IPADDR  3<br>#define AM_ETHER   4</div>
<div>/* Interface defines */<br>#define IF_UNDEFINED  0 /* ERM I/F not defined / detected         */<br>#define IF_PLC    1 /* ERM will use a PLC style interface        */<br>#define IF_WINPLC   2 /* ERM will use a WinPLC style interface       */</div>

<div>#define ERM_FLAG_IGNORE_WARNINGS  1  /* If set, warnings from this device are ignored */<br>#define ERM_FLAG_AUTO_HOT_SWAP  2  /* If set, terminator hot swap is automatic   */</div>
<div>/* Frame type defines */<br>#define FT_802_2       1<br>#define FT_802_3       2<br>#define FT_ETHER_II    3</div>
<div><br>typedef struct sERMConfig<br> {<br> BYTE Version;      /* Version of sERMConfig 0=Unconfigured; 1= Current Version */<br> BYTE Interface;     /* See IF_XXX above.              */<br> WORD PLCAddresses[4];   /* Address for each type. (BIT_INPUT, BIT_OUTPUT,    */<br>
           /* WORD_INPUT, WORD_OUTPUT) if with a PLC       */<br> WORD PLCDataSizes[4];   /* Size (in bytes) for each type if with a PLC.     */<br> DWORD StandbyCycleTime;   /* Time to wait when a module is not responding before      */<br>
           /* trying to access the module again        */<br>           /* If zero, the module will not be accessed again    */<br> DWORD NotSupportedCycleTime; /* Time to wait when a module is not supported before       */<br>
           /* trying to access the module again        */<br>           /* If zero, the module will not be accessed again    */<br> WORD AssumePLCScanTime;   /* PLC Scan time to assume for timeout purposes if zero,       */<br>
           /* default is used               */<br> BYTE Unused[228];<br> } sERMConfig;</div>
<div>#define MAX_ERM_DEVICES  16</div>
<div><br>typedef struct sERMDeviceInfo<br> {<br> BYTE State;<br> BYTE Supported      : 1;<br> BYTE GotAddressInfo    : 1;<br> BYTE ARPReplyPending    : 1;<br> BYTE GotBaseDef     : 1;<br> BYTE GotSupportInfo    : 1;<br> BYTE GotWatchDogSetupAck  : 1;<br>
 BYTE GotWatchDogSetupComplete : 1;<br> WORD TotalRetrys;<br> WORD LastError;<br> } sERMDeviceInfo;</div>
<div><br>typedef struct sERMInfo<br> {<br> BYTE Version;      /* Version of sERMInfo 1 = current version    */<br> BYTE AutoDetectedInterface; /* Interface which was auto detected by Hx-ERM module */<br> BYTE PLCType;      /* PLC Type that Hx-ERM module is in rack with   */<br>
 BYTE BytesInUsedByERM;   /* Number of Input bytes that Hx-ERM uses     */<br>           /* Currently 32 Bits (4 Bytes) of Error Info    */<br> BYTE BytesOutUsedByERM;   /* Number of Output bytes that Hx-ERM uses    */<br>
           /* Currently 16 Bits (2 Bytes) of disable bits   */<br> sERMDeviceInfo DeviceInfo[MAX_ERM_DEVICES]; <br> WORD Error;       /* Error value from ERM           */<br> WORD Status;      /* Bit per device error status        */<br>
 BYTE RunMode : 1;    /* 1 if in Run Mode; 0 if not         */<br> BYTE ERMState;      </div>
<div> WORD MinScan;      /* Minimum scan time in ms          */<br> WORD MaxScan;      /* Miximum scan time in ms          */<br> DWORD TotalScans;     /* Total Number of scans          */<br> DWORD TotalTime;     /* Total Time for TotalScans         */<br>
 DWORD ReadRetrys;     /* Number of PLC Read Retrys         */<br> DWORD WriteRetrys;    /* Number of PLC Write Retrys         */<br> DWORD DeviceRetrys;    /* Number of Device Retrys          */<br> DWORD DeviceTime;     /* Total Time spent on device comm       */<br>
 BYTE Base;       /* Base number that Hx-ERM module is in     */<br> BYTE Slot;       /* Slot number that Hx-ERM module is in     */<br> BYTE EthernetAddress[6];  /* Ethernet address of controlling WinPLC (0 for PLC) */</div>

<div> BYTE Unused[113];<br> } sERMInfo;</div>
<div>typedef struct sDevCommand<br> {<br> BYTE Version;      /* Version of sDevCommand 1 = current version    */<br> BYTE Command;      /* Command to give to Device (see DEV_CMD_XXX values) */<br> BYTE Data[254];     /* Command specific data           */<br>
 } sDevCommand;</div>
<div>#define DEV_CMD_REINIT   1  /* Used to tell Device to do a reinitialization    */<br>#define DEV_CMD_RESET_STATS 2  /* Used to tell Device to clear error / stat info   */<br>#define DEV_CMD_RESET_ERROR 3  /* Used to clear LastError value for one or more devices */<br>
            /*   Data[0]: bits 0-7 correspond to devies num 0-7  */<br>            /*   Data[1]: bits 0-7 correspond to devies num 8-15  */</div>
<div><br>/* Hx-ERM Errors.     */<br>#define ERM_CONFIG_ERROR_BITS_IN_TOO_FEW     1 /* Config error: Bits In configured not enough    */<br>#define ERM_CONFIG_ERROR_BITS_OUT_TOO_FEW     2 /* Config error: Bits Out configured not enough    */<br>
#define ERM_CONFIG_ERROR_BITS_IN_OVERLAPS_SYS_DATA  3 /* Configured Bit Inputs overlap system input bits   */<br>#define ERM_CONFIG_ERROR_BITS_OUT_OVERLAPS_SYS_DATA 4 /* Configured Bit Outputs overlap system output bits  */<br>
#define ERM_MULTIPLE_DEVICES_WITH_SAME_NODE_NUM   5 /* More than one device found with same node number  */<br>#define ERM_MULTIPLE_DEVICES_WITH_SAME_IP_ADDRESS  6 /* More than one device foudn with same IP address   */<br>
#define ERM_MODULE_NOT_RESPONDING       7 /* Device is not responding to a function request   */<br>#define ERM_MODULE_NOT_SUPPORTED        8 /* Device not supported; may be firmware or cfg error  */<br>#define ERM_MODULE_TIMEOUT          9 /* Device timed out on a function request (after retrys) */<br>
#define ERM_MODULE_NO_GATEWAY_ADDRESS      13 /* Gateway address needed, but not specified     */<br>#define ERM_NO_SUBNET_MASK          14 /* Subnet mask needed, but not specified      */<br>#define ERM_MODULE_MISMATCHED_MODULE_IDS     15 /* Configured module Id's don't match modules in device */<br>
#define ERM_MODULE_INCORRECT_BITS_IN      16 /* Number of bit inputs specified is less than actual  */<br>#define ERM_MODULE_INCORRECT_BITS_OUT      17 /* Number of bit outputs specified is less than actual */<br>#define ERM_MODULE_INCORRECT_WORDS_IN      18 /* Number of word inputs specified is less than actual */<br>
#define ERM_MODULE_INCORRECT_WORDS_OUT      19 /* Number of word outputs specified is less than actual */<br>#define ERM_MODULE_BASE_DEF_ERROR       20 /* Invalid base def for this device        */<br>#define ERM_CONFIG_MISSING          21 /* Hx-ERM hasn't been configured         */<br>
#define ERM_MODULE_BASE_DEF_BUFFER_OVERFLOW    22 /* Overflow of entire BaseDefBuffer        */<br>#define ERM_MODULE_BASE_DEF_OVERFLOW      23 /* Overflow of previous Device BaseDef       */<br>#define ERM_MODULE_WRITE_PACKET_BUFFER_OVERFLOW   24 /* Overflow of entire WritePacketBuffer      */<br>
#define ERM_MODULE_WRITE_PACKET_OVERFLOW     25 /* Overflow of previous WritePacketBuffer      */<br>#define ERM_CONFIG_IO_BUFFER_OVERFLOW      26 /* Overflow of entire IO buffer         */<br>#define ERM_CONFIG_ERROR_WORDS_IN_TOO_FEW     27 /* Config error: Words In configured not enough    */<br>
#define ERM_CONFIG_ERROR_WORDS_OUT_TOO_FEW    28 /* Config error: Words Out configured not enough   */</div>
<div>/* ERM Backplane errors */<br>#define ERM_BPERROR_OBJ_NOT_FOUND           221 /* Internal backplane error          */<br>#define ERM_BPERROR_UNK_PLC_FAMILY       223 /* PLC Family unknown            */<br>#define ERM_BPERROR_INVALID_STATUS       224 /* Invalid backplane status value        */<br>
#define ERM_BPERROR_CCM_CODEERROR       225 /* Code Error returned from PLC         */<br>#define ERM_BPERROR_CCM_ERROR         226 /* General Error returned from PLC        */<br>#define ERM_BPERROR_TIMEOUT         227 /* Timeout on PLC backplane request        */<br>
#define ERM_BPERROR_NO_MORE_OBJECTS       228 /* Backplane queue full            */<br>#define ERM_BPERROR_INVALID_REQUEST       231 /* Internal request error           */</div>
<div>/* Serial port defines */<br>#define SERIAL_1_STOP_BIT 0<br>#define SERIAL_2_STOP_BITS  1</div>
<div>#define SERIAL_7_DATA_BITS 0<br>#define SERIAL_8_DATA_BITS 1</div>
<div>#define SERIAL_NO_PARITY 0<br>#define SERIAL_ODD_PARITY 2<br>#define SERIAL_EVEN_PARITY 3</div>
<div>#define SERIAL_SLAVE  0<br>#define SERIAL_MASTER  1<br>#define SERIAL_PROXY  1</div>
<div>#define SERIAL_NO_RTS  0<br>#define SERIAL_USE_RTS  1<br> <br>typedef struct<br> {<br> DWORD BaudRate;    /* Baud rate to use i.e. 9600 */<br>          /* If Baud rate == 0 then serial port is disabled */<br> <br>#if defined (ANSI_C)<br>
 BYTE  ConfigData;   <br>#else<br> BYTE StopBits  : 1;    /* 0 == 1 Stop bit;  1 == 2 Stop bits */<br> BYTE  DataBits : 1;    /* 0 == 7 Data bits;  1 == 8 Data bits */<br> BYTE Parity  : 2;    /* 0 == 1 == None; 2 == Odd;  3 == Even */<br>
 BYTE Mode  : 1;    /* 0 == Slave;  1 == Master/Proxy */<br> BYTE UseRTS  : 1; /* 0 == Don't use RTS line;  1 == Use RTS line */<br> BYTE Reserved : 2;    /* Reserved locations */<br>#endif <br> BYTE PreTransmitDelay; /* If UseRTS == 1 delay this many ms (times 2) before starting transmit */<br>
 BYTE PostTransmitDelay;  /* If UseRTS == 1 delay this many ms (times 2) after ending transmit */</div>
<div> BYTE  Unused;  /* Unused byte (set to zero) */<br> } SerialSetup;</div>
<div>/* Flags for IPSetup */<br>#define IPF_USE_BRAM_SETUP 0x00000001<br>#define IPF_USE_ZERO_BCAST 0x00000002<br>#define IPF_ENABLE_DHCP  0x00000004<br>#define IPF_USE_DNS   0x00000008<br>#define IPF_USE_WINS   0x00000010</div>

<div>typedef struct<br> {<br> DWORD  Flags;    /* Flags see IPF_XXX above */<br> BYTE  Gateway[16];  /* Gateway address   */<br> BYTE  IPAddress[16];  /* IP Address     */<br> BYTE  Subnet[16];   /* Subnet address    */<br>
 BYTE  DNSAddr[16];  /* Primary DNS (used if IPF_USE_DNS flag is set) */<br> BYTE  WINSAddr[16];  /* Primary WINS (used if IPF_USE_WINS flag is set) */<br> BYTE  Unused[172];  /* Unused (clear to zero)         */<br> } IPSetup;</div>

<div> </div>
<div>typedef struct<br> {<br> WORD Mode;     /* Mode for ErrorLightSetup see ELS_XXXX below   */<br> WORD InitVal;    /* Initial value used for ELS_SET and ELS_CYCLE   */<br> WORD OnTime;    /* OnTime used for ELS_CYCLE         */<br>
 WORD OffTime;    /* OffTime used for ELS_CYCLE         */<br> WORD Num;     /* Number of times to loop for ELS_CYCLE     */<br> WORD Val1;     /* Unused value             */<br> WORD Val2;     /* Unused value             */<br>
 WORD Val3;     /* Unused value             */<br> } ErrorLightSetup;</div>
<div><br>#define ELS_OFF  0  /* Turns the error light off         */<br>#define ELS_SET  1  /* Sets the error light to the value of InitVal   */<br>#define ELS_CYCLE  2  /* Cycles error light.  Begins with value of InitVal  */<br>
         /* When light is turned on, it stays on for OnTime  */<br>         /* When light is turned off, it stays off for OffTime */<br>         /* Cycles lights Num times          */ </div>
<div>typedef struct<br> {<br> BYTE MajorVersion;<br> BYTE MinorVersion;<br> WORD BuildVersion;<br> } VersionDef;<br> <br>typedef struct<br> {<br> BYTE SizeofVersionInfo;<br> VersionDef BootVersion;<br> VersionDef OSVersion;<br>
 BYTE NumOSExtensions;<br> VersionDef OSExt[10];<br> } VersionInfoDef;<br> <br>/* Module type defines */<br>#define MT_EBC   0   /* Ethernet base controller   */<br>#define MT_ECOM  1   /* Ethernet communications module */<br>
#define MT_WPLC  2   /* WinPLC         */<br>#define MT_DRIVE  3   /* Drive card        */<br>#define MT_ERMA  4   /* Ethernet remote master    */<br>#define MT_CTRIO  5   /* Counter I/O card      */<br>#define MT_AVG_DISP 6   /* AVG Display Adapter card   */<br>
#define MT_PBC   7   /* Profibus controller     */<br>#define MT_PBCC  8   /* Profibus IO coprocessor    */<br>#define MT_UNK   0xFF</div>
<div>/* Module Family defines for MT_EBC, MT_ECOM, MT_WPLC, MT_ERMA */<br>#define MF_005    0<br>#define MF_205    2<br>#define MF_305    3<br>#define MF_405    4<br>#define MF_TERM   10</div>
<div>/* Module Family defines for MT_DRIVE */<br>#define MF_100_SERIES 1  /* Hitachi L100 and SJ100 drives */<br>#define MF_J300   2  /* Hitachi J300 drive */<br>#define MF_300_SERIES 3  /* Hitachi SJ300 drive */<br>#define MF_GS    4  /* GS Series drives  GS-EDRV*/</div>

<div>/* Module Family defines for MT_AVG_DISP */<br>#define MF_EZ_TOUCH  1  /* AVG EZ-Touch Ethernet adapter */</div>
<div>typedef struct<br> {<br> BYTE PLCFamily;  /* See MF_XXX defines above */<br> BYTE Unused1;<br> BYTE ModuleType;  /* See MT_XXX defines above */<br> BYTE StatusCode;    <br> BYTE EthernetAddress[6]; /* Hardware ethernet address */<br>
 WORD RamSize;      /* In K-Byte increments */<br> WORD FlashSize;    /* In K-Byte increments */<br> BYTE DIPSettings;   /* Settings of the 8 dip switches. */<br> BYTE MediaType;    /* 0 == 10-Base T */<br>        /* 1 == 10-Base F */<br>
 DWORD EPFCount;    /* Early power fail count (405 EBC)*/</div>
<div>#if defined (ANSI_C)<br> BYTE  Status;   <br>#else<br> BYTE RunRelay : 1;  /* 405 EBC Run Relay Status */<br> BYTE BattLow : 1;   /* 405 EBC Battery Low indicator */<br> BYTE UnusedBits : 6;  /* Unused status bits */<br>
#endif</div>
<div> WORD BattRamSize;   /* Size in K-Bytes of battery-backed ram */<br> BYTE ExtraDIPS;   /* Extra Dip switches on Terminator EBC's */<br> BYTE ModelNumber;   <br> BYTE EtherSpeed;   /* 0=10MBit; 1=100MBit */<br> BYTE PLDRev[2];</div>

<div> BYTE Unused[14];<br> } DeviceDef;</div>
<div>typedef struct<br> {<br> DWORD Timeout;  /* Timeout 0 == Don't use link monitor */<br> BYTE Mode;   /* Mode: */<br>       /*   0 == Clear outputs */<br>       /*   1 == Set outputs to given I/O data pattern */<br>
 BYTE Data[251]; /* Pattern:  Used with set outputs,  same format */<br>       /*     as data for HEIWriteIO call. */<br> } LinkMonitor;</div>
<div>typedef struct<br> { <br> BYTE Algorithm;   /* Algorithm to use for encryption */<br>       /*  0 == No encryption */<br>       /*  1 == Private key encryption */<br>       /* */<br> BYTE Unused[3];  /* Reserved for later */<br>
 BYTE Key[60];  /* Encryption key (null terminated) */<br> }  Encryption;<br> </div>
<div>typedef struct<br> {<br> WORD Type;   /* Type of memory */<br> DWORD Size;   /* Size of memory */<br> DWORD UnitSize; /* 0 = DWORD, 1 = BYTE, 2 = WORD, 4 = DWORD */<br> DWORD Unused[3]; /* Unused */<br> } MemoryTypeDef;<br>
 <br>typedef struct<br> {<br> WORD SizeofSettings  ;    /* sizeof(HEISettings) */<br> <br> /* Action items. */   <br> DWORD Flags;              /* Flags used to control things. */<br>             /* Bit:    Function:                    */<br>
             /*  0-31   Unused                    */<br> <br> /* RXWX Config items. */<br> WORD RXWXACKTimeout    ;   /* Timeout for receiving ACK / NAK */<br> WORD RXWXResponseTimeout  ;   /* Timeout for receiving response. */<br>
 WORD RXWXMaxRetrys   ;   /* Number of times to retry a transaction. */<br> <br> /* RXWX Stat Items. */<br> WORD RXWXMaxACKTime   ;   /* STAT: Max number of ms we have waited for an ack. */<br> WORD RXWXMaxRSPTime   ;   /* STAT: Max number of ms we have waited for a response. */<br>
 DWORD RXWXACKRetrys   ;       /* STAT: Number of retrys for an ack. */<br> DWORD RXWXRSPRetrys   ;   /* STAT: Number of retrys for a response. */<br> DWORD RXWXCompleted   ;   /* STAT: Number of successfully completed transactions */<br>
 DWORD RXWXTimeouts   ;   /* STAT: Number of timeouts on transactions (after retrys) */<br> DWORD RXWXOverruns   ;   /* STAT: Number of times the PLC requested a transaction while */<br>             /* one was being processed. */<br>
 DWORD RXWXErrors    ;   /* STAT: Number of times an invalid code was found or a transaction */<br>             /* was NAKed. */<br>             <br> /* Other stuff */             <br> BYTE Version;        /* Version of this structure.  Currently 0 */<br>
 <br> /* K-Sequence Retrys */<br> WORD KSeqMaxRetrys;      /* Max number of times to retry a K-Sequence request  */<br> WORD KSeqRetrys;       /* STAT: Number of K-Sequence retrys.        */<br> WORD KSeqTimeouts;      /* STAT: Number of K-Sequence timeouts. */<br>
 <br> BYTE Unused[81];       /* Reserved for future use.  (Configure protocol, etc. */<br> } HEISettings;</div>
<div> <br>typedef struct<br> {<br> BYTE RunRelayMode;  /* Relay Mode */<br>         /* See Relay modes below. */<br> DWORD SerialTimeout;  /* Used for RRM_DRIVE_COMM_BAD */<br> DWORD EthernetTimeout; /* Used for RRM_DRIVE_COMM_BAD */</div>

<div> BYTE Unused[55];<br> } ModuleSetup;</div>
<div><br>typedef struct<br> {<br> /*<br> ** GS Series drive setup timeouts.<br> ** In order for a value to be used, set the most significant bit.<br> */<br> WORD ReceiveCharTimeout[4];<br> WORD CommandResponseTimeout[4];<br>
 WORD WriteCacheClearTime;   /* 250 ms default */<br> WORD TimeoutsBeforeAutoBaud;  /*  50 ms default */<br> WORD RTSPreTransmitDelay;   /*   4 ms default */<br> WORD RTSPostTransmitDelay;   /*   4 ms default */<br> WORD AutoBaudDelay;     /*  10 ms default */<br>
 WORD ProcessSlaveIdle;    /*  10 ms default */<br> WORD RetryDelay;      /*  20 ms default */<br> WORD Unused[49];<br> } DriveSetup;</div>
<div><br>/* Relay Modes */<br>#define RRM_LINK_GOOD  0 /* Run relay on when link is good (default) */<br>#define RRM_LINK_NOT_GOOD 1 /* Run relay on when link is not good */<br>#define RRM_POWERUP_ON  2 /* EBC turns run relay mode on on powerup   */<br>
#define RRM_MANUAL_ON  3 /* Run relay mode is controlled by control software */<br>#define RRM_DRIVE_COMM_BAD 4 /* Relay on if serial or ethernet comm lost (for Drive controller card) */</div>
<div><br>#define ACCESS_READ  0<br>#define ACCESS_WRITE 1</div>
<div>typedef struct sMemRefDetail<br> {<br> BYTE Direction; /* ACCESS_READ == Read, ACCESS_WRITE == Write */<br> WORD Type;   /* Memory type */ <br> DWORD Offset;  /* Memory Offset */<br> WORD NumBytes;  /* Number of bytes */<br>
 } MemRefDetail;</div>
<div>typedef struct<br> {<br> MemRefDetail Detail;<br> BYTE *pBuffer;  /* Data buffer */<br> } MemRef;</div>
<div>/* RescanFlags */<br>#define RESCAN_LEAVE_IMAGE_RAM 0  /* Don't clear the image RAM */<br>#define RESCAN_CLEAR_IMAGE_RAM 1  /* Clear the image RAM */</div>
<div>/* Protocol Defines */<br>#define HEIP_HOST     1<br>#define HEIP_IPX     2<br>#define HEIP_IP   3<br>#define HEIP_SERIAL  4</div>
<div><br>#if !defined(FIRMWARE)</div>
<div>#if defined(HEIDEFS)<br>typedef int  BOOL;<br>typedef unsigned char BYTE;<br>typedef unsigned short WORD;<br>typedef unsigned long DWORD;<br>#define FALSE 0<br>#define TRUE 1<br>#endif /* #if defined(HEIDEFS) */</div>

<div>#define HEIAPIVERSION 3<br>#define HEIAPIVERSIONSTRING "3"</div>
<div>#define HEIT_HOST   1<br>#define HEIT_IPX   2 <br>#define HEIT_WINSOCK  4<br>#define HEIT_OTHER_TRANSPORT 8<br>#define HEIT_UNIX   16<br>#define HEIT_SERIAL  32</div>
<div>/* Encryption Algorithms */<br>#define HEIEN_NONE   0 <br>#define HEIEN_A1   1  </div>
<div>#define PACKET_HEADER_SIZE 9</div>
<div>#if defined(HEIDOS)<br>#define __declspec(dllexport)<br>#endif /* #if defined(HEIDOS) */</div>
<div>#if defined(HEI16)<br>#define __declspec(dllexport)<br>#endif /* #if defined(HEI16) */</div>
<div>#if defined(HEIUNIX)<br>#define __declspec(dllexport)<br>#endif /* #if defined(HEIT_UNIX) */</div>
<div><br>/* Default values for HEIOpenDevice */<br>#define DefDevTimeout 100<br>#define DefDevRetrys  3<br>#define DefDevUseAddressedBroadcast FALSE</div>
<div><br>typedef struct <br> {<br> union<br>  {<br>  /* Use this for HEIP_HOST protocol addressing. */<br>  struct <br>   {<br>   short Family;   /* AF_UNSPEC == 0 */<br>   char Nodenum[6];  /* Ethernet network address */<br>
   unsigned short LANNum; /* Lana number */<br>   } AddressHost;</div>
<div>  /* Use this for HEIP_IPX protocol addressing. */<br>  struct <br>   {<br>   short Family;   /* AF_IPX == 6 */<br>   char Netnum[4];   /* Network number */<br>   char Nodenum[6];  /* Ethernet network address */<br>
   unsigned short Socket; /* Socket number == 0x7070 */<br>   } AddressIPX;</div>
<div>  /* Use this for HEIP_IP protocol addressing. */<br>  struct <br>   {<br>   short Family;   /* AF_INET == 2 */<br>   unsigned short Port; /* Port number == 0x7070 */<br>   union     /* Internet address */<br>    {<br>
    struct { unsigned char b1,b2,b3,b4; } bAddr;/* Byte addressing */<br>    struct { unsigned short w1,w2; } wAddr;  /* Word addressing */<br>    unsigned long lAddr;      /* DWord addressing */<br>    } AddressingType;<br>
   char  Zero[8];   /* Initialize to zeros */<br>   } AddressIP;</div>
<div>  /* This is the generic address buffer. */<br>  BYTE Raw[20];<br>#ifdef ANSI_C /*  ANSI C cannot have anonymous structures */<br>  } Address;<br>#else<br>  };<br>#endif<br> } ENetAddress;</div>
<div><br>#if defined(__cplusplus)<br>extern "C"<br> {<br>#endif /* #if defined(__cplusplus) */</div>
<div> /* INITIALIZATION / SHUTDOWN */<br> __declspec(dllexport) int HEIOpen(WORD HEIAPIVersion);<br> __declspec(dllexport) int HEIClose();<br> <br> /* Protocol Stuff */<br> typedef struct <br>  {<br>  WORD Transport;  /* HEIT_HOST */<br>
       /* HEIT_IPX */<br>       /* HEIT_NETBIOS */<br>       /* HEIT_WINSOCK */</div>
<div>  WORD Protocol;  /* HEIP_HOST*/<br>       /* HEIP_IPX */<br>       /* HEIP_IP */<br>       /* HEIP_NETBIOS */<br>  /* Encryption stuff. */<br>  Encryption Encrypt; /* Set this up before calling HEIOpenTransport  */<br>
       /* .Algorithm == HEIEN_NONE OR HEIEN_A1 */<br>       /* .Key == Encryption key */<br>         <br>  /* DWORD NetworkAddress; */<br>  ENetAddress *pSourceAddress; /* Used for multiple ethernet cards.  This address is the address of the card to use. */</div>

<div>  /*int (*pSendPacket)(HEIDevice *pDevice, BYTE *pPacket, WORD PacketSize);*/<br>  /*int (*pReceivePacket)(HEIDevice *pDevice, BYTE *pResponse, int *pResponseSize);*/<br>#if HEIAPIVERSION==3<br>  BYTE Reserved[48];  /* Reserved bytes, set to zero */<br>
#endif<br>  } HEITransport;<br> <br> __declspec(dllexport) int HEIOpenTransport(HEITransport *pTransport, WORD Version,  ENetAddress *pSourceAddress);<br> /* __declspec(dllexport) int HEIOpenTransport(HEITransport *pTransport, WORD Version, DWORD NetworkAddress );*/<br>
 /* __declspec(dllexport) int HEIOpenTransport(HEITransport *pTransport, WORD Version, DWORD NetworkAddress = 0); */<br> __declspec(dllexport) int HEICloseTransport(HEITransport *pTransport);<br> <br> <br> /* DEVICE Stuff */<br>
 typedef struct <br>  {<br>  union<br>   {<br>   /* Use this for HEIP_HOST protocol addressing. */<br>   struct <br>    {<br>    short Family;   /* AF_UNSPEC == 0 */<br>    char Nodenum[6];  /* Ethernet network address */<br>
    unsigned short LANNum; /* Lana number */<br>    } AddressHost;</div>
<div>   /* Use this for HEIP_IPX protocol addressing. */<br>   struct <br>    {<br>    short Family;   /* AF_IPX == 6 */<br>    char Netnum[4];   /* Network number */<br>    char Nodenum[6];  /* Ethernet network address */<br>
    unsigned short Socket; /* Socket number == 0x7070 */<br>    } AddressIPX;</div>
<div>   /* Use this for HEIP_IP protocol addressing. */<br>   struct <br>    {<br>    short Family;   /* AF_INET == 2 */<br>    unsigned short Port; /* Port number == 0x7070 */<br>    union     /* Internet address */<br>
     {<br>     struct { unsigned char b1,b2,b3,b4; } bAddr;/* Byte addressing */<br>     struct { unsigned short w1,w2; } wAddr;  /* Word addressing */<br>     unsigned long lAddr;      /* DWord addressing */<br>     } AddressingType;<br>
    char  Zero[8];   /* Initialize to zeros */<br>    } AddressIP;</div>
<div>   struct<br>    {<br>    BYTE CommPort;<br>    BYTE ByteSize;<br>    BYTE Parity;  <br>    BYTE StopBits;<br>    DWORD Baud;<br>    void *hLocal;<br>    } AddressSerial;</div>
<div>   /* This is the generic address buffer. */<br>   BYTE Raw[20];<br>   } Address;</div>
<div>  WORD wParam;    /* Application can use this. */<br>  DWORD dwParam;    /* Application can use this. */</div>
<div>  WORD Timeout;    /* Timeout value in ms (can be changed without closing the device). */<br>  WORD Retrys;    /* Number of times to retry (can be changed without closing the device). */</div>
<div>  BYTE ENetAddress[6];  /* The ethernet address is placed here in the HEIQueryDevices call. */</div>
<div>  WORD RetryCount;   /* Number of retrys which have occured. */<br>  WORD BadCRCCount;    /* Number of packets received with bad CRC */<br>  WORD LatePacketCount;   /* Number of packets received, but after a timeout */</div>

<div>  BOOL ParallelPackets;  /* Setting this to TRUE (after HEIOpenDevice) will enable an application */<br>         /* to send multiple HEIReadIO, HEIWriteIO, HEICCMRequest or  HEIKSEQRequest requests  */<br>         /* (to different) modules before waiting for any responses.   */<br>
         /* The application will then need to implement its own retry / timeout mechanism  */<br>         /* while waiting for the responses. */<br>         /* The application uses HEIGetResponse to see if a response for a module has arrived. */<br>
         /* NOTE: The application should not send multiple requests to a single module */<br>         /*       without waiting for the response in between. */</div>
<div>  /* Internal - Do not touch!! */<br>  BOOL UseAddressedBroadcast; /* Need to close the device and reopen it to change this! */<br>  BOOL UseBroadcast;    <br>  DWORD _dwParam; <br>  WORD DataOffset;<br>  HEITransport *_pTransport; /* Need to close the device and reopen it to change this! */<br>
  int SizeOfData;<br>  BYTE *pData;<br>  void *pBuffer;<br>  unsigned short LastAppVal;<br>#if HEIAPIVERSION==3<br>  BYTE UseProxy;<br>  BYTE ProxyBase;<br>  BYTE ProxySlot;<br>  BYTE ProxyDevNum;</div>
<div>  BYTE Reserved[44];  /* Reserved bytes, set to zero */<br>#endif<br>  } HEIDevice;<br> <br> __declspec(dllexport) int HEIQueryDevices(HEITransport *pTransport, HEIDevice *pDevices, WORD *pNumDevices, WORD HEIAPIVersion);<br>
 <br> __declspec(dllexport) int HEIOpenDevice(HEITransport *pTransport, HEIDevice *pDevice, WORD HEIAPIVersion, WORD Timeout, WORD Retrys, BOOL UseAddressedBroadcast);<br> /* __declspec(dllexport) int HEIOpenDevice(HEITransport *pTransport, HEIDevice *pDevice, WORD HEIAPIVersion, WORD Timeout=DefDevTimeout, WORD Retrys=DefDevRetrys, BOOL UseAddressedBroadcast=DefDevUseAddressedBroadcast); */<br>
 __declspec(dllexport) int HEICloseDevice(HEIDevice *pDevice);<br> <br> __declspec(dllexport) int HEIQueryDeviceData(HEITransport *pTransport, HEIDevice *pDevices, WORD *pNumDevices, WORD HEIAPIVersion, WORD DataType, BYTE *pData, WORD SizeofData);<br>
 <br> /* SUPPORT INFORMATION */<br> __declspec(dllexport) int HEIReadSupportInfo(HEIDevice *pDevice, BYTE *pSupportInfo, WORD SizeOfSupportInfo);<br> <br> <br> /* VERSION INFORMATION */<br> __declspec(dllexport) int HEIReadVersionInfo(HEIDevice *pDevice, BYTE *pVerInfo, WORD SizeVerInfo);<br>
 <br> <br> /* BASE DEFINITION */<br> __declspec(dllexport) int HEIReadBaseDef(HEIDevice *pDevice, BYTE *pBaseDefInfo, WORD *pSizeOfBaseDefInfo);<br> __declspec(dllexport) int HEIWriteBaseDef(HEIDevice *pDevice, BYTE *pInputBaseDef, WORD SizeOfInputBaseDef, BYTE *pOutputBaseDef, WORD *pSizeOfOutputBaseDef);<br>
 __declspec(dllexport) int HEIInitBaseDef(HEIDevice *pDevice, BYTE *pBaseDefInfo, WORD *pSizeOfBaseDefInfo);<br> __declspec(dllexport) int HEIRescanBase(HEIDevice *pDevice, DWORD RescanFlags, BYTE *pBaseDefInfo, WORD *pSizeOfBaseDefInfo);</div>

<div> <br> <br> /* DEVICE DEFINITION */<br> __declspec(dllexport) int HEIReadDeviceDef(HEIDevice *pDevice, BYTE *pModuleDefInfo, WORD SizeOfModuleDefInfo);</div>
<div> /* IO ACCESS */<br> __declspec(dllexport) int HEIReadIO(HEIDevice *pDevice, BYTE *pData, WORD *DataSize);<br> __declspec(dllexport) int HEIWriteIO(HEIDevice *pDevice, BYTE *pData, WORD SizeofData, BYTE *pReturnData, WORD *pSizeofReturnData);<br>
 __declspec(dllexport) int HEIWriteIONoRead(HEIDevice *pDevice, BYTE *pData, WORD SizeofData);</div>
<div> __declspec(dllexport) int HEIReadIOEx(HEIDevice *apDevice[], BYTE *apData[], WORD aSizeofData[], int aErrorCode[], int DeviceCount);<br> __declspec(dllexport) int HEIWriteIOEx(HEIDevice *apDevice[], BYTE *apData[], WORD aSizeofData[], BYTE *apReturnData[], WORD aSizeofReturnData[], int aErrorCode[], int DeviceCount);</div>

<div> /* CONFIG */<br> __declspec(dllexport) int HEIReadConfigData(HEIDevice *pDevice, BYTE *pData, WORD *DataSize);<br> __declspec(dllexport) int HEIWriteConfigData(HEIDevice *pDevice, BYTE *pData, WORD SizeofData, BYTE *pReturnData, WORD *pSizeofReturnData);<br>
 // NOTE: You can also Use HEIWriteIO to write config data using type DF_CONFIG</div>
<div><br> /* SETUP */<br> __declspec(dllexport) int HEIReadSetupData(HEIDevice *pDevice, WORD SetupType, BYTE *pData, WORD *pSizeofData);<br> __declspec(dllexport) int HEIWriteSetupData(HEIDevice *pDevice, WORD SetupType, BYTE *pData, WORD SizeofData);<br>
 __declspec(dllexport) int HEIDeleteSetupData(HEIDevice *pDevice, WORD SetupType);<br> __declspec(dllexport) int HEIEnumSetupData(HEIDevice *pDevice, WORD *pData, WORD *pSizeofDataInWords);</div>
<div> /* WATCHDOG */<br> __declspec(dllexport) int HEIPetDevice(HEIDevice *pDevice);</div>
<div> /* STATISTICS */<br> __declspec(dllexport) int HEIReadEthernetStats(HEIDevice *pDevice, BYTE *pData, WORD *DataSize, BOOL Clear);<br> /* __declspec(dllexport) int HEIReadEthernetStats(HEIDevice *pDevice, BYTE *pData, WORD *DataSize, BOOL Clear=FALSE); */</div>

<div> /* MODULES STATUS */<br> __declspec(dllexport) int HEIReadModuleStatus(HEIDevice *pDevice, BYTE *pData, WORD *DataSize, BOOL Reset);<br> /* __declspec(dllexport) int HEIReadModuleStatus(HEIDevice *pDevice, BYTE *pData, WORD *DataSize, BOOL Reset=FALSE); */</div>

<div> /* Multiple Packet Stuff. */<br> __declspec(dllexport) int HEIGetResponse(HEIDevice *pDevice, BYTE *pResponse, int *pResponseSize, BOOL CheckAppVal);<br> /* __declspec(dllexport) int HEIGetResponse(HEIDevice *pDevice, BYTE *pResponse, int *pResponseSize, BOOL CheckAppVal=TRUE); */</div>

<div>   /* ECOM STUFF */<br> __declspec(dllexport) int HEICCMRequest(HEIDevice *pDevice, BOOL bWrite, BYTE DataType, WORD Address, WORD DataLen, BYTE *pData);<br> __declspec(dllexport) int HEIKSEQRequest(HEIDevice *pDevice, WORD DataLenIn, BYTE *pData, WORD *pDataLen);</div>

<div> /* SERIAL PORT STUFF */<br> __declspec(dllexport) int HEIWriteComm(HEIDevice *pDevice, WORD Num2Write, BYTE *pData);<br> __declspec(dllexport) int HEIReadComm(HEIDevice *pDevice, WORD *pNum2Read, BYTE *pData);<br> __declspec(dllexport) int HEIGetRXAvailable(HEIDevice *pDevice, WORD *pAvailable);<br>
 __declspec(dllexport) int HEIFlushRXQueue(HEIDevice *pDevice);<br> __declspec(dllexport) int HEIGetTXLeft(HEIDevice *pDevice, WORD *pLeft);<br> __declspec(dllexport) int HEISetupSerialPort(HEIDevice *pDevice, SerialSetup *pSetup, BOOL WriteToFlash);<br>
 __declspec(dllexport) int HEIReadSerialPortSetup(HEIDevice *pDevice, SerialSetup *pSetup);<br> <br> /* SERIAL PORT STUFF (EX) */<br> __declspec(dllexport) int HEIWriteCommEx(HEIDevice *pDevice,BYTE Port ,WORD Num2Write, BYTE *pData);<br>
 __declspec(dllexport) int HEIReadCommEx(HEIDevice *pDevice, BYTE Port, WORD *pNum2Read, BYTE *pData);<br> __declspec(dllexport) int HEIGetRXAvailableEx(HEIDevice *pDevice, BYTE Port, WORD *pAvailable);<br> __declspec(dllexport) int HEIFlushRXQueueEx(HEIDevice *pDevice, BYTE Port);<br>
 __declspec(dllexport) int HEIFlushTXQueueEx(HEIDevice *pDevice, BYTE Port);<br> __declspec(dllexport) int HEIGetTXLeftEx(HEIDevice *pDevice, BYTE Port, WORD *pLeft);<br> __declspec(dllexport) int HEISetupSerialPortEx(HEIDevice *pDevice, BYTE Port, SerialSetup *pSetup, BOOL WriteToFlash);<br>
 __declspec(dllexport) int HEIReadSerialPortSetupEx(HEIDevice *pDevice, BYTE Port, SerialSetup *pSetup);<br> __declspec(dllexport) int HEIAccessComm(HEIDevice *pDevice, WORD SendDataSize, BYTE *pSendData, WORD *pReturnDataSize, BYTE *pReturnData);</div>

<div><br> /* MEMORY STUFF (see below for types) */<br> __declspec(dllexport) int HEIReadMemory(HEIDevice *pDevice, WORD Type, DWORD Offset, WORD NumBytes, BYTE *pBuffer);<br> __declspec(dllexport) int HEIWriteMemory(HEIDevice *pDevice, WORD Type, DWORD Offset, WORD NumBytes, BYTE *pBuffer);<br>
 __declspec(dllexport) int HEIENumMemory(HEIDevice *pDevice, WORD *pNumWords, MemoryTypeDef *pBuffer);<br> __declspec(dllexport) int HEIAccessMemory(HEIDevice *pDevice, MemRef MemRefs[], WORD NumRefs);</div>
<div><br> /* SHARED RAM STUFF (for Intelligent modules) */<br> __declspec(dllexport) int HEIReadSharedRAM(HEIDevice *pDevice, WORD Base, WORD Slot, WORD Address, WORD Bytes2Read, BYTE *pBuffer);<br> __declspec(dllexport) int HEIWriteSharedRAM(HEIDevice *pDevice, WORD Base, WORD Slot, WORD Address, WORD Bytes2Write, BYTE *pBuffer);</div>

<div><br> /* WinPLC specific functions */<br>#ifndef WINPLC<br> __declspec(dllexport) int WPLCSetOSLoad(HEIDevice *pDevice, int Val);<br> __declspec(dllexport) int WPLCReboot(HEIDevice *pDevice);<br> __declspec(dllexport) int WPLCRunProgram(HEIDevice *pDevice, BYTE *pProgram);</div>

<div> __declspec(dllexport) int HEIWriteERMData(HEIDevice *pDevice, WORD Base, WORD Slot, BYTE DataType, BYTE *pData, WORD NumBytes, WORD Offset);<br> __declspec(dllexport) int HEIReadERMData(HEIDevice *pDevice, WORD Base, WORD Slot, BYTE DataType, BYTE *pData, WORD NumBytes, WORD Offset);<br>
 __declspec(dllexport) int HEIDoERMCommand(HEIDevice *pDevice, WORD Base, WORD Slot, WORD Command);<br> __declspec(dllexport) int HEIDoERMCommandEx(HEIDevice *pDevice, WORD Base, WORD Slot, WORD Command, BYTE *pExtra, WORD ExtraLen);</div>

<div> __declspec(dllexport) int WPLCWriteERMData(HEIDevice *pDevice, WORD Base, WORD Slot, BYTE DataType, BYTE *pData, WORD NumBytes, WORD Offset);<br> __declspec(dllexport) int WPLCReadERMData(HEIDevice *pDevice, WORD Base, WORD Slot, BYTE DataType, BYTE *pData, WORD NumBytes, WORD Offset);<br>
 __declspec(dllexport) int WPLCDoERMCommand(HEIDevice *pDevice, WORD Base, WORD Slot, WORD Command);<br> __declspec(dllexport) int WPLCDoERMCommandEx(HEIDevice *pDevice, WORD Base, WORD Slot, WORD Command, BYTE *pExtra, WORD ExtraLen);<br>
#endif<br> /* <br> ** Query timeout function <br> */<br> /* Sets new query timeout value and returns the old query timeout value */<br> __declspec(dllexport) DWORD HEISetQueryTimeout(DWORD NewTimeout);<br> /* Gets current query timeout value */<br>
 __declspec(dllexport) DWORD HEIGetQueryTimeout();</div>
<div> /*<br> ** Async Handler for handling extra packets.<br> */<br> __declspec(dllexport) int HEISetAsyncHandler(void (*pFun)(HEIDevice *pDevice, BYTE *pResponse, int ResponseLen));<br> __declspec(dllexport) int HEIGetAsyncHandler(void (**pFun)(HEIDevice *pDevice, BYTE *pResponse, int ResponseLen));</div>

<div>/*<br>** EZ-Ethernet defs<br>*/<br>typedef signed   char    SBIT8;<br>#define MAX_PGM_DATA_LEN  255   // Max packet sent by AVG.<br>#define MAX_ERR_MSG_SZ     40   // Forty bytes of error message space.<br>#define MAC_LEN             6   // Six bytes for MAC address<br>
#define SPARE_BYTES         4   // Four spare bytes for future use.<br>#ifndef NO_ERROR<br>#define NO_ERROR     0L<br>#endif</div>
<div>typedef struct<br>{<br>    unsigned char Name[20];<br>    unsigned char Node_ID[2];<br>    HEIDevice    *pDevice;<br>} NODELIST;</div>
<div><br>/*<br>** Layout of the control buffer.<br>*/<br>typedef struct CntlBuffer<br>{<br>    BYTE   TaskCode;               /*  Taskcode byte (future use)*/<br> BYTE   PanelLock;              /*  1 - Panel has lock, 0 - not locked*/<br>
 BYTE   AdapterLock;            /*  1 - Adapter has lock, 0 - not locked*/<br> BYTE   InStatus;               /*  Incoming status*/<br> BYTE   OutStatus;              /*  Outgoing status*/<br> SBIT8  Seq;                    /*  Sequence number assigned by panel*/<br>
 BYTE   ErrorOffset;            /*  Offset into error array*/<br>    BYTE   ItemCnt[2];             /*  Two bytes since read tags can be > 256.*/<br> BYTE   ErrMsg[MAX_ERR_MSG_SZ]; /*  40 character string.*/<br>    BYTE   EcomOffset;             /*  Used for panel to panel communications.*/<br>
    BYTE   Mac[MAC_LEN];           /*  Stores mac address of responding device.*/<br> BYTE   Spare[SPARE_BYTES];     /*  Future use*/<br>} CNTL_BUF;</div>
<div>/*<br>** Layout of the program shared ram frame<br>*/<br>typedef struct PgmBuffer<br>{<br>    CNTL_BUF   CntlBuf;<br> BYTE       PgmData[MAX_PGM_DATA_LEN];<br> <br>} PGM_BUF;</div>
<div><br> /*<br> ** EZ-Ethernet functions<br> */<br> __declspec(dllexport) int HEIWriteEZethernetPgmSpace(HEIDevice *pDevice, BYTE *pData, WORD SizeofData);<br> __declspec(dllexport) BOOL EZSendPacket(HEIDevice *pDevice, PGM_BUF *pBuffer, BYTE *Error_message, unsigned short int Len);<br>
 __declspec(dllexport) NODELIST *EZGetNodeList(unsigned short int *TotalEZ);</div>
<div> __declspec(dllexport) int SetCRCMode(int Mode);<br> __declspec(dllexport) int SendPacketTwoResponses(HEIDevice *pDevice, BYTE *pPacket, WORD PacketSize, BYTE *pResponse, int *pResponseSize, <br>         BOOL WaitForResponse, BOOL ReturnWarnings, WORD Bytes2Verify, BYTE *pVerifyData, <br>
         WORD ExtraTime, BOOL ProcessTimeout, BOOL CheckAppVal);</div>
<div>#if defined(__cplusplus)<br> }<br>#endif /* #if defined(__cplusplus) */</div>
<div>#endif /* #if !defined(FIRMWARE) */</div>
<div>/* Errors */<br>#define HEIE_NULL        0 /* No Error */<br>#define HEIE_FIRST_ERROR     0x8000 /* Number for First Error */<br>#define HEIE_LAST_ERROR      0xFFFF /* Number for Last Error */</div>
<div>#define HEIE_NOT_IMPLEMENTED    0x8000 /* Function not implemented */<br>#define HEIE_VER_MISMATCH     0x8001 /* Version passed to function not correct for library */<br>#define HEIE_UNSUPPORTED_TRANSPORT   0x8002 /* Supplied transport not supported */<br>
#define HEIE_INVALID_DEVICE     0x8003 /* Supplied device is not valid */<br>#define HEIE_BUFFER_TOO_SMALL    0x8004 /* Supplied buffer is too small */<br>#define HEIE_ZERO_BYTES_RECEIVED   0x8005 /* Zero bytes were returned in the packet */<br>
#define HEIE_TIMEOUT      0x8006 /* Timeout error */<br>#define HEIE_UNSUPPORTED_PROTOCOL   0x8007 /* Supplied protocol not supported */<br>#define HEIE_IP_ADDR_NOT_INITIALIZED  0x8008 /* The devices IP address has not be set. NOTE: Need to use */<br>
             /* addressed broadcast to talk to the module (with IP) to setup */<br>             /* the IP address. */<br>#define HEIE_NULL_TRANSPORT      0x8009 /* No transport specified. */<br>#define HEIE_IPX_NOT_INSTALLED    0x800A /* IPX Transport not installed. */<br>
#define HEIE_IPX_OPEN_SOCKET     0x800B /* Error opening IPX Socket. */<br>#define HEIE_NO_PACKET_DRIVER    0x800C /* No packet driver found. */<br>#define HEIE_CRC_MISMATCH     0x800D /* CRC did not match. */<br>#define HEIE_ALLOCATION_ERROR    0x800E /* Memory allocation error failed. */<br>
#define HEIE_NO_IPX_CACHE     0x800F /* No cache has been allocated for IPX */<br>#define HEIE_INVALID_REQUEST    0x8010 /* Invalid request */<br>#define HEIE_NO_RESPONSE     0x8011 /* No response was available./ requested */<br>
#define HEIE_INVALID_RESPONSE    0x8012 /* Invalid format response was received. */<br>#define HEIE_DATA_TOO_LARGE     0x8013 /* Given data is too large */<br>#define HEIE_LOAD_PROC_ERROR    0x8014  /* Error loading procedures */<br>
#define HEIE_NOT_LOADED      0x8015 /* Attempted command before successfull OpenTransport */<br>#define HEIE_ALIGNMENT_ERROR    0x8016 /* Data not aligned on proper boundary */<br>#define HEIE_FILE_NOT_OPEN     0x8017    /* File not open */</div>

<div>#define HEIE_LOAD_ERROR      0x8100 /* Mask for WinSock load Error see below (from HEIOpenTransport) */<br>#define HEIE_LAST_LOAD_ERROR    0x811F /* Last in the range of WinSock load Errors */</div>
<div>#define HEIE_IO_ERROR      0x9000 /* Mask for IO Error condition (from HEIReadModuleStatus, HEIReadIO, or HEIWriteIO) */<br>#define HEIE_IO_WARNING      0xA000 /* Mask for IO Warning condition (from HEIReadModuleStatus, HEIReadIO, or HEIWriteIO) */<br>
#define HEIE_IO_INFO       0xC000 /* Mask for IO Info condition (from HEIReadModuleStatus, HEIReadIO, or HEIWriteIO) */</div>
<div>#define HEIE_ICMP_PKT_FOUND    65<br>#define HEIE_ARP_PKT_FOUND       66<br>#define HEIE_TYPE_NOT_HANDLED      67<br>#define HEIE_LINK_SENSE_TRIGGERED  68<br>#define HEIE_UNK_IP_PACKET     100<br>#define HEIE_UNK_ETHERTYPE     101<br>
#define HEIE_UNK_PACKET_TYPE     102<br>#define HEIE_UNK_802X_PACKET_TYPE  103<br>#define HEIE_UNK_LLC_TYPE     104<br>#define HEIE_CRC_DOES_NOT_MATCH   105<br>#define HEIE_CRC_NO_DATA     106<br>#define HEIE_ENET_ADDR_REPROGRAMMED  107<br>
#define HEIE_NULL_DATA_POINTER   108<br>#define HEIE_SIZE_ERROR      109<br>#define HEIE_NOT_FOUND      110<br>#define HEIE_INVALID_TYPE     111<br>#define HEIE_RAM_ALREADY_LOCKED   112<br>#define HEIE_INVALID_REQUEST_INT   113<br>
#define HEIE_TIMEOUT_ERROR     114<br>#define HEIE_FLASH_PROGRAM_ERROR   115<br>#define HEIE_INVALID_OS      116<br>#define HEIE_INVALID_LOCATION    117<br>#define HEIE_INVALID_SLOT_NUMBER   118<br>#define HEIE_INVALID_DATA     119<br>
#define HEIE_MODULE_BUSY     120<br>#define HEIE_CHANNEL_FAILURE    121<br>#define HEIE_UNUSED_CHANNELS_EXIST  122<br>#define HEIE_INVALID_UDP_PORT    123<br>#define HEIE_SHUTDOWN_OS     124<br>#define HEIE_NOT_MY_IP_ADDRESS   125<br>
#define HEIE_PROTECTION_ERROR    126<br>#define HEIE_UNK_TYPE_ERROR    127<br>#define HEIE_BACKPLANE_INIT_ERROR  128<br>#define HEIE_UNK_RESPONSE     129<br>#define HEIE_UNK_RXWX_FORMAT    130<br>#define HEIE_UNK_ACK       131<br>
#define HEIE_UNK_NAK       132<br>#define HEIE_RANGE_ERROR     133<br>#define HEIE_LENGTH_WARNING    134<br>#define HEIE_INVALID_BASE_NUMBER   135<br>#define HEIE_INVALID_MODULE_TYPE   136<br>#define HEIE_INVALID_OFFSET    137<br>
#define HEIE_INVALID_BOOT_VER_FOR_OS 138<br>#define HEIE_BROKEN_TRANSMITTER   139<br>#define HEIE_INVALID_ADDRESS    140<br>#define HEIE_TIMING       141<br>#define HEIE_CHANNEL_FAILURE_MULTI  142<br>#define HEIE_SERIAL_SETUP_ERROR   143<br>
#define HEIE_NOT_INITIALIZED    144<br>#define HEIE_INVALID_MODE     145<br>#define HEIE_COMM_FAILURE     146<br>#define HEIE_OPERATION_ABORTED   147<br>#define HEIE_INVALID_RX_CHAR    148<br>#define HEIE_REQUEST_NAKED     149<br>
#define HEIE_INVALID_OPERATION   150<br>#define HEIE_VAL_ALREADY_USED    151<br>/* define HEIE_MODULE_ERROR     152 */<br>#define HEIE_MODULE_NOT_RESPONDING  153<br>#define HEIE_BASE_CHANGED     154 /* I/O Base has changed */<br>
#define HEIE_MODULE_FAILURE    155<br>#define HEIE_PARITY_ERROR     156<br>#define HEIE_FRAMING_ERROR     157<br>#define HEIE_OVER_RUN_ERROR    158<br>#define HEIE_BUFFER_OVERFLOW    159<br>#define HEIE_ABORT       160<br>
#define HEIE_BUSY        161<br>#define HEIE_DRIVE_TRIP      162  /* Drive has tripped */<br>#define HEIE_COMMAND_PENDING    163</div>
<div><br>#define HEIE_CHANNELS_UNUSED_0   200<br>#define HEIE_CHANNELS_UNUSED_1   201<br>#define HEIE_CHANNELS_UNUSED_2   202<br>#define HEIE_CHANNELS_UNUSED_3   203<br>#define HEIE_CHANNELS_UNUSED_4   204<br>#define HEIE_CHANNELS_UNUSED_5   205<br>
#define HEIE_CHANNELS_UNUSED_6   206<br>#define HEIE_CHANNELS_UNUSED_7   207<br>#define HEIE_CHANNELS_UNUSED_8   208<br>#define HEIE_CHANNELS_UNUSED_9   209<br>#define HEIE_CHANNELS_UNUSED_10   210<br>#define HEIE_CHANNELS_UNUSED_11   211<br>
#define HEIE_CHANNELS_UNUSED_12   212<br>#define HEIE_CHANNELS_UNUSED_13   213<br>#define HEIE_CHANNELS_UNUSED_14   214<br>#define HEIE_CHANNELS_UNUSED_15   215<br>#define HEIE_CHANNELS_UNUSED_16   216</div>
<div><br>/*  Winsock Load Errors<br>If OpenTransport for WinSock fails, it will return one of the following errors:<br>0x8014 Error getting addresses from WinSock.DLL<br>0x8100 System was out of memory, executable file was corrupt, or relocations were invalid. <br>
0x8101 Unused<br>0x8102 File was not found. <br>0x8103 Path was not found. <br>0x8104 Unused<br>0x8105 Attempt was made to dynamically link to a task, or there was a sharing or network-protection error. <br>0x8106 Library required separate data segments for each task. <br>
0x8107  Unused<br>0x8108 There was insufficient memory to start the application. <br>0x8109  Unused<br>0x810A Windows version was incorrect. <br>0x810B Executable file was invalid. Either it was not a Windows application or there was an error in the .EXE image. <br>
0x810C Application was designed for a different operating system. <br>0x810D Application was designed for MS-DOS 4.0. <br>0x810E Type of executable file was unknown. <br>0x810F Attempt was made to load a real-mode application (developed for an earlier version of Windows). <br>
0x8110 Attempt was made to load a second instance of an executable file containing multiple data segments that were not marked read-only. <br>0x8111 Unused<br>0x8112 Unused<br>0x8113 Attempt was made to load a compressed executable file. The file must be decompressed before it can be loaded. <br>
0x8114 Dynamic-link library (DLL) file was invalid. One of the DLLs required to run this application was corrupt. <br>0x8115 Application requires Microsoft Windows 32-bit extensions. <br>0x8116-0x811F Unused<br>*/<br>             </div>

<div>/* Warnings */<br>#define HEIW_FIRST_WARNING     0x2000 /* Number for First Error */<br>#define HEIW_LAST_WARNING     0x2FFF /* Number for Last Error */<br>#define HEIW_RETRY       0x2000 /* One or more retrys have occurred. */</div>

<div><br>/* These are masks for values returned from HEIReadIO and/or HEIWriteIO and indicate that some  */<br>/* error/warning/info condition exists for some module in the base (it could be an I/O  */<br>/* module or it could be the ethernet module.  The function HEIReadModuleStatus can then be used  */<br>
/* to retrieve the actual conditions.  Note that more than one of the conditions can exist at any time. */<br>#define MASK_DEVICE_ERROR   0x1000<br>#define MASK_DEVICE_WARNING    0x2000<br>#define MASK_DEVICE_INFO       0x4000</div>

<div><br>/* Data Types */<br>#define DT_IP_ADDRESS    0x0010 /* 4 Byte IP address */<br>#define DT_NODE_NUMBER    0x0020 /* 4 Byte Node Number */<br>#define DT_SUBNET_MASK    0x0030 /* 4 Byte Subnet Mask */<br>#define DT_GATEWAY_ADDRESS   0x0040 /* 4 Byte Gateway Address */<br>
#define DT_ERASE_COUNT    0x0050   /* 4 Byte used internally */</div>
<div>#define DT_SERIAL_SETUP    0x0011 /* 8 Byte Serial Setup (see SerialSetup)*/<br>#define DT_SET_PARM     0x8011 /* 8 Byte Parm Setup (see PARM_XXXX defines) */</div>
<div>#define DT_SETUP_ERROR_LIGHT  0x8012 /* 16 Byte Error Light Setup (see ErrorLightSetup) */</div>
<div>#define DT_STARTUP_SETTINGS  0x0013 /* 32 Byte Startup settings data (see StartupSettings above) */<br>#define DT_TIME_OF_DAY    0x8013 /* SYSTEMTIME structure */<br>#define DT_TYPE_STRING    0x0033 /* 32 Byte ASCII String for netedit type identification */</div>

<div>#define DT_ENCRYPT_KEY_FLASH  0x0014 /* 64 Byte key data from FALSH See Encryption structure */<br>#define DT_ENCRYPT_KEY_RAM   0x8014 /* 64 Byte key data from RAM - This is the working copy! */<br>              /* See Encryption structure */<br>
#define DT_MODULE_SETUP    0x0024 /* 64 Byte data from FLASH. See ModuleSetup structure */</div>
<div>#define DT_RXWX_SETTINGS   0x0015 /* 128 Bytes settings see HEISettings */<br>#define DT_SETTINGS     0x0015 /* 128 Bytes settings see HEISettings */<br>#define DT_DRIVE_SETUP    0x0025 /* 128 Byte DriveSetup structure */</div>

<div>#define DT_NODE_NAME     0x0016 /* 256 Byte Node Name */<br>#define DT_DESCRIPTION    0x0026 /* 256 Byte Node Description */<br>#define DT_LINK_MONITOR    0x8006 /* 256 Byte Link monitor setup (Ram Based) */<br>              /* See LinkMonitor structure below */<br>
#define DT_IP_SETUP     0x0036 /* 256 Byte IP Setup structure (see IPSetup) */<br>#define DT_WPLC_SYS_INFO   0x0046 /* 256 Byte WinPLC system info (see WPLCSystemInformation) */<br>#define DT_ERM_CONFIG    0x0056 /* 256 Byte ERM Config info (see sERMConfig) */<br>
#define DT_ERM_INFO     0x8016 /* 256 Byte ERM Info (see sERMInfo) */<br>#define DT_DEV_COMMAND    0x8026 /* 32 Byte ERM Command (see sDevCommand) */</div>
<div>#define DT_BASE_DEF     0x0017 /* 512 Byte Base Def (405 HEIWriteBaseDef) */<br>#define DT_RXWX_NODE_ADDR_1  0x0027 /* 512 Byte node address data for addr 00-31 */<br>#define DT_RXWX_NODE_ADDR_2  0x0037 /* 512 Byte node address data for addr 32-63 */<br>
#define DT_RXWX_NODE_ADDR_3  0x0047 /* 512 Byte node address data for addr 64-95 */</div>
<div>#define DT_R_W_IO_DEF    0x0057 /* 512 Byte read/write IO def (for Drive card) (base 0) (see MemoryItemBase) */</div>
<div>#define DT_ERM_DEV_00_03   0x0067 /* 512 Byte ERM device data (Devices numbers 00 - 03) (See sERMDevice) */<br>#define DT_ERM_DEV_04_07   0x0077 /* 512 Byte ERM device data (Devices numbers 04 - 07) (See sERMDevice) */<br>
#define DT_ERM_DEV_08_11   0x0087 /* 512 Byte ERM device data (Devices numbers 08 - 11) (See sERMDevice) */<br>#define DT_ERM_DEV_12_15   0x0097 /* 512 Byte ERM device data (Devices numbers 12 - 15) (See sERMDevice) */</div>

<div>#define DT_RESET      0x8010 /* 4 Byte (32-Bit) reset flag.  (RESET_XXX values below) */<br>#define DT_BOOT_OS     0x0023 /* 32 Byte OS Boot data */</div>
<div>#define DT_MODULE_INIT_BASE  0x8057 /* 512 Byte Module Initialization data: (from I/O Base) */</div>
<div> </div>
<div>/* Common functions. */<br>#define FUN_POLLING      0x00  /* Polling one module */<br>#define FUN_READ_VER_INFO   0x01  /* Read Version Info from module */<br>#define FUN_READ_SUPPORT_INFO  0x02  /* Read Support Info from module */<br>
           /* 0x03 UNUSED                         */<br>#define FUN_READ_DEVICE_INFO  0x04  /* Read Device Info from module */<br>#define FUN_POLLING_ALL    0x05  /* Polling all bases on the network (returns ethernet address) */<br>
           /* Used as a broadcast function to locate devices on the network. */<br>#define FUN_WRITE_IO    0x06  /* Write IO data to the base */<br>#define FUN_READ_IO     0x07  /* Read IO data from Base */<br>#define FUN_READ_BASE_DEF   0x08  /* Read Base Definition */<br>
#define FUN_QUERY_SETUP_DATA  0x09 /* Query the network for a particular type of data with a particular value */<br>#define FUN_ENUM_SETUP_DATA   0x0A /* Enumerate the types of data stored in a module */<br>#define FUN_READ_SETUP_DATA   0x0B /* Read a particular type of data from a module */<br>
#define FUN_WRITE_SETUP_DATA  0x0C /* Write a particular type of data to a module */<br>#define FUN_DELETE_SETUP_DATA  0x0D /* Delete a particular type of data from a module */<br>#define FUN_READ_ETHERNET_STATS  0x0E /* Read ethernet statistics from the module. */<br>
#define FUN_WRITE_BASE_DEF   0x0F /* Write Base Definition (305/405 EBC) */<br>           /* 0x10 UNUSED                         */<br>           /* 0x11 UNUSED                         */<br>           /* 0x12 UNUSED                         */<br>
           /* 0x13 UNUSED                         */<br>#define FUN_PET_LINK    0x14  /* Used to keep the link sense timer from firing in the absense of ReadIO or WriteIO messages */<br>#define FUN_ADDRESSED_BROADCAST  0x15 /* Used to broadcast to a particular ethernet address. Used to setup IP address in a new module. */<br>
#define FUN_DATA_BROADCAST   0x16 /* Used to broadcast to a particular data type. */<br>#define FUN_READ_MODULE_STATUS  0x17 /* Read the status bytes from each of the slots of the module. */<br>#define FUN_INIT_BASE_DEF   0x18 /* Initialize the base def by re-reading from the backplane */<br>
#define FUN_CCM_REQUEST    0x19 /* Perform a CCM Request with an ECom Module */<br>#define FUN_KSEQ_REQUEST   0x1A /* Perform a K-Seq Request with an ECom Module */<br>#define FUN_BACKPLANE_REQUEST  0x1B /* Perform a backplane request on an ECom Module */<br>
#define FUN_EXTEND_RESPONSE   0x1C  /* Extends the response packet. */</div>
<div>#define FUN_ACK      0x20 /* Acknowledge */<br>#define FUN_NAK      0x21 /* Not acknowledge */<br>#define FUN_RESPONSE    0x22 /* Response */</div>
<div>#define FUN_SERIAL_PORT    0x23 /* Execute serial port function (see below) */<br>#define FUN_WRITE_MEMORY   0x24 /* Write a particular memory type */<br>#define FUN_READ_MEMORY    0x25 /* Read a particular memory type */<br>
#define FUN_ENUM_MEMORY    0x26 /* Get list of all memory types */<br>#define FUN_ACCESS_MEMORY   0x27 /* Access (Read/Write) multiple memory types */</div>
<div>#define FUN_READ_SHARED_RAM   0x28 /* Read shared ram */<br>#define FUN_WRITE_SHARED_RAM  0x29 /* Write shared ram */<br>#define FUN_WRITE_IO_NO_READ  0x30 /* Write IO without returned read */</div>
<div>#define FUN_COMM_RESPONSE   0x31 /* Response to PLC generated COMM request */<br>#define FUN_COMM_REQ_ACK   0x32 /* Function from PLC generated COMM request */<br>#define FUN_COMM_NO_REQ_ACK  0x33 /* Function from PLC generated COMM request */<br>
#define FUN_RUN_PROGRAM    0x34 /* Function to execute a program */<br>#define FUN_REMOTE_API    0x35 /* Function to execute a function on remote device */</div>
<div>#define FUN_NOTIFY     0x36 /* Indicates a notification */<br>#define FUN_COMPLETION    0x37 /* Indicates completion of some activity */<br>#define FUN_PROXY      0x38 /* Indicates a proxy function request */<br>#define FUN_QUERY_RESPONSE   0x55 /* This is a response to a query function */</div>

<div>#define FUN_USER_CONFIG_PANEL    0x60    /* User specific data for AVG Panel */</div>
<div>#define FUN_WRITE_CONFIG_DATA  0x61  /* Write Config data to the base */<br>#define FUN_READ_CONFIG_DATA  0x62  /* Read Config data from Base */</div>
<div>#define FUN_UNSUPPORTED    0x99 /* This function will never be supported by any device (internal use only) */</div>
<div>#define FUN_SET_OS_LOAD    0xF9 /* Set Load OS Parm. */<br>#define FUN_REBOOT     0xFA /* Reboot OS   */</div>
<div><br>/* Serial port functions */<br>#define SPF_WRITE_COMM    0x01  /* Writes one or more characters to the serial port */<br>#define SPF_READ_COMM    0x02  /* Reads zero or more characters from the serial port */<br>
#define SPF_RX_AVAILABLE   0x03  /* Returns number of characters available in the input queue */<br>#define SPF_RX_FLUSH     0x04  /* Flushs the serial port input queue */<br>#define SPF_SETUP      0x05  /* Setup serial port (see SerialSetup above) */<br>
#define SPF_TX_LEFT     0x06  /* Returns number of characters left in the output queue */<br>#define SPF_READ_SETUP    0x07  /* Read Setup serial port (see SerialSetup above) */<br>#define SPF_ACCESS_COMM    0x08  /* Used to read / write multiple ports */<br>
#define SPF_TX_FLUSH     0x09  /* Flushs the serial port output queue */</div>
<div>/* Serial port commands for HEIAccessComm */<br>#define SPC_WRITE_PORT    0x01<br>#define SPC_READ_PORT    0x02<br>#define SPC_RX_FLUSH     0x04<br>#define SPC_TX_FLUSH     0x09<br>#define SPC_ERROR      0x80<br>#define SPC_READ_RESPONSE   0x82<br>
#define SPC_DONE      0xFF</div>
<div>/* Reset values */<br>#define RESET_DRIVE_RELAY   0x01 /* Reset relay on ethernet drive card */</div>
<div>/* Parm values */<br>#define PARM_RETURN_SYS_ERRORS 0x01  </div>
<div><br>/*<br> Memory Types.<br> Description of memory types.<br> A memory type is a 16 bit value that is divided up as follows:<br>   FEDCBA9876543210<br>   PKAAFFFFTTTTUNNN<br>   ||| |   |   ||<br>   ||| |   |   ||-- Number: Index number from 0 to 7<br>
   ||| |   |   |<br>   ||| |   |   |-- Undefined (set to zero)<br>   ||| |   |<br>   ||| |   |-- Type: 0000 = General Purpose<br>   ||| |             0001 = Program<br>   ||| |             0010 = System<br>   ||| |             0011 = Timer<br>
   ||| |             0100 = Counter<br>   ||| |             0101 = Setup<br>   ||| |             0110 = Input<br>   ||| |             0111 = Output<br>   ||| |             1000 = Undefined <br>   ||| |             1001 = Undefined <br>
   ||| |             1010 = Undefined <br>   ||| |             1011 = Undefined <br>   ||| |             1100 = Undefined <br>   ||| |             1101 = Undefined <br>   ||| |             1110 = Undefined <br>   ||| |             1111 = Undefined <br>
   ||| |<br>   ||| |-- Format: 0000 = Bit<br>   |||             0001 = Byte<br>   |||             0010 = Word<br>   |||             0011 = DWord<br>   |||             0100 = Float<br>   |||             0101 = Undefined<br>
   |||             0110 = Undefined<br>   |||             0111 = Undefined<br>   |||             1000 = Undefined<br>   |||             1001 = Undefined <br>   |||             1010 = Undefined<br>   |||             1011 = Undefined<br>
   |||             1100 = Undefined<br>   |||             1101 = Undefined<br>   |||             1110 = Undefined<br>   |||             1111 = Undefined<br>   |||<br>   |||-- Access:  00 = Read / write<br>   ||             01 = Read Only<br>
   ||             10 = Write Only<br>   ||             11 = Undefined<br>   ||<br>   ||-- Kind of memory: 0 = Ram;  1 = Flash<br>   |<br>   |-- Protection:  1 = Protected;  0 = Not Protected<br>   <br>   <br>  Example:  <br>
   V-Memory in Koyo boxes (205/405) is General Purpose, WORD format, Read / Write, RAM.<br>   this would make the type be: 0000 0010 0000 0000 = 0200h = 512<br>   <br>   CR Memory in Koyo boxes is General Purpose, Bit format, Read / Write, RAM,<br>
   this would make the type be: 0000 0000 0000 0000 = 0000h = 0<br>   <br>   Scratch Pad Memory in Koyo boxes is System, Byte Format, Read / Write, RAM.<br>   this would make the type be: 0000 0001 0010 0000 = 0120h = 288<br>
   <br>   SP's in Koyo boxes is System, Bit Format, Read Only, RAM<br>   this would make the type be: 0001 0000 0010 0000 = 1020h = 4128<br>*/</div>
<div>#define MT_KOYO_V  0x0200  /* V-Memory */<br>#define MT_KOYO_C  0x0000  /* C-Memory */<br>#define MT_KOYO_Z  0x0120  /* Scratch Pad Memory */ <br>#define MT_KOYO_SP 0x1020  /* SP-Memory */</div>
<div>#define MT_DRIVE_FIRST 0x300  /* First memory type for Hitachi Drives */<br>#define MT_HITACHI_D 0x300   /* Hitachi Drive Memory: Monitoring functions */<br>#define MT_HITACHI_F 0x301   /* Hitachi Drive Memory: Basic Profile functions */<br>
#define MT_HITACHI_A 0x302   /* Hitachi Drive Memory: Standard functions */<br>#define MT_HITACHI_B 0x303   /* Hitachi Drive Memory: Fine tuning functions */<br>#define MT_HITACHI_C 0x304   /* Hitachi Drive Memory: Intelligent terminal functions */<br>
#define MT_HITACHI_H 0x305   /* Hitachi Drive Memory: Sensorless vector functions */<br>#define MT_HITACHI_O 0x306   /* Hitachi Drive Memory: Other functions */<br>#define MT_HITACHI_OP 0x307  /* Hitachi Drive Memory: Option Board */<br>
#define MT_HITACHI_R 0x308   /* Hitachi Drive Memory: Reference codes */</div>
<div>/* The following offsets can only be used with HEIReadMemory (not HEIAccessMemory) */<br>#define MT_INFO_OFFSET   0x100  /* Add MT_INFO_OFFSET to above MT_HITACHI_? types to get MemoryTypeInfo for the given ID */<br>
#define MT_VALID_IDS_OFFSET 0x200  /* Add MT_VALID_IDS_OFFSET to above MT_HITACHI_? types to get the valid Ids for the given memory type */<br>#define MT_MEMORY_TYPE_STRING 0x300  /* Add MT_MEMORY_TYPE_STRING to above MT_HITACHI_? types to get the string name for the memory type (use 128 byte length) */<br>
#define MT_DRIVE_STRING   0x400  /* Add MT_DRIVE_STRING to any of the MT_HITACHI_? types to get the string name for the current drive (use 32 byte length) */<br>#define MT_VERSION_STRING  0x500  /* Add MT_DRIVE_STRING to any of the MT_HITACHI_? types to get the version string current drive (use 32 byte length) */</div>

<div>typedef struct <br> {<br> DWORD MinVal;   /* Minimum value for this type */<br> DWORD MaxVal;   /* Maximum value for this type */<br> BYTE Magnitude;  /* Magnitude of type.  See MAG_XXXX values */<br> BYTE RunModeEdit; /* If TRUE, this field can be edited in run mode */<br>
 BYTE ReadOnly;  /* If TRUE, this field is read-only */<br> BYTE FieldType;  /* Type of memory.  see FIELD_XXXX values */<br> BYTE NumBits;   /* If FieldType == FIELD_BIT, this tells the number of bits */<br> BYTE StartBit;  /* If FieldType == FIELD_BIT, this tells the starting bit number */<br>
 BYTE  Size;    /* Internal size in bytes */<br> WORD  Addr;    /* Internal address */<br> BYTE Unused[13];  /* Unused */<br> WORD NameLength;  /* Length of pName (including null terminator) */<br> char Name[224];  /* Name string for the given memory type */<br>
 } MemoryTypeInfo;</div>
<div><br>typedef struct<br> {<br> WORD Type;<br> WORD Id;<br> } MemoryItem;</div>
<div>typedef struct<br> {<br> MemoryItem Items[16];<br> } MemoryItemSlot;</div>
<div>typedef struct<br> {<br> MemoryItemSlot Slot[8];<br> } MemoryItemBase;</div>
<div>#define FIELD_NORMAL  0<br>#define FIELD_CODE  1<br>#define FIELD_BIT   2</div>
<div>#define MAG_00001   0<br>#define MAG_00010   1<br>#define MAG_00100   2<br>#define MAG_01000   3</div>
<div><br>/* Hitachi Drive type defines */<br>#define L100 1<br>#define SJ100 2 <br>#define J300 3<br>#define SJ300 4</div>
<div>/* GS Drive type defines */<br>#define GS1  1<br>#define GS2  2<br>#define GS3  3<br>#define GS4  4</div>
<div>/* Defines for Data formats */<br>#define DF_BIT_IN   0x03<br>#define DF_BIT_OUT  0x04<br>#define DF_BYTE_IN  0x10<br>#define DF_BYTE_OUT  0x11<br>#define DF_WORD_IN  0x05<br>#define DF_WORD_OUT  0x06<br>#define DF_DWORD_IN  0x08<br>
#define DF_DWORD_OUT  0x09<br>#define DF_DOUBLE_IN  0x12<br>#define DF_DOUBLE_OUT 0x13<br>#define DF_FLOAT_IN  0x14<br>#define DF_FLOAT_OUT  0x15<br>#define DF_CONFIG   0x16</div>
<div><br>/* Data type defines for HX-ERM */<br>#define DATA_SIZE_INFO  0  /* Used to read the size info for     */<br>#define DATA_INPUT   1  /* Used to read/write all input data    */<br>#define DATA_OUTPUT   2  /* Used to read/write all output data    */<br>
#define DATA_DESCRIPTION 3  /* Used to read description/layout of I/O data */<br>#define DATA_COMMAND   4  /* Used to read/write to command buffer   */<br>#define DATA_ERMINFO   5  /* Used to read sERMInfo structure     */</div>

<div>/* Commands for the HX-ERM module */<br>#define COMMAND_PROCESS_IO      1<br>#define COMMAND_ABORT       2<br>#define COMMAND_PROCESS_COMMAND_BUFFER  3</div>
<div> </div>
<div>/* Restore structure alignment boundary */<br>#pragma pack()</div>
<div><br>#endif /* #if !defined(__HEI_H) */<br></div>
<div> </div>
<div> </div>
<div>#include "defs.h"<br>#include <memory.h><br>#include <malloc.h><br>#include "hei.h"</div>
<div>#define TimeDiff(StartTime, EndTime)  (((DWORD)EndTime > (DWORD)StartTime) ? ((DWORD)EndTime - (DWORD)StartTime) : ((DWORD)EndTime + ((DWORD)ULONG_MAX - (DWORD)StartTime) + 1))<br>DWORD HEIIGetCounter();</div>
<div>int GetResponseEx(HEIDevice *apDevice[], BYTE *apData[], WORD aSizeofData[], int aErrorCode[], int DeviceCount)<br> {<br> int Done = TRUE;<br> int idx = 0;</div>
<div> for(idx = 0; idx < DeviceCount; idx++)<br>  {<br>  /* Handle NULL device */<br>  if(!apDevice[idx])<br>   continue;</div>
<div>  if(aErrorCode[idx] == HEIE_NO_RESPONSE)<br>   {<br>   BYTE Buff[500];<br>   int BuffLen = sizeof(Buff);<br>   aErrorCode[idx] = HEIGetResponse(apDevice[idx], Buff, &BuffLen, TRUE);</div>
<div>   /* If no response, continue */<br>   if(aErrorCode[idx] == HEIE_NO_RESPONSE)<br>    {<br>    Done = FALSE;<br>    continue;<br>    }</div>
<div>   /* Check for error and not warning. */<br>   if(aErrorCode[idx] && !(aErrorCode[idx] & HEIW_FIRST_WARNING))<br>    {<br>    /* Set data size to 0 */<br>    aSizeofData[idx] = 0;<br>    }<br>   else<br>
    {<br>    if(BuffLen)<br>     {<br>     short int *pInt = (short int *)&Buff[PACKET_HEADER_SIZE];</div>
<div>     BuffLen -= PACKET_HEADER_SIZE;<br>     BuffLen -= 2;</div>
<div>     if((WORD)BuffLen > aSizeofData[idx])<br>      {<br>      BuffLen = aSizeofData[idx];<br>      aErrorCode[idx] = HEIE_BUFFER_TOO_SMALL;<br>      }</div>
<div>     if(*pInt)<br>      aErrorCode[idx] = (*pInt) | 0x8000;</div>
<div>     memcpy(apData[idx], Buff+PACKET_HEADER_SIZE+2, BuffLen);<br>     aSizeofData[idx] = BuffLen;<br>     }<br>    else<br>     {<br>     /* Set data size to 0 */<br>     aSizeofData[idx] = 0;<br>     aErrorCode[idx] = HEIE_ZERO_BYTES_RECEIVED;<br>
     }<br>    }<br>   }<br>  }</div>
<div> return Done;<br> }</div>
<div>DWORD StartHEIReadIO(HEIDevice *pDevice, BYTE *pData, WORD *pSizeofData, int *pErrorCode)<br> {<br> DWORD StartTime = 0;<br> BOOL OldPP = FALSE;</div>
<div> /* Force parallel packet mode */<br> OldPP = pDevice->ParallelPackets;<br> pDevice->ParallelPackets = TRUE;</div>
<div> /* Init error code */<br> *pErrorCode = HEIE_NO_RESPONSE;</div>
<div> /* Log the time */<br> StartTime = HEIIGetCounter();</div>
<div> /* Send request */<br> HEIReadIO(pDevice, pData, pSizeofData);</div>
<div> /* Restore parallel packet mode */<br> pDevice->ParallelPackets = OldPP;</div>
<div> return StartTime;<br> }</div>
<div>__declspec(dllexport) int HEIReadIOEx<br> (<br> HEIDevice *apDevice[], <br> BYTE *apData[], <br> WORD aSizeofData[], <br> int aErrorCode[], <br> int DeviceCount<br> )<br> {<br> int idx = 0;<br> BOOL Done = FALSE;<br>
 DWORD *pStartTime = (DWORD *)calloc(sizeof(DWORD), DeviceCount);<br> int MaxStarted = 0;<br> int StartAt = 0;</div>
<div> /* Reset retry count */<br> for(idx = 0; idx < DeviceCount; idx++)<br>  if(apDevice[idx])<br>   apDevice[idx]->SizeOfData = 0;</div>
<div> while(!Done)<br>  {<br>  /* Start a request */<br>  for(idx = StartAt; idx < DeviceCount; idx++)<br>   {<br>   /* Handle NULL device */<br>   if(!apDevice[idx])<br>    {<br>    StartAt = idx + 1;<br>    if(idx+1 > MaxStarted)<br>
     MaxStarted = idx + 1;<br>    }<br>   /* If request not started, start it */<br>   else if(!pStartTime[idx])<br>    {<br>    pStartTime[idx] = StartHEIReadIO(apDevice[idx], apData[idx], &aSizeofData[idx], &aErrorCode[idx]);<br>
    StartAt = idx + 1;<br>    if(idx+1 > MaxStarted)<br>     MaxStarted = idx + 1;<br>    break;<br>    }<br>   }</div>
<div>  /* Test for completion of requests */<br>  GetResponseEx(apDevice, apData, aSizeofData, aErrorCode, MaxStarted);</div>
<div>  /* When all have been started, we're done until proven otherwise */<br>  Done = MaxStarted == DeviceCount;<br>  <br>  /* Test for timeout of requests */<br>  for(idx = 0; idx < MaxStarted; idx++)<br>   {<br>
   /* Handle NULL device */<br>   if(!apDevice[idx])<br>    continue;</div>
<div>   /* If request started, test timeout */<br>   if(aErrorCode[idx] == HEIE_NO_RESPONSE && pStartTime[idx])<br>    {<br>    /* Check timeout for device */<br>    if(TimeDiff(pStartTime[idx], HEIIGetCounter()) >= apDevice[idx]->Timeout)<br>
     {<br>     /* Timed out, check retries */<br>     if(apDevice[idx]->SizeOfData < apDevice[idx]->Retrys)<br>      {<br>      apDevice[idx]->SizeOfData++;<br>      apDevice[idx]->RetryCount++;</div>
<div>      /* Reset */<br>      pStartTime[idx] = 0;<br>      aErrorCode[idx] == HEIE_NO_RESPONSE;</div>
<div>      if(idx < StartAt)<br>       StartAt = idx;<br>      <br>      /* Not done */<br>      Done = FALSE;<br>      }<br>     /* No more retries */<br>     else<br>      {<br>      /* Set error code */<br>      aErrorCode[idx] = HEIE_TIMEOUT;<br>
      <br>      /* This device is done */<br>      }<br>     }<br>    /* Started but not timed out */<br>    else<br>     /* Not done */<br>     Done = FALSE;<br>    }<br>   /* If not started... */<br>   else if(!pStartTime[idx])<br>
    {<br>    /* Can't be done */<br>    Done = FALSE;<br>    }<br>   }<br>  }</div>
<div> free(pStartTime);</div>
<div> return 0;<br> }</div>
<div>DWORD StartHEIWriteIO(HEIDevice *pDevice, BYTE *pData, WORD SizeofData, BYTE *pReturnData, WORD *pSizeofReturnData, int *pErrorCode)<br> {<br> DWORD StartTime = 0;<br> BOOL OldPP = FALSE;</div>
<div> /* Force parallel packet mode */<br> OldPP = pDevice->ParallelPackets;<br> pDevice->ParallelPackets = TRUE;</div>
<div> /* Init error code */<br> *pErrorCode = HEIE_NO_RESPONSE;</div>
<div> /* Log the time */<br> StartTime = HEIIGetCounter();</div>
<div> /* Send request */<br> HEIWriteIO(pDevice, pData, SizeofData, pReturnData, pSizeofReturnData);</div>
<div> /* Restore parallel packet mode */<br> pDevice->ParallelPackets = OldPP;</div>
<div> return StartTime;<br> }</div>
<div>__declspec(dllexport) int HEIWriteIOEx<br> (<br> HEIDevice *apDevice[], <br> BYTE *apData[], <br> WORD aSizeofData[], <br> BYTE *apReturnData[], <br> WORD aSizeofReturnData[], <br> int aErrorCode[], <br> int DeviceCount<br>
 )<br> {<br> int idx = 0;<br> BOOL Done = FALSE;<br> DWORD *pStartTime = (DWORD *)calloc(sizeof(DWORD), DeviceCount);<br> int MaxStarted = 0;<br> int StartAt = 0;</div>
<div> /* Reset retry count */<br> for(idx = 0; idx < DeviceCount; idx++)<br>  if(apDevice[idx])<br>   apDevice[idx]->SizeOfData = 0;</div>
<div> while(!Done)<br>  {<br>  /* Start a request */<br>  for(idx = StartAt; idx < DeviceCount; idx++)<br>   {<br>   /* Handle NULL device */<br>   if(!apDevice[idx])<br>    {<br>    StartAt = idx + 1;<br>    if(idx+1 > MaxStarted)<br>
     MaxStarted = idx + 1;<br>    }<br>   /* If request not started, start it */<br>   else if(!pStartTime[idx])<br>    {<br>    pStartTime[idx] = StartHEIWriteIO(apDevice[idx], apData[idx], aSizeofData[idx], apReturnData[idx], &aSizeofReturnData[idx], &aErrorCode[idx]);<br>
    StartAt = idx + 1;<br>    if(idx+1 > MaxStarted)<br>     MaxStarted = idx + 1;<br>    break;<br>    }<br>   }</div>
<div>  /* Test for completion of requests */<br>  GetResponseEx(apDevice, apReturnData, aSizeofReturnData, aErrorCode, MaxStarted);</div>
<div>  /* When all have been started, we're done until proven otherwise */<br>  Done = MaxStarted == DeviceCount;<br>  <br>  /* Test for timeout of requests */<br>  for(idx = 0; idx < MaxStarted; idx++)<br>   {<br>
   /* Handle NULL device */<br>   if(!apDevice[idx])<br>    continue;</div>
<div>   /* If request started, test timeout */<br>   if(aErrorCode[idx] == HEIE_NO_RESPONSE && pStartTime[idx])<br>    {<br>    /* Check timeout for device */<br>    if(TimeDiff(pStartTime[idx], HEIIGetCounter()) >= apDevice[idx]->Timeout)<br>
     {<br>     /* Timed out, check retries */<br>     if(apDevice[idx]->SizeOfData < apDevice[idx]->Retrys)<br>      {<br>      apDevice[idx]->SizeOfData++;<br>      apDevice[idx]->RetryCount++;</div>
<div>      /* Reset */<br>      pStartTime[idx] = 0;<br>      aErrorCode[idx] == HEIE_NO_RESPONSE;</div>
<div>      if(idx < StartAt)<br>       StartAt = idx;<br>      <br>      /* Not done */<br>      Done = FALSE;<br>      }<br>     /* No more retries */<br>     else<br>      {<br>      /* Set error code */<br>      aErrorCode[idx] = HEIE_TIMEOUT;<br>
      <br>      /* This device is done */<br>      }<br>     }<br>    /* Started but not timed out */<br>    else<br>     /* Not done */<br>     Done = FALSE;<br>    }<br>   /* If not started... */<br>   else if(!pStartTime[idx])<br>
    {<br>    /* Can't be done */<br>    Done = FALSE;<br>    }<br>   }<br>  }</div>
<div> free(pStartTime);</div>
<div> return 0;<br> }<br> <br>#if 0<br>int GetResponseEx(HEIDevice *apDevice[], BYTE *apData[], WORD aSizeofData[], int aErrorCode[], int DeviceCount)<br> {<br> int Done = TRUE;<br> int idx = 0;</div>
<div> for(idx = 0; idx < DeviceCount; idx++)<br>  {<br>  /* Handle NULL device */<br>  if(!apDevice[idx])<br>   continue;</div>
<div>  if(aErrorCode[idx] == HEIE_NO_RESPONSE)<br>   {<br>   BYTE Buff[500];<br>   int BuffLen = sizeof(Buff);<br>   aErrorCode[idx] = HEIGetResponse(apDevice[idx], Buff, &BuffLen, TRUE);</div>
<div>   /* If no response, continue */<br>   if(aErrorCode[idx] == HEIE_NO_RESPONSE)<br>    {<br>    Done = FALSE;<br>    continue;<br>    }</div>
<div>   /* Check for error and not warning. */<br>   if(aErrorCode[idx] && !(aErrorCode[idx] & HEIW_FIRST_WARNING))<br>    {<br>    /* Set data size to 0 */<br>    aSizeofData[idx] = 0;<br>    }<br>   else<br>
    {<br>    if(BuffLen)<br>     {<br>     short int *pInt = (short int *)&Buff[PACKET_HEADER_SIZE];</div>
<div>     BuffLen -= PACKET_HEADER_SIZE;<br>     BuffLen -= 2;</div>
<div>     if((WORD)BuffLen > aSizeofData[idx])<br>      {<br>      BuffLen = aSizeofData[idx];<br>      aErrorCode[idx] = HEIE_BUFFER_TOO_SMALL;<br>      }</div>
<div>     if(*pInt)<br>      aErrorCode[idx] = (*pInt) | 0x8000;</div>
<div>     memcpy(apData[idx], Buff+PACKET_HEADER_SIZE+2, BuffLen);<br>     aSizeofData[idx] = BuffLen;<br>     }<br>    else<br>     {<br>     /* Set data size to 0 */<br>     aSizeofData[idx] = 0;<br>     aErrorCode[idx] = HEIE_ZERO_BYTES_RECEIVED;<br>
     }<br>    }<br>   }<br>  }</div>
<div> return Done;<br> }</div>
<div>__declspec(dllexport) int HEIReadIOEx<br> (<br> HEIDevice *apDevice[], <br> BYTE *apData[], <br> WORD aSizeofData[], <br> int aErrorCode[], <br> int DeviceCount, <br> DWORD Timeout<br> )<br> {<br> DWORD StartTime = HEIIGetCounter();<br>
 int idx = 0;<br> BOOL Done = FALSE;<br> BOOL OldPP = FALSE;</div>
<div> for(idx = 0; idx < DeviceCount; idx++)<br>  {<br>  /* Handle NULL device */<br>  if(!apDevice[idx])<br>   continue;</div>
<div>  /* Force parallel packet mode */<br>  OldPP = apDevice[idx]->ParallelPackets;<br>  apDevice[idx]->ParallelPackets = TRUE;</div>
<div>  /* Init error code */<br>  aErrorCode[idx] = HEIE_NO_RESPONSE;</div>
<div>  /* Send request */<br>  HEIReadIO(apDevice[idx], apData[idx], &aSizeofData[idx]);</div>
<div>  /* Check for response */<br>  GetResponseEx(apDevice, apData, aSizeofData, aErrorCode, idx+1);</div>
<div>  /* Restore parallel packet mode */<br>  apDevice[idx]->ParallelPackets = OldPP;<br>  }</div>
<div> /* Spin on GetResponseEx waiting for timeout */<br> while(!Done)<br>  {<br>  Done = GetResponseEx(apDevice, apData, aSizeofData, aErrorCode, idx);<br>  if(TimeDiff(StartTime, HEIIGetCounter()) >= Timeout)<br>   return HEIE_TIMEOUT;<br>
  }</div>
<div> return 0;<br> }</div>
<div>__declspec(dllexport) int HEIWriteIOEx<br> (<br> HEIDevice *apDevice[], <br> BYTE *apData[], <br> WORD aSizeofData[], <br> BYTE *apReturnData[], <br> WORD aSizeofReturnData[], <br> int aErrorCode[], <br> int DeviceCount, <br>
 DWORD Timeout<br> )<br> {<br> DWORD StartTime = HEIIGetCounter();<br> int idx = 0;<br> BOOL Done = FALSE;<br> BOOL OldPP = FALSE;</div>
<div> for(idx = 0; idx < DeviceCount; idx++)<br>  {<br>  /* Handle NULL device */<br>  if(!apDevice[idx])<br>   continue;</div>
<div>  /* Force parallel packet mode */<br>  OldPP = apDevice[idx]->ParallelPackets;<br>  apDevice[idx]->ParallelPackets = TRUE;</div>
<div>  /* Init error code */<br>  aErrorCode[idx] = HEIE_NO_RESPONSE;</div>
<div>  /* Send request */<br>  HEIWriteIO(apDevice[idx], apData[idx], aSizeofData[idx], apReturnData[idx], &aSizeofReturnData[idx]);</div>
<div>  /* Check for response */<br>  GetResponseEx(apDevice, apReturnData, aSizeofReturnData, aErrorCode, idx+1);</div>
<div>  /* Restore parallel packet mode */<br>  apDevice[idx]->ParallelPackets = OldPP;<br>  }</div>
<div> /* Spin on GetResponseEx waiting for timeout */<br> while(!Done)<br>  {<br>  Done = GetResponseEx(apDevice, apReturnData, aSizeofReturnData, aErrorCode, idx);<br>  if(TimeDiff(StartTime, HEIIGetCounter()) >= Timeout)<br>
   return HEIE_TIMEOUT;<br>  }</div>
<div> return 0;<br> }<br>#endif</div>
<div> </div>
<div>/*<br>** HEI.C - Platform dependent code for communicating with Host Automation Products<br>**   line of ethernet modules using the WinSock transport.<br>** <br>** Copyright (C) - 1996-1998 Host Automation Products, Inc.<br>
**<br>*/<br>#include "winsock.h"  /* Needed for winsock calls */<br>#include "wsipx.h"   /* Needed for winsock IPX calls */<br>#include "mmsystem.h"  /* Needed for timer stuff */<br>#include "hei.h" <br>
#include <memory.h></div>
<div>/*<br>** Notes for porting code to another platform:<br>**<br>** This file contains the transport/system dependant code for use with the<br>** Host Ethernet Interface (HEI).  There are nine functions which must be<br>
** implemented by this code:<br>**<br>**  1) int HEIIOpen();<br>**  2) int HEIIClose();<br>**  3) int HEIIOpenTransport(HEITransport *pTransport);<br>**  4) int HEIICloseTransport(HEITransport *pTransport);<br>**  5) int HEIIOpenDevice(HEITransport *pTransport, HEIDevice *pDevice);<br>
**  6) int HEIICloseDevice(HEIDevice *pDevice);<br>**  7) int HEIIReceivePacket(HEIDevice *pDevice, BYTE *pResponse, int *pResponseSize);<br>**  8) int HEIISendPacket(HEIDevice *pDevice, BYTE *pPacket, WORD PacketSize);<br>
**  9) DWORD HEIIGetCounter();<br>**<br>** Make changes in this file, do not change HEI.C or any structures in HEI.H!  <br>** If you find that you must change something in HEI.C, contact the person<br>** you got this source from.<br>
**<br>** Feel free to remove any of the WinSock specific code from this module.<br>** <br>** To compile the code for ANSI C, ANSI_C must be defined!<br>**<br>** See all sections containing "TODO_FOR_OTHER_SYSTEM" for further details.<br>
**<br>*/</div>
<div><br>/* Counter for the number of times that OpenTransport has been called */<br>static int WinSockLoadCount = 0; </div>
<div>/* <br>** Windows version gets stored here.  It is used for setting winsock options <br>** Win 16 is slightly different than Win 32.<br>*/<br>WORD  WinVer=0;</div>
<div>/* This is the port number to use when talking to a module. */<br>#define PORT_ID 0x7070</div>
<div>/* This function should return a millisecond resolution tick counter. */<br>DWORD HEIIGetCounter()<br> {<br> /*return timeGetTime(); */<br> LARGE_INTEGER freq, count;<br> QueryPerformanceFrequency(&freq);<br> QueryPerformanceCounter(&count);<br>
 return (DWORD)((count.QuadPart * 1000) / freq.QuadPart);<br> }</div>
<div> </div>
<div>/* <br>** This function is called from within HEIOpen. It gives the opportunity<br>** to do initialization type stuff.  NOTE: This function may be called more<br>** than once!<br>**<br>** RETURNS:  0 on success<br>**           non-zero on error.<br>
*/<br>int HEIIOpen()<br> {<br> /* Save the windows version for later use. */<br> DWORD dwVersion = GetVersion();<br> WinVer = LOWORD(dwVersion);</div>
<div> /* <br> ** TODO_FOR_OTHER_SYSTEM <br> ** Do system level init stuff here.  <br> ** Be aware that this may be called more than once.<br> */<br> return HEIE_NULL;<br> }<br> <br>/* <br>** This function is called from within HEIClose. It gives the opportunity<br>
** to do shutdown type stuff.  NOTE: This function may be called more<br>** than once!<br>**<br>** RETURNS:  0 on success<br>**           non-zero on error.<br>*/<br>int HEIIClose() <br> {<br> /* <br> ** TODO_FOR_OTHER_SYSTEM <br>
 ** Do system level shut down stuff here.  <br> ** Be aware that this may be called more than once.<br> */<br> return HEIE_NULL; <br> } <br> <br>/*<br>** This function is called from within HEIOpenTransport.  It is used to prepare<br>
** the given Transport to be used in subsequent HEIOpenDevice calls.<br>**<br>** RETURNS:  0 on success<br>**           non-zero on error.<br>*/<br>int HEIIOpenTransport(HEITransport *pTransport)<br> { <br> switch (pTransport->Transport) <br>
  {<br>  case HEIT_WINSOCK:   /* Open Transport type HEIT_WINSOCK */<br>   {<br>   /* WinSock Transport. Protocol must be either IPX or IP */<br>   if (pTransport->Protocol == HEIP_IPX || pTransport->Protocol == HEIP_IP)<br>
    {<br>    /* Keep track of load count, Initialize winsock if zero. */<br>    if (!WinSockLoadCount)<br>     {<br>     WSADATA wsaData;<br>     WORD wVersionRequested = MAKEWORD(2, 0);<br>  <br>     /* Initialize winsock dll */<br>
     if(WSAStartup(wVersionRequested, &wsaData) == SOCKET_ERROR)<br>      return WSAGetLastError();<br>     }</div>
<div>    WinSockLoadCount++;<br>    }<br>   else<br>    return HEIE_UNSUPPORTED_PROTOCOL;<br>   break;<br>   }<br>   <br>  case HEIT_OTHER_TRANSPORT:<br>   {<br>   /* <br>   ** TODO_FOR_OTHER_SYSTEM <br>   ** Do one time init stuff by keeping track of the number of times this<br>
   ** transport has been opened.<br>   ** Don't return HEIE_UNSUPPORTED_TRANSPORT<br>   */<br>   return HEIE_UNSUPPORTED_TRANSPORT;<br>   }<br>  <br>  default:<br>   return HEIE_UNSUPPORTED_TRANSPORT;<br>  }<br>  <br>
 return HEIE_NULL;<br>   }<br>   <br>   <br>/*<br>** This function is called from within HEICloseTransport.  It indicates<br>** that the given Transport is no longer in use.<br>**<br>** RETURNS:  0 on success<br>**           non-zero on error.<br>
*/<br>int HEIICloseTransport(HEITransport *pTransport)<br> {<br> switch (pTransport->Transport) <br>  {<br>  case HEIT_WINSOCK:      /* Close Transport type HEIT_WINSOCK */<br>   {<br>   /* WinSock Transport. Protocol must be IPX or IP */<br>
   if (pTransport->Protocol == HEIP_IPX || pTransport->Protocol == HEIP_IP)<br>    {<br>    /* Decrement load count.  Shut down WinSock if zero */<br>    if (WinSockLoadCount)<br>     {<br>     WinSockLoadCount--;</div>

<div>     if (!WinSockLoadCount)<br>      WSACleanup();<br>     }<br>    }<br>   else<br>    return HEIE_UNSUPPORTED_PROTOCOL; <br>    <br>   break;<br>   }<br>   <br>  case HEIT_OTHER_TRANSPORT:<br>   {<br>   /* <br>   ** TODO_FOR_OTHER_SYSTEM <br>
   ** Decrement load counter, do cleanup stuff if zero.<br>   ** Don't return HEIE_UNSUPPORTED_TRANSPORT<br>   */<br>   return HEIE_UNSUPPORTED_TRANSPORT;<br>   }<br>  <br>  default:<br>   return HEIE_UNSUPPORTED_TRANSPORT;<br>
  }<br>  <br> return HEIE_NULL; <br>   }<br>   <br>   <br>/*<br>** This function is called from within HEIOpenDevice.  It is used to prepare<br>** the given Device to be used with the given Transprot.<br>**<br>** RETURNS:  0 on success<br>
**           non-zero on error.<br>*/<br>int HEIIOpenDevice(HEITransport *pTransport, HEIDevice *pDevice)<br> {<br> switch (pTransport->Transport) <br>  {<br>  case HEIT_WINSOCK:  /* Open Device type HEIT_WINSOCK */<br>
   {<br>   /* WinSock Transport. */<br>   SOCKET sock;<br>   struct sockaddr *pRemAddr, *pMyAddr;<br>   int SizeRemAddr, SizeMyAddr;<br>   u_long NonBlockingMode;</div>
<div>   if (pTransport->Protocol == HEIP_IPX)<br>    {<br>    static SOCKADDR_IPX RemAddr, MyAddr;</div>
<div>    /* Initialize remote address */<br>    if (!pDevice->UseBroadcast)<br>     memcpy(&RemAddr, pDevice->Address.Raw, sizeof(SOCKADDR_IPX));</div>
<div>    if (pTransport->pSourceAddress)<br>     {<br>     MyAddr.sa_family = pTransport->pSourceAddress->AddressIPX.Family;<br>     memcpy(MyAddr.sa_netnum, pTransport->pSourceAddress->AddressIPX.Netnum, 4);<br>
     memcpy(MyAddr.sa_nodenum, pTransport->pSourceAddress->AddressIPX.Nodenum, 6);<br>     MyAddr.sa_socket = pTransport->pSourceAddress->AddressIPX.Socket;<br>     }<br>    else<br>     {<br>     /* Initialize MyAddr to all zeros so that windows can tell me who I am! */<br>
     MyAddr.sa_family = AF_IPX;<br>     /*memcpy(MyAddr.sa_netnum, &pTransport->NetworkAddress, 4);*/<br>     memset(MyAddr.sa_netnum, 0, 4);<br>     memset(MyAddr.sa_nodenum, 0, 6);<br>     MyAddr.sa_socket = 0x00;<br>
     }</div>
<div>    /* get socket handle */<br>    sock = socket(AF_IPX,        /* IPX family */<br>         SOCK_DGRAM,    /* Datagram */<br>         NSPROTO_IPX);  </div>
<div>    pRemAddr = (struct sockaddr *) &RemAddr;<br>    pMyAddr = (struct sockaddr *) &MyAddr;<br>    SizeRemAddr = sizeof(RemAddr);<br>    SizeMyAddr = sizeof(MyAddr);<br>    }<br>   else if (pTransport->Protocol == HEIP_IP)<br>
    {<br>    static struct sockaddr_in RemAddr, MyAddr;</div>
<div>    /*<br>    ** If Protocol is IP and we are not using broadcast, and <br>    ** Address.Raw[19] == 1 then the IP address in the module<br>    ** is undefined.<br>    */<br>    if (!pDevice->UseBroadcast && (pDevice->Address.Raw[19] == 1))<br>
     return HEIE_IP_ADDR_NOT_INITIALIZED;<br>     <br>    /* Initialize remote address */<br>    if (!pDevice->UseBroadcast)<br>     memcpy(&RemAddr, pDevice->Address.Raw, sizeof(RemAddr));</div>
<div>    if (pTransport->pSourceAddress)<br>     {<br>     MyAddr.sin_family = pTransport->pSourceAddress->AddressIP.Family;<br>     MyAddr.sin_port = pTransport->pSourceAddress->AddressIP.Port;<br>     MyAddr.sin_addr.s_addr = pTransport->pSourceAddress->AddressIP.AddressingType.lAddr;<br>
     }<br>    else<br>     {<br>     /* Initialize MyAddr to all zeros so that windows can tell me who I am! */<br>     MyAddr.sin_family = AF_INET;<br>     MyAddr.sin_port = 0;<br>     MyAddr.sin_addr.s_addr = 0;<br>     }</div>

<div>    /* get socket handle */<br>    sock = socket(AF_INET,       /* IP family */<br>         SOCK_DGRAM,    /* Datagram */<br>         IPPROTO_UDP);      </div>
<div>    pRemAddr = (struct sockaddr *) &RemAddr;<br>    pMyAddr = (struct sockaddr *) &MyAddr;<br>    SizeRemAddr = sizeof(RemAddr);<br>    SizeMyAddr = sizeof(MyAddr);<br>    }<br>   else <br>    return HEIE_UNSUPPORTED_PROTOCOL;</div>

<div><br>   if(sock == INVALID_SOCKET) <br>    return WSAGetLastError();</div>
<div>   if (bind (sock, pMyAddr, SizeMyAddr) == SOCKET_ERROR)<br>    {<br>    int Error = WSAGetLastError();<br>    closesocket(sock);<br>    return Error;<br>    } </div>
<div>   if (pDevice->UseBroadcast)<br>    {<br>    int rSetSockOpt;<br>      <br>    if (WinVer < 0x0332) /* Check for WinVer < 3.50 */<br>     {<br>     /* 16 Bit uses int type. */<br>     int AllowBroadcast = TRUE;<br>
     rSetSockOpt = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const char *) &AllowBroadcast, sizeof(AllowBroadcast));<br>     }<br>    else<br>     {<br>     /* 32 Bit uses long type. */<br>     long AllowBroadcast = TRUE;<br>
     rSetSockOpt = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const char *) &AllowBroadcast, sizeof(AllowBroadcast));<br>     }<br>    <br>    if (rSetSockOpt == SOCKET_ERROR)<br>     {<br>     int Error = WSAGetLastError();<br>
     closesocket(sock);<br>     return Error;<br>     }<br>    }<br>   else<br>    {<br>    if (connect (sock, pRemAddr, SizeRemAddr) == SOCKET_ERROR)<br>     {<br>     int Error = WSAGetLastError();<br>     closesocket(sock);<br>
     return Error;<br>     } <br>    }</div>
<div>   /* Setup for non-blocking mode */<br>   NonBlockingMode = 1;</div>
<div>   if (ioctlsocket (sock, FIONBIO, &NonBlockingMode) == SOCKET_ERROR)<br>    {<br>    int Error = WSAGetLastError();<br>    closesocket(sock);<br>    return Error;<br>    }<br>   <br>   pDevice->_dwParam = (DWORD) sock;<br>
   break;<br>   }<br>   <br>  case HEIT_OTHER_TRANSPORT:<br>   {<br>   /* <br>   ** TODO_FOR_OTHER_SYSTEM <br>   ** Prepare to communicate with the given device.<br>   ** The address to talk to is stored in pDevice->Address (see HEI.H for format)<br>
   ** Be aware that pDevice->UseBroadcast indicates that we<br>   ** will be broadcasting to the module.<br>   ** For IP, pDevice->Address.Raw[19] == 1 (after a query)<br>   ** if the given module's IP address is not initialized.  In<br>
   ** this case, the only way to talk to it (using IP) is by <br>   ** using addressed broadcast.<br>   ** You can use pDevice->_dwParam to store whatever (such as<br>   ** a socket number).<br>   ** Don't return HEIE_UNSUPPORTED_TRANSPORT<br>
   */<br>   return HEIE_UNSUPPORTED_TRANSPORT;<br>   }<br>  <br>  default:<br>   return HEIE_UNSUPPORTED_TRANSPORT;<br>  }<br>  <br> return HEIE_NULL;<br> }</div>
<div> <br>/*<br>** This function is called from within HEICloseDevice.  It indicates<br>** that the given Device is no longer in use.<br>**<br>** RETURNS:  0 on success<br>**           non-zero on error.<br>*/<br>int HEIICloseDevice(HEIDevice *pDevice)<br>
 {<br> switch (pDevice->_pTransport->Transport) <br>  {<br>  case HEIT_WINSOCK:  /* Close Device type HEIT_WINSOCK */<br>   {<br>   /* WinSock Transport. */<br>   if (pDevice->_pTransport->Protocol == HEIP_IPX || pDevice->_pTransport->Protocol == HEIP_IP)<br>
    {<br>    SOCKET sock = (SOCKET) pDevice->_dwParam;<br>      <br>    if (closesocket(sock) == SOCKET_ERROR)<br>     return WSAGetLastError();<br>    }<br>   else<br>    return HEIE_UNSUPPORTED_PROTOCOL;</div>
<div>   break;<br>   }<br>   <br>  case HEIT_OTHER_TRANSPORT:<br>   {<br>   /* <br>   ** TODO_FOR_OTHER_SYSTEM<br>   ** Do device type shutdown stuff.<br>   ** Don't return HEIE_UNSUPPORTED_TRANSPORT<br>   */<br>   return HEIE_UNSUPPORTED_TRANSPORT;<br>
   }<br>  <br>  default:<br>   return HEIE_UNSUPPORTED_TRANSPORT;<br>  }<br>    <br> return HEIE_NULL; <br> }<br> <br> <br>/*<br>** This is the code for receiving a packet from the ethernet driver for the given<br>**  device.  The response should be stored in the given response buffer - pResponse.<br>
**  On entry, pResponseSize contains the size of the response buffer (pResponse).<br>**  On exit, pResponseSize MUST contain the number of bytes copied to the response buffer.<br>**<br>** RETURNS:  0 on success<br>**           non-zero on error.<br>
*/<br>int HEIIReceivePacket(HEIDevice *pDevice, BYTE *pResponse, int *pResponseSize)<br> {<br> int Retval = HEIE_NULL;<br> <br> switch (pDevice->_pTransport->Transport) <br>  {<br>  case HEIT_WINSOCK:  /* GetResponse from HEIT_WINSOCK */<br>
   {<br>   int NumBytes;<br>   SOCKET sock = (SOCKET) pDevice->_dwParam;<br>   <br>   if (pDevice->UseBroadcast)<br>    {<br>    struct sockaddr FromAddr;<br>    int FromLen = sizeof(FromAddr);<br>  <br>    NumBytes = recvfrom(sock, (char *) pResponse, *pResponseSize, 0, &FromAddr, &FromLen);<br>
    <br>    if (pDevice->pData)<br>     {<br>     /* Need to copy FROM address. */<br>     int Num2Copy = FromLen;<br>   <br>     if (pDevice->SizeOfData < Num2Copy)<br>      {<br>      Retval = HEIE_BUFFER_TOO_SMALL;<br>
      Num2Copy = pDevice->SizeOfData;<br>      }<br>   <br>     memcpy(pDevice->pData, &FromAddr, Num2Copy);     <br>     }<br>    }<br>   else<br>    {<br>    NumBytes = recv(sock, (char *) pResponse, *pResponseSize, 0);<br>
    }<br>   <br>   if (NumBytes == SOCKET_ERROR)<br>    {<br>    /* Check to see if the error is WSAWOULDBLOCK. */<br>    int Error = WSAGetLastError();<br>  <br>    if (Error != WSAEWOULDBLOCK)<br>     {<br>     *pResponseSize = 0;<br>
     Retval = Error;<br>     }<br>    else<br>     {<br>     Retval = HEIE_NO_RESPONSE;<br>     }<br>    }<br>   else<br>    {<br>    (*pResponseSize) = NumBytes;<br>    }<br>   <br>   break;<br>   }</div>
<div>  case HEIT_OTHER_TRANSPORT:<br>   {<br>   /* <br>   ** TODO_FOR_OTHER_SYSTEM <br>   ** Receive a packet for the given device into the buffer pResponse.<br>   ** *pResponseSize indicates the length of the pResponse buffer.<br>
   ** If pDevice->UseBroadcast && pDevice->pData, <br>   ** then we need to copy the FROM address into pDevice->pData.<br>   ** pDevice->SizeOfData tells how long the buffer pDevice->pData is.<br>   ** Store the number of bytes received in (*pResponseSize).<br>
   ** Don't return HEIE_UNSUPPORTED_TRANSPORT<br>   */<br>   return HEIE_UNSUPPORTED_TRANSPORT;<br>   }<br>  <br>  default:<br>   return HEIE_UNSUPPORTED_TRANSPORT;<br>  }<br>  <br> return Retval;<br> }             <br>
 <br> <br>/*<br>** This is the code for sending the given packet for the given device.<br>** pPacket is the pointer to the actual packet data, and PacketSize is the<br>** number of bytes in the packet to be sent.<br>**<br>
** RETURNS:  0 on success<br>**           non-zero on error.<br>*/<br>int HEIISendPacket(HEIDevice *pDevice, BYTE *pPacket, WORD PacketSize)<br> {<br> switch (pDevice->_pTransport->Transport) <br>  {<br>  case HEIT_WINSOCK:   /* Send packet of type HEIT_WINSOCK */<br>
   {<br>   /* WinSock Transport. */<br>   SOCKET sock = (SOCKET) pDevice->_dwParam;</div>
<div>   if (pDevice->UseBroadcast)<br>    {<br>    /* Initialize remote address */<br>    struct sockaddr *pRemAddr = (struct sockaddr *) NULL;<br>    int SizeRemAddr = 0;</div>
<div>    if (pDevice->_pTransport->Protocol == HEIP_IP)<br>     {<br>     static struct sockaddr_in RemAddr;<br>  <br>     RemAddr.sin_family = AF_INET;<br>     RemAddr.sin_port = PORT_ID;<br>     RemAddr.sin_addr.s_addr = INADDR_BROADCAST;<br>
  <br>     pRemAddr = (struct sockaddr *) &RemAddr;<br>     SizeRemAddr = sizeof(RemAddr);<br>     }<br>    else if (pDevice->_pTransport->Protocol == HEIP_IPX)<br>     {<br>     static SOCKADDR_IPX RemAddr;<br>
  <br>     RemAddr.sa_family = AF_IPX;<br>     memset(RemAddr.sa_netnum, 0, 4);<br>     memset(RemAddr.sa_nodenum, 0xFF, 6);<br>     RemAddr.sa_socket = PORT_ID;</div>
<div>     if (pDevice->_pTransport->pSourceAddress)<br>      memcpy(RemAddr.sa_netnum, pDevice->_pTransport->pSourceAddress->AddressIPX.Netnum, 4);<br>      /*memcpy(RemAddr.sa_netnum, &pDevice->_pTransport->NetworkAddress, 4);*/<br>
  <br>     pRemAddr = (struct sockaddr *) &RemAddr;<br>     SizeRemAddr = sizeof(RemAddr);<br>     }</div>
<div>    if (sendto(sock, (char *) pPacket, PacketSize, 0, pRemAddr, SizeRemAddr) == SOCKET_ERROR)<br>     return  WSAGetLastError();<br>    }<br>   else<br>    {<br>    if (send(sock, (char *) pPacket, PacketSize, 0) == SOCKET_ERROR)<br>
     return  WSAGetLastError();<br>    }<br>   <br>   return HEIE_NULL;<br>   }</div>
<div>  case HEIT_OTHER_TRANSPORT:<br>   {<br>   /* <br>   ** TODO_FOR_OTHER_SYSTEM <br>   ** Send a packet to the given device.<br>   ** If pDevice->UseBroadcast, then we need to broadcast the packet.<br>   ** Don't return HEIE_UNSUPPORTED_TRANSPORT<br>
   */<br>   return HEIE_UNSUPPORTED_TRANSPORT;<br>   }<br>  <br>  default:<br>   return HEIE_UNSUPPORTED_TRANSPORT;<br>  }<br> } </div>
<div> <br><br></div>
<div> </div>
<div> </div>
<div> </div>