[C con Clase] Codigo fuente de PLC Direct soft, como se hace un script fastAGI para que me controle las salidas del plc desde asterisk?
Jorge Vega Sanchez
memmaker650 en gmail.com
Dom Mayo 2 11:38:59 CEST 2010
No sé si me estoy pasando. Pero creo que algo tan profesional esta
fuera de este Buzón de correo.
Esto es para dudas con C/C++ e interacciones con algunos S.O. como
mucho.
On 02/05/2010, at 4:33, Jose Sanchez wrote:
> Files included in this package:
> readme.txt - The file you are reading
> intrface.c - The file which should be changed to support a new
> transport
> hei.c - Common source for HEI functions
> hei.h - Header for HEI functions
> defs.h - Defines used by hei.c
> function.h - Defines used by hei.c
> /* Some usefull stuff! */
> #if !defined(_DEFS_H)
> #define _DEFS_H
> typedef int BOOL;
> #define FALSE 0
> #define TRUE 1
>
> typedef unsigned char BYTE;
> typedef unsigned short WORD;
> typedef unsigned long DWORD;
>
> typedef unsigned int UINT;
>
> #define LONG long
> #define ULONG_MAX 0xffffffff /* maximum unsigned long value */
>
> #define LOBYTE(w) ((BYTE)(w))
> #define HIBYTE(w) ((BYTE)(((UINT)(w) >> 8) & 0xFF))
>
> #define LOWORD(l) ((WORD)(DWORD)(l))
> #define HIWORD(l) ((WORD)((((DWORD)(l)) >> 16) & 0xFFFF))
>
> #define MAKEWORD(a, b) ((WORD)(((BYTE)(a)) | ((WORD)((BYTE)
> (b))) << 8))
> #define MAKELONG(low, high) ((LONG)(((WORD)(low)) | (((DWORD)((WORD)
> (high))) << 16)))
>
> #define max(a,b) (((a) > (b)) ? (a) : (b))
> #define min(a,b) (((a) < (b)) ? (a) : (b))
>
>
> #define NULL ((void *)0)
>
> #define TimeDiff(StartTime, EndTime) (((DWORD)EndTime >
> (DWORD)StartTime) ? ((DWORD)EndTime - (DWORD)StartTime) :
> ((DWORD)EndTime + ((DWORD)ULONG_MAX - (DWORD)StartTime) + 1))
>
>
> #endif
>
>
>
> #define UDP_PORT_ID 0x7070
>
> #pragma pack(1)
> typedef struct
> {
> char *pOSBegin;
> char *pOSEnd;
> char *pOSRun;
> WORD CRC;
> WORD BootSignature;
> WORD OSSignature;
> BYTE Unused[14];
> } OSDef;
>
> /* Error/return val List */
> #define HEI_NO_ERROR 0
> #define ICMP_PKT_FOUND 65
> #define ARP_PKT_FOUND 66
> #define TYPE_NOT_HANDLED 67
> #define LINK_SENSE_TRIGGERED 68
> #define UNK_IP_PACKET 100
> #define UNK_ETHERTYPE 101
> #define UNK_PACKET_TYPE 102
> #define UNK_802X_PACKET_TYPE 103
> #define UNK_LLC_TYPE 104
> #define CRC_DOES_NOT_MATCH 105
> #define CRC_NO_DATA 106
> #define ENET_ADDR_REPROGRAMMED 107
> #define NULL_DATA_POINTER 108
> #define SIZE_ERROR 109
> #define NOT_FOUND 110
> #define INVALID_TYPE 111
> #define RAM_ALREADY_LOCKED 112
> #define INVALID_REQUEST 113
> #define TIMEOUT_ERROR 114
> #define FLASH_PROGRAM_ERROR 115
> #define INVALID_OS 116
> #define INVALID_LOCATION 117
> #define INVALID_SLOT_NUMBER 118
> #define INVALID_DATA 119
> #define MODULE_BUSY 120
> #define CHANNEL_FAILURE 121
> #define UNUSED_CHANNELS_EXIST 122
> #define INVALID_UDP_PORT 123
> #define SHUTDOWN_OS 124
> #define NOT_MY_IP_ADDRESS 125
> #define PROTECTION_ERROR 126
> #define UNK_TYPE_ERROR 127
> #define BACKPLANE_INIT_ERROR 128
> #define UNK_RESPONSE 129
> #define UNK_RXWX_FORMAT 130
> #define UNK_ACK 131
> #define UNK_NAK 132
> #define RANGE_ERROR 133
> #define LENGTH_WARNING 134
> #define INVALID_BASE_NUMBER 135
> #define INVALID_MODULE_TYPE 136
> #define INVALID_OFFSET 137
> #define INVALID_BOOT_VER_FOR_OS 138
> #define BROKEN_TRANSMITTER 139
> #define INVALID_ADDRESS 140
> #define CHANNELS_UNUSED_0 200
> #define CHANNELS_UNUSED_1 201
> #define CHANNELS_UNUSED_2 201
> #define CHANNELS_UNUSED_3 203
> #define CHANNELS_UNUSED_4 204
> #define CHANNELS_UNUSED_5 205
> #define CHANNELS_UNUSED_6 206
> #define CHANNELS_UNUSED_7 207
> #define CHANNELS_UNUSED_8 208
> #define CHANNELS_UNUSED_9 209
> #define CHANNELS_UNUSED_10 210
> #define CHANNELS_UNUSED_11 211
> #define CHANNELS_UNUSED_12 212
> #define CHANNELS_UNUSED_13 213
> #define CHANNELS_UNUSED_14 214
> #define CHANNELS_UNUSED_15 215
> #define CHANNELS_UNUSED_16 216
> #pragma pack()
>
> /*
> ** HEI.C - Platform independent code for communicating with Host
> Automation Products
> ** line of ethernet modules.
> **
> ** Copyright (C) - 1996-1997 Host Automation Products, Inc.
> **
> */
> #include "windows.h"
> #include "defs.h"
> #include <memory.h>
> #include <string.h>
> #include <ctype.h>
> #include "hei.h"
> void (*pAsyncPacketHandler)(HEIDevice *pDevice, BYTE *pResponse, int
> ResponseLen) = 0;
>
> /* Interface functions */
> int HEIIOpen(void);
> int HEIIClose(void);
> int HEIIOpenDevice(HEITransport *pTransport, HEIDevice *pDevice);
> int HEIICloseDevice(HEIDevice *pDevice);
> int HEIIOpenTransport(HEITransport *pTransport);
> int HEIICloseTransport(HEITransport *pTransport);
> int HEIIReceivePacket(HEIDevice *pDevice, BYTE *pResponse, int
> *pResponseSize);
> int HEIISendPacket(HEIDevice *pDevice, BYTE *pPacket, WORD
> PacketSize);
> DWORD HEIIGetCounter(void);
> #define DEBUG_FILE 0
> #if DEBUG_FILE
> #include <stdio.h>
> #include <stdarg.h>
> #include "windows.h"
> FILE *pOutFile=NULL;
> void DebugString(char *String, ...)
> {
> char Buffer[200];
> va_list ap;
> va_start(ap, String);
> wvsprintf(Buffer, String, ap);
> //OutputDebugString(Buffer);
> pOutFile = fopen("c:\\heiout.txt", "a+");
> if (pOutFile)
> {
> fputs("\n", pOutFile);
> fputs(Buffer, pOutFile);
> fclose(pOutFile);
> }
> va_end(ap);
> }
>
> #endif
>
> __declspec(dllexport) int HEISetAsyncHandler(void (*pFun)(HEIDevice
> *pDevice, BYTE *pResponse, int ResponseLen))
> {
> pAsyncPacketHandler = pFun;
> return 0;
> }
> __declspec(dllexport) int HEIGetAsyncHandler(void (**pFun)(HEIDevice
> *pDevice, BYTE *pResponse, int ResponseLen))
> {
> *pFun = pAsyncPacketHandler;
> return 0;
> }
>
> /*
> ** This macro will return the difference between a start time (in
> milliseconds) and an end time (also in milliseconds).
> ** It handles the fact that a DWORD millisecond indicator will wrap
> every 49.XXX days.
> */
> #define TimeDiff(StartTime, EndTime) (((DWORD)EndTime >
> (DWORD)StartTime) ? ((DWORD)EndTime - (DWORD)StartTime) :
> ((DWORD)EndTime + ((DWORD)ULONG_MAX - (DWORD)StartTime) + 1))
> #define WordDiff(Start, End) (((WORD)End > (WORD)Start) ?
> ((WORD)End - (WORD)Start) : ((WORD)End + ((WORD)0xFFFF -
> (WORD)Start) + 1))
>
> #ifdef NOCRC
> int DoCRC = 0;
> #else
> int DoCRC = 1;
> #endif
> #define EXTRA_TIME_FOR_SETUP_DATA 10
> int DoEncrypt(Encryption *pEncrypt, BYTE *ptr, WORD Num);
> __declspec(dllexport) int _SendPacket(HEIDevice *pDevice, BYTE
> *pPacket, WORD PacketSize, BYTE *pResponse, int *pResponseSize, BOOL
> WaitForResponse, BOOL ReturnWarnings);
>
> #if defined(SUPERVISOR)
> int PrepareSupervisorPacket(HEIDevice *pDevice, BYTE *pPacket, WORD
> PacketSize);
> #endif /* #if defined(SUPERVISOR) */
>
> WORD CalcCRC(WORD icrc, BYTE *icp, WORD icnt);
>
> int InsertCRC(BYTE *pBuffer, WORD Len)
> {
> WORD *pWord = (WORD *) (pBuffer+5);
>
> if (DoCRC)
> {
> (*pWord) = CalcCRC(0, (BYTE *) (pBuffer+PACKET_HEADER_SIZE),
> (WORD) (Len - PACKET_HEADER_SIZE));
> }
> else
> {
> (*pWord) = 0;
> }
>
> return 0;
> }
> BOOL CRCCorrect(BYTE *pBuffer, WORD Len)
> {
> if (!DoCRC)
> return TRUE;
> else if (Len < PACKET_HEADER_SIZE)
> return FALSE;
> else
> {
> WORD *pCRC = (WORD *) (pBuffer+5);
> WORD CRC;
> if (!*pCRC)
> return TRUE;
> CRC = CalcCRC(0, (BYTE *) (pBuffer+PACKET_HEADER_SIZE), (WORD)
> (Len - PACKET_HEADER_SIZE));
> return (CRC == (*pCRC));
> }
> }
>
> /* int GetResponse(HEIDevice *pDevice, BYTE *pResponse, int
> *pResponseSize, WORD ExtraTime=0, BOOL ProcessTimeout=TRUE, BOOL
> CheckAppVal=TRUE)*/
> __declspec(dllexport) int GetResponse(HEIDevice *pDevice, BYTE
> *pResponse, int *pResponseSize, WORD ExtraTime, BOOL ProcessTimeout,
> BOOL CheckAppVal)
> {
> unsigned short ThisAppVal = pDevice->LastAppVal;
> DWORD DeviceTimeout = pDevice->Timeout;
> int SavedSize = *pResponseSize;
> int Error;
> DWORD Timeout = DeviceTimeout + ExtraTime;
> DWORD StartTime = HEIIGetCounter();
> while (1)
> {
> *pResponseSize = SavedSize;
> Error = HEIIReceivePacket(pDevice, pResponse, pResponseSize);
>
> if (!Error && (*pResponseSize))
> {
> /* We have a packet to look at. */
> /* Check the App Val. */
> WORD *pWord = (WORD *) (pResponse+3);
>
> if (*pWord == ThisAppVal || !ThisAppVal || !CheckAppVal)
> {
> int Retval;
>
> if (!CheckAppVal)
> pDevice->LastAppVal = *pWord;
> Retval = 0;
> if (CRCCorrect((BYTE *) pResponse, (WORD) *pResponseSize))
> {
> /* We have our response! */
> }
> else
> {
> pDevice->BadCRCCount++;
> Retval = HEIE_CRC_MISMATCH;
> }
>
> return Retval;
> }
> else
> {
> if (pAsyncPacketHandler)
> {
> (*pAsyncPacketHandler)(pDevice, pResponse, *pResponseSize);
> }
> pDevice->LatePacketCount++;
> continue;
> }
> }
> else if (Error && Error != HEIE_NO_RESPONSE)
> {
> return Error;
> }
> else if (!ProcessTimeout)
> {
> /* No more packets to look at. */
> return HEIE_NO_RESPONSE;
> }
>
> if (ProcessTimeout && (TimeDiff(StartTime, HEIIGetCounter()) >=
> Timeout))
> {
> /* Timeout! */
> break;
> }
> }
>
> *pResponseSize = 0;
> return HEIE_TIMEOUT;
> }
>
> static unsigned short AppVal = 1;
> __declspec(dllexport) int HEIGetResponse(HEIDevice *pDevice, BYTE
> *pResponse, int *pResponseSize, BOOL CheckAppVal)
> {
> int Retval;
>
> #if DEBUG_FILE
> DebugString("In GetResponse %u", AppVal);
> #endif
> Retval = GetResponse(pDevice, pResponse, pResponseSize, 0, FALSE,
> CheckAppVal);
>
> #if DEBUG_FILE
> DebugString("Leaving GetResponse %u -> %d (0x%X)", AppVal, Retval,
> Retval);
> #endif
> return Retval;
> }
>
> int WriteERMCommandData(HEIDevice *pDevice, WORD Base, WORD Slot,
> BYTE *pData, WORD NumBytes, WORD Offset)
> {
> return HEIWriteERMData(pDevice, Base, Slot, DATA_COMMAND, pData,
> NumBytes, Offset);
> }
> int ReadERMCommandData(HEIDevice *pDevice, WORD Base, WORD Slot,
> BYTE *pData, WORD NumBytes, WORD Offset)
> {
> return HEIReadERMData(pDevice, Base, Slot, DATA_COMMAND, pData,
> NumBytes, Offset);
> }
>
> #if HEIAPIVERSION>=3
> int _SendProxyPacket(HEIDevice *pDevice, BYTE *pPacket, WORD
> PacketSize, BYTE *pResponse, int *pResponseSize, BOOL
> WaitForResponse, BOOL ReturnWarnings)
> {
> int Retval = 0;
> WORD DataOffset = pDevice->DataOffset;
> WORD SubTotal = PacketSize - DataOffset;
> BYTE *pCmd = pPacket+PacketSize-SubTotal;
> // Disable proxying.
> pDevice->UseProxy = FALSE;
> Retval = WriteERMCommandData(pDevice, pDevice->ProxyBase, pDevice-
> >ProxySlot, pCmd, SubTotal, 0);
> if (Retval)
> {
> // printf("\nError %d (0x%X) from WriteERMCommandData", Retval,
> Retval);
> }
> else
> {
> BYTE Extra[10];
> WORD ExtraLen;
> WORD *pWord;
> pWord = (WORD *) &Extra[0];
> *pWord++ = pDevice->ProxyDevNum;
> *pWord++ = 0; // CmdOffset
> *pWord++ = SubTotal; // CmdLength
> *pWord++ = 0; // RspOffset;
> *pWord++ = 0x800; // RspLength
> ExtraLen = 10;
> Retval = HEIDoERMCommandEx(pDevice, pDevice->ProxyBase, pDevice-
> >ProxySlot, COMMAND_PROCESS_COMMAND_BUFFER, Extra, ExtraLen);
> if (Retval)
> {
> // printf("Error %d (0x%X) from call to WPLCDoERMCommandEx",
> Retval, Retval);
> }
> else
> {
> // Read response from command buffer.
> BYTE ResponseBuffer[4];
> Retval = ReadERMCommandData(pDevice, pDevice->ProxyBase, pDevice-
> >ProxySlot, ResponseBuffer, 4, 0);
> if (Retval)
> {
> // printf("\nError %d (0x%X) from ReadERMCommandData", Retval,
> Retval);
> }
> else
> {
> WORD *pError = (WORD *) &ResponseBuffer[0];
> WORD *pLen = (WORD *) &ResponseBuffer[2];
> if (*pError)
> {
> // printf("\nCommand Error: %d Len: %d", *pError, *pLen);
> }
> else
> {
> Retval = ReadERMCommandData(pDevice, pDevice->ProxyBase,
> pDevice->ProxySlot, pResponse+PACKET_HEADER_SIZE, *pLen, 4);
> if (Retval)
> {
> // printf("\nError %d (0x%X) from ReadERMCommandData", Retval,
> Retval);
> }
> else
> {
> // Fix pResponse[0] - pResponse[PACKET_HEADER_SIZE-1]
> (*pResponseSize) = (*pLen) + PACKET_HEADER_SIZE;
> }
> }
> }
> }
> }
> // Reenable proxying.
> pDevice->UseProxy = TRUE;
> return Retval;
> }
> #endif
>
> /*int SendPacket(HEIDevice *pDevice, BYTE *pPacket, WORD PacketSize,
> BYTE *pResponse, int *pResponseSize, BOOL WaitForResponse=TRUE, BOOL
> ReturnWarnings=FALSE)*/
> __declspec(dllexport) int _SendPacket(HEIDevice *pDevice, BYTE
> *pPacket, WORD PacketSize, BYTE *pResponse, int *pResponseSize, BOOL
> WaitForResponse, BOOL ReturnWarnings)
> {
> #if HEIAPIVERSION>=3
> if (pDevice->UseProxy == TRUE)
> {
> // Proxy this command to the device.
> //printf("\nUse proxy.");
> return _SendProxyPacket(pDevice, pPacket, PacketSize, pResponse,
> pResponseSize, WaitForResponse, ReturnWarnings);
> }
> #endif
> {
> BYTE *ptr;
> WORD *pWord;
> unsigned short ThisAppVal;
> unsigned short *pWordAppVal;
> BYTE *pBegin = pPacket;
> WORD PreHeaderBytes = pDevice->DataOffset - PACKET_HEADER_SIZE;
> WORD Retry;
> if (pDevice->UseAddressedBroadcast)
> PreHeaderBytes -= 7;
>
> pPacket += PreHeaderBytes;
>
> ptr = pPacket;
>
> if (pDevice->UseAddressedBroadcast)
> {
> pPacket[PACKET_HEADER_SIZE] = FUN_ADDRESSED_BROADCAST;
> memcpy(&pPacket[PACKET_HEADER_SIZE+1], pDevice->ENetAddress, 6);
> }
>
> *ptr++ = 'H';
> *ptr++ = 'A';
> *ptr = 'P';
>
> /* Calculate CRC */
> InsertCRC(pPacket, (WORD) (PacketSize-PreHeaderBytes));
>
> /* Insert the number of bytes which were checksumed. */
> pWord = (WORD *) (pPacket+7);
>
> *pWord = (WORD) PacketSize - PreHeaderBytes - PACKET_HEADER_SIZE; /
> * This is the bytes to follow/checksum */
>
> /* Do encryption (if required) */
> if (pDevice->_pTransport->Encrypt.Algorithm)
> DoEncrypt(&pDevice->_pTransport->Encrypt, pPacket+5, (WORD)
> (PacketSize-5-PreHeaderBytes));
>
> pWordAppVal = (unsigned short *) (pPacket+3);
>
>
> #if defined(SUPERVISOR)
> PrepareSupervisorPacket(pDevice, pPacket, PacketSize);
> #endif /* #if defined(SUPERVISOR) */
> for (Retry = 0; Retry<=pDevice->Retrys; Retry++)
> {
> int ResponseSize = *pResponseSize;
> int Error;
>
> ThisAppVal = AppVal++;
> pDevice->LastAppVal = ThisAppVal;
>
> if (!AppVal)
> AppVal++;
>
> if (Retry)
> pDevice->RetryCount++;
>
> /* Insert the app value. */
> *pWordAppVal = ThisAppVal;
>
> Error = HEIISendPacket(pDevice, pBegin, PacketSize);
>
> if (Error)
> {
> *pResponseSize = 0;
> return Error;
> }
>
> if (!WaitForResponse)
> {
> *pResponseSize = 0;
> return HEIE_NO_RESPONSE;
> }
> Error = GetResponse(pDevice, pResponse, &ResponseSize, 0, TRUE,
> TRUE);
> if (!Error)
> {
> *pResponseSize = ResponseSize;
> if (Retry != 0 && ReturnWarnings)
> return HEIW_RETRY;
> return 0; /* Success! */
> }
> else if (Error != HEIE_TIMEOUT)
> return Error;
> }
>
> *pResponseSize = 0;
> return HEIE_TIMEOUT;
> }
> }
>
> __declspec(dllexport) int SendPacketTwoResponses(HEIDevice *pDevice,
> BYTE *pPacket, WORD PacketSize, BYTE *pResponse, int *pResponseSize,
> BOOL WaitForResponse, BOOL ReturnWarnings, WORD
> Bytes2Verify, BYTE *pVerifyData,
> WORD ExtraTime, BOOL ProcessTimeout, BOOL CheckAppVal)
> {
> WORD SaveRetryCount = pDevice->RetryCount;
> WORD SaveRetrys = pDevice->Retrys;
> int SaveResponseSize = *pResponseSize;
> #if HEIAPIVERSION>=3
> if (pDevice->UseProxy == TRUE)
> {
> // Proxy this command to the device.
> //printf("\nUse proxy.");
> return _SendProxyPacket(pDevice, pPacket, PacketSize, pResponse,
> pResponseSize, WaitForResponse, ReturnWarnings);
> }
> #endif
> while (TRUE)
> {
> int Error = _SendPacket(pDevice, pPacket, PacketSize,pResponse,
> pResponseSize, WaitForResponse, ReturnWarnings);
> if (Error && !(Error & HEIW_FIRST_WARNING))
> {
> /* Restore retrys value */
> pDevice->Retrys = SaveRetrys;
> return Error;
> }
> /* Check and make sure we got an ack. */
> if (Bytes2Verify)
> {
> BYTE *pRet = (pResponse+PACKET_HEADER_SIZE);
>
> while (Bytes2Verify)
> {
> if (*pRet++ != *pVerifyData++)
> {
> /* Restore retrys value */
> pDevice->Retrys = SaveRetrys;
> return HEIE_INVALID_RESPONSE;
> }
> Bytes2Verify--;
> }
> }
> /* Restore size of response buffer. */
> *pResponseSize = SaveResponseSize;
> Error = GetResponse(pDevice, pResponse, pResponseSize, ExtraTime,
> ProcessTimeout, CheckAppVal);
> if (Error == HEIE_TIMEOUT)
> {
> WORD TotalRetrys;
> /* Perform a retry */
> pDevice->RetryCount++;
> /* See how many retrys we have already done. */
> TotalRetrys = WordDiff(SaveRetryCount, pDevice->RetryCount);
> if (TotalRetrys >= SaveRetrys)
> {
> /* Restore retrys value */
> pDevice->Retrys = SaveRetrys;
> return Error;
> }
> /* Prepare to go again. */
> *pResponseSize = SaveResponseSize;
> /* Adjust number of retrys left to do. */
> pDevice->Retrys = SaveRetrys - TotalRetrys;
> }
> else
> {
> /* Restore retrys value */
> pDevice->Retrys = SaveRetrys;
> if (!Error && pDevice->RetryCount != SaveRetryCount)
> Error = HEIW_RETRY;
> if (Error)
> return Error;
> return HEIE_NULL;
> }
> }
> }
>
> /* Transport Stuff */
> __declspec(dllexport) int HEIOpenTransport(HEITransport *pTransport,
> WORD Ver, ENetAddress *pSourceAddress)
> /* __declspec(dllexport) int HEIOpenTransport(HEITransport
> *pTransport, WORD Ver, DWORD NetworkAddress)*/
> {
> int Retval;
>
> #if DEBUG_FILE
> DebugString("In HEIOpenTransport");
> #endif
> if (HEIAPIVERSION != Ver)
> return HEIE_VER_MISMATCH;
> if (!pTransport)
> return HEIE_NULL_TRANSPORT;
>
> pTransport->Encrypt.Algorithm = HEIEN_NONE;
> /*pTransport->NetworkAddress = NetworkAddress;*/
> pTransport->pSourceAddress = pSourceAddress;
>
> Retval = HEIIOpenTransport(pTransport);
>
> #if DEBUG_FILE
> DebugString("Leaving HEIOpenTransport", Retval);
> #endif
>
> return Retval;
> }
>
>
> __declspec(dllexport) int HEICloseTransport(HEITransport *pTransport)
> {
> if (!pTransport)
> return HEIE_NULL_TRANSPORT;
>
> return HEIICloseTransport(pTransport);
> }
> __declspec(dllexport) int HEIOpenDevice
> (
> HEITransport *pTransport,
> HEIDevice *pDevice,
> WORD Ver,
> WORD iTimeout,
> WORD iRetrys,
> BOOL UseBroadcast
> )
> {
> int Retval;
>
> #if 0
> {
> char Buffer[200];
> wsprintf(Buffer, "Timeout: %d Retrys: %d UseBroadCast: %d",
> iTimeout, iRetrys, UseBroadcast);
> MessageBox(NULL, Buffer, "HEIOpenDevice", 0);
> }
> #endif
>
> #if DEBUG_FILE
> DebugString("In HEIOpenDevice");
> #endif
>
> if (HEIAPIVERSION != Ver)
> return HEIE_VER_MISMATCH;
> if (!pTransport)
> return HEIE_NULL_TRANSPORT;
>
> if (!pDevice)
> return HEIE_INVALID_DEVICE;
> pDevice->_dwParam = 0;
> pDevice->Timeout = iTimeout;
> pDevice->Retrys = iRetrys;
> pDevice->UseAddressedBroadcast = UseBroadcast;
> pDevice->UseBroadcast = UseBroadcast;
> pDevice->pData = 0;
> pDevice->SizeOfData = 0;
> pDevice->DataOffset = PACKET_HEADER_SIZE;
> pDevice->pBuffer = 0;
> pDevice->RetryCount = 0;
> pDevice->BadCRCCount = 0;
> pDevice->LatePacketCount = 0;
> pDevice->ParallelPackets = FALSE;
> pDevice->_pTransport = pTransport;
> #if HEIAPIVERSION==3
> pDevice->UseProxy = 0;
> pDevice->ProxyBase = 0;
> pDevice->ProxySlot = 0;
> pDevice->ProxyDevNum = 0;
> memset(pDevice->Reserved, 0, sizeof(pDevice->Reserved)); /*
> Reserved bytes, set to zero */
> #endif
> if (pDevice->UseAddressedBroadcast)
> pDevice->DataOffset += 7;
> Retval = HEIIOpenDevice(pTransport, pDevice);
>
> #if DEBUG_FILE
> DebugString("Leaving HEIOpenDevice", Retval);
> #endif
> return Retval;
> }
> __declspec(dllexport) int HEICloseDevice(HEIDevice *pDevice)
> {
> int Retval = HEIE_NULL;
> if (!pDevice)
> return HEIE_INVALID_DEVICE;
>
> if (pDevice->_pTransport)
> {
> Retval = HEIICloseDevice(pDevice);
> pDevice->_pTransport = (HEITransport *) NULL;
> }
>
> return Retval;
> }
>
> __declspec(dllexport) int HEIOpen(WORD Ver)
> {
> if (HEIAPIVERSION != Ver)
> return HEIE_VER_MISMATCH;
>
> return HEIIOpen();
> }
> __declspec(dllexport) int HEIClose()
> {
> return HEIIClose();
> }
>
> int DoEncrypt(Encryption *pEncrypt, BYTE *ptr, WORD Num)
> {
> switch (pEncrypt->Algorithm)
> {
> case 1: /* Private key encryption (XOR) */
> {
> BYTE *keyptr = pEncrypt->Key;
> WORD x;
>
> for (x=0; x<Num; x++)
> {
> *ptr++ ^= *keyptr++;
>
> if (!*keyptr)
> keyptr = pEncrypt->Key;
> }
>
> return 0;
> }
>
> default:
> return -1;
> }
> }
> int OpenQueryableDevice(HEITransport *pTransport, HEIDevice
> *pDevice, WORD Ver)
> {
> /* Open a device which I can use for broadcasting a packet. */
> int RetVal = HEIOpenDevice(pTransport, pDevice, Ver, 20, 0, TRUE);
> if (!RetVal)
> {
> pDevice->UseAddressedBroadcast = FALSE; /* Don't want to use
> 'Addressed' Broadcast, just Broadcast! */
> pDevice->DataOffset -= 7; /* We are not using addressed
> broadcast. */
> pDevice->wParam = 0;
> }
> return RetVal;
> }
>
>
> DWORD QueryTimeout = 600;
> __declspec(dllexport) DWORD HEISetQueryTimeout(DWORD NewTimeout)
> {
> DWORD Save = QueryTimeout;
> QueryTimeout = NewTimeout;
> return Save;
> }
> __declspec(dllexport) DWORD HEIGetQueryTimeout()
> {
> return QueryTimeout;
> }
>
> int DoQuery(HEITransport *pTransport, HEIDevice *pDevice, HEIDevice
> *pDevices, WORD *pNumDevices, WORD Ver, BYTE *pBuffer, WORD
> BufferSize)
> {
> BYTE RetBuffer[600];
> int ResponseSize = sizeof(RetBuffer);
> BYTE FromAddress[20];
> int Error;
> WORD Count = 0;
> DWORD Timeout = QueryTimeout;
> DWORD StartTime;
> int Retval;
> pDevice->pData = FromAddress;
> pDevice->SizeOfData = sizeof(FromAddress);
> Error = _SendPacket(pDevice, pBuffer, BufferSize, RetBuffer,
> &ResponseSize, TRUE, FALSE);
> StartTime = HEIIGetCounter();
> Retval = HEIE_NULL;
> while (1)
> {
> switch ((WORD) Error)
> {
> case HEIE_NULL:
> {
> /* No Error, so process packet. */
> if (RetBuffer[0] == 'H' && RetBuffer[1] == 'A' && (RetBuffer[2]
> == 'P' || RetBuffer[2] == 'A') &&
> RetBuffer[PACKET_HEADER_SIZE] == 0x55 &&
> (BYTE) RetBuffer[PACKET_HEADER_SIZE+1] == 0xAA)
> {
> if (Count < (*pNumDevices))
> {
> memcpy(pDevices[Count].Address.Raw, pDevice->pData, pDevice-
> >SizeOfData);
> memcpy(pDevices[Count].ENetAddress, (char *) (RetBuffer
> +PACKET_HEADER_SIZE+2), 6);
> if (pTransport->Protocol == HEIP_IP)
> {
> if (RetBuffer[PACKET_HEADER_SIZE+8] == 1)
> pDevices[Count].Address.Raw[19] = 1; /* The modules IP
> address is not initialized. */
> else
> pDevices[Count].Address.Raw[19] = 0;
> }
> Count++;
> }
> else
> {
> Count++;
> Retval = HEIE_BUFFER_TOO_SMALL;
> }
> }
> break;
> }
> case HEIE_TIMEOUT:
> break;
>
> case HEIW_RETRY:
> break;
> default:
> {
> /* Other error, so bail out. */
> pDevice->pData = 0;
> pDevice->SizeOfData = 0;
> return Error;
> }
> }
> if (TimeDiff(StartTime, HEIIGetCounter()) < Timeout)
> {
> ResponseSize = sizeof(RetBuffer);
> pDevice->SizeOfData = sizeof(FromAddress);
> Error = GetResponse(pDevice, RetBuffer, &ResponseSize, 0, TRUE,
> TRUE);
> }
> else
> break;
> }
> *pNumDevices = Count;
> pDevice->pData = 0;
> pDevice->SizeOfData = 0;
> return Retval;
> }
>
> __declspec(dllexport) int HEIQueryDevices(HEITransport *pTransport,
> HEIDevice *pDevices, WORD *pNumDevices, WORD Ver)
> {
> HEIDevice qDevice;
> WORD DataOffset;
> BYTE Buffer[100];
> WORD Total;
> int Retval;
> int Error;
> if (pTransport->Protocol == HEIP_SERIAL)
> {
> *pNumDevices = 0;
> return HEIE_NULL;
> }
> Error = OpenQueryableDevice(pTransport, &qDevice, Ver);
>
> if (Error)
> return Error;
> /* Build the buffer. */
> DataOffset = qDevice.DataOffset;
> Buffer[DataOffset] = FUN_POLLING_ALL; /* This is the function
> code! */
> Total = DataOffset+1;
> Retval = DoQuery(pTransport, &qDevice, pDevices, pNumDevices, Ver,
> Buffer, Total);
> HEICloseDevice(&qDevice);
>
> return Retval;
> }
> __declspec(dllexport) int HEIQueryDeviceData(HEITransport
> *pTransport, HEIDevice *pDevices, WORD *pNumDevices, WORD Ver, WORD
> DataType, BYTE *pData, WORD SizeofData)
> {
> HEIDevice qDevice;
> WORD DataOffset;
> BYTE Buffer[600];
> WORD *pWord;
> WORD Total;
> int Retval;
>
> int Error = OpenQueryableDevice(pTransport, &qDevice, Ver);
>
> if (Error)
> return Error;
> /* Build the buffer. */
> DataOffset = qDevice.DataOffset;
> Buffer[DataOffset] = FUN_QUERY_SETUP_DATA; /* This is the
> function code! */
> Buffer[DataOffset+1] = 0;
> pWord = (WORD *) (Buffer+DataOffset+2);
>
> if (SizeofData > 512)
> SizeofData = 512;
> *pWord++ = DataType;
> *pWord = SizeofData;
>
> memcpy(Buffer+DataOffset+6, pData, SizeofData);
> Total = qDevice.DataOffset+6+SizeofData;
> Retval = DoQuery(pTransport, &qDevice, pDevices, pNumDevices, Ver,
> Buffer, Total);
> HEICloseDevice(&qDevice);
>
> return Retval;
> }
>
> /* SUPPORT INFORMATION */
> __declspec(dllexport) int HEIReadSupportInfo(HEIDevice *pDevice,
> BYTE *pSupportInfo, WORD SizeOfSupportInfo)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int NumBytes;
> int Error;
> int Retval;
> Buffer[DataOffset] = (BYTE) FUN_READ_SUPPORT_INFO; /* This is
> the function code! */
> Total = DataOffset+1;
> NumBytes = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> NumBytes -= PACKET_HEADER_SIZE;
> if ((WORD) NumBytes > SizeOfSupportInfo)
> {
> Retval = HEIE_BUFFER_TOO_SMALL;
> NumBytes = SizeOfSupportInfo;
> }
> memcpy(pSupportInfo, RetBuffer+PACKET_HEADER_SIZE, NumBytes);
> }
> else
> {
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> }
> return Retval;
> }
>
> /* VERSION INFORMATION */
> __declspec(dllexport) int HEIReadVersionInfo(HEIDevice *pDevice,
> BYTE *pVerInfo, WORD SizeVerInfo)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int Retval;
> int NumBytes;
> Buffer[DataOffset] = (BYTE) FUN_READ_VER_INFO; /* This is the
> function code! */
> Total = DataOffset+1;
> NumBytes = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> NumBytes -= PACKET_HEADER_SIZE;
> if ((WORD) NumBytes > SizeVerInfo)
> {
> Retval = HEIE_BUFFER_TOO_SMALL;
> NumBytes = SizeVerInfo;
> }
> memcpy(pVerInfo, RetBuffer+PACKET_HEADER_SIZE, NumBytes);
> }
> else
> {
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> }
> return Retval;
> }
>
> /* BASE DEFINITION */
> __declspec(dllexport) int HEIReadBaseDef(HEIDevice *pDevice, BYTE
> *pBaseDefInfo, WORD *pSizeOfBaseDefInfo)
> {
> BYTE Buffer[300];
> BYTE RetBuffer[1000];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int Retval;
> int NumBytes;
> Buffer[DataOffset] = FUN_READ_BASE_DEF; /* This is the function
> code! */
> Total = DataOffset+1;
> if (pBaseDefInfo && *pBaseDefInfo == 0xB1)
> {
> Buffer[DataOffset+1] = *pBaseDefInfo;
> Total++;
> }
> NumBytes = sizeof(RetBuffer);
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> NumBytes -= PACKET_HEADER_SIZE;
> if ((WORD) NumBytes > *pSizeOfBaseDefInfo)
> {
> Retval = HEIE_BUFFER_TOO_SMALL;
> NumBytes = *pSizeOfBaseDefInfo;
> }
> memcpy(pBaseDefInfo, RetBuffer+PACKET_HEADER_SIZE, NumBytes);
> (*pSizeOfBaseDefInfo) = NumBytes;
> }
> else
> {
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> (*pSizeOfBaseDefInfo) = 0;
> }
> return Retval;
> }
> __declspec(dllexport) int HEIRescanBase(HEIDevice *pDevice, DWORD
> Flags, BYTE *pBaseDefInfo, WORD *pSizeOfBaseDefInfo)
> {
> BYTE Buffer[300];
> BYTE RetBuffer[1000];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int Retval;
> int NumBytes;
> DWORD *pDWord;
> Buffer[DataOffset] = FUN_INIT_BASE_DEF; /* This is the function
> code! */
> pDWord = (DWORD *) &Buffer[DataOffset+1];
> *pDWord = Flags;
> Total = DataOffset+5;
> NumBytes = sizeof(RetBuffer);
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> NumBytes -= PACKET_HEADER_SIZE;
> if ((WORD) NumBytes > *pSizeOfBaseDefInfo)
> {
> Retval = HEIE_BUFFER_TOO_SMALL;
> NumBytes = *pSizeOfBaseDefInfo;
> }
> memcpy(pBaseDefInfo, RetBuffer+PACKET_HEADER_SIZE, NumBytes);
> (*pSizeOfBaseDefInfo) = NumBytes;
> }
> else
> {
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> (*pSizeOfBaseDefInfo) = 0;
> }
> return Retval;
> }
> __declspec(dllexport) int HEIInitBaseDef(HEIDevice *pDevice, BYTE
> *pBaseDefInfo, WORD *pSizeOfBaseDefInfo)
> {
> BYTE Buffer[300];
> BYTE RetBuffer[600];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int Retval;
> int NumBytes;
> Buffer[DataOffset] = FUN_INIT_BASE_DEF; /* This is the function
> code! */
> Total = DataOffset+1;
> NumBytes = sizeof(RetBuffer);
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> NumBytes -= PACKET_HEADER_SIZE;
> if ((WORD) NumBytes > *pSizeOfBaseDefInfo)
> {
> Retval = HEIE_BUFFER_TOO_SMALL;
> NumBytes = *pSizeOfBaseDefInfo;
> }
> memcpy(pBaseDefInfo, RetBuffer+PACKET_HEADER_SIZE, NumBytes);
> (*pSizeOfBaseDefInfo) = NumBytes;
> }
> else
> {
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> (*pSizeOfBaseDefInfo) = 0;
> }
> return Retval;
> }
> __declspec(dllexport) int HEIWriteBaseDef(HEIDevice *pDevice, BYTE
> *pInputBaseDef, WORD SizeOfInputBaseDef, BYTE *pOutputBaseDef, WORD
> *pSizeOfOutputBaseDef)
> {
> BYTE Buffer[600];
> BYTE RetBuffer[600];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int Retval;
> int NumBytes;
> WORD *pWord;
> Buffer[DataOffset] = FUN_WRITE_BASE_DEF; /* This is the function
> code! */
> Buffer[DataOffset+1] = 0;
>
> pWord = (WORD *) &Buffer[DataOffset+2];
> *pWord = SizeOfInputBaseDef;
> Total = DataOffset+4+SizeOfInputBaseDef;
> if (Total > sizeof(Buffer))
> {
> return HEIE_DATA_TOO_LARGE;
> }
>
> memcpy(Buffer+DataOffset+4, pInputBaseDef, SizeOfInputBaseDef);
>
> NumBytes = sizeof(RetBuffer);
> Error = SendPacketTwoResponses(pDevice, Buffer, Total, RetBuffer,
> &NumBytes,
> TRUE, FALSE,
> 0, NULL,
> 30000, TRUE, TRUE);
>
> #if 0
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
>
> NumBytes = sizeof(RetBuffer);
> Error = GetResponse(pDevice, RetBuffer, &NumBytes, 30000, TRUE,
> TRUE);
> #endif
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
>
> Retval = Error;
> if (NumBytes)
> {
> short int *pInt = (short int *) (RetBuffer+PACKET_HEADER_SIZE);
>
> if (*pInt)
> Retval = *pInt;
> else if (pOutputBaseDef)
> {
> NumBytes -= (PACKET_HEADER_SIZE+2);
>
> if ((WORD) NumBytes > *pSizeOfOutputBaseDef)
> {
> Retval = HEIE_BUFFER_TOO_SMALL;
> NumBytes = *pSizeOfOutputBaseDef;
> }
>
> memcpy(pOutputBaseDef, RetBuffer+PACKET_HEADER_SIZE+2, NumBytes);
> (*pSizeOfOutputBaseDef) = NumBytes;
> }
> }
> else
> {
> Retval = HEIE_ZERO_BYTES_RECEIVED;
>
> if (pOutputBaseDef && pSizeOfOutputBaseDef)
> (*pSizeOfOutputBaseDef) = 0;
> }
> return Retval;
> }
> /* DEVICE DEFINITION */
> __declspec(dllexport) int HEIReadDeviceDef(HEIDevice *pDevice, BYTE
> *pDeviceDefInfo, WORD SizeOfDeviceDefInfo)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int Retval;
> int NumBytes;
> Buffer[DataOffset] = (BYTE) FUN_READ_DEVICE_INFO; /* This is the
> function code! */
> Total = DataOffset+1;
> NumBytes = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
>
> if (NumBytes)
> {
> NumBytes -= PACKET_HEADER_SIZE;
> if ((WORD) NumBytes > SizeOfDeviceDefInfo)
> {
> Retval = HEIE_BUFFER_TOO_SMALL;
> NumBytes = SizeOfDeviceDefInfo;
> }
> memcpy(pDeviceDefInfo, RetBuffer+PACKET_HEADER_SIZE, NumBytes);
> }
> else
> {
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> }
> return Retval;
> }
>
> /* SETUP */
> __declspec(dllexport) int HEIReadSetupData(HEIDevice *pDevice, WORD
> SetupType, BYTE *pData, WORD *pSizeofData)
> {
> BYTE Buffer[100];
> BYTE RetBuffer[600];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int Retval;
> int NumBytes;
> WORD *pWord;
> Buffer[DataOffset] = (BYTE) FUN_READ_SETUP_DATA; /* This is the
> function code! */
> Buffer[DataOffset+1] = 0;
> pWord = (WORD *) &Buffer[DataOffset+2];
> *pWord = SetupType;
> Total = DataOffset+4;
> NumBytes = sizeof(RetBuffer);
> pDevice->Timeout += EXTRA_TIME_FOR_SETUP_DATA;
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> pDevice->Timeout -= EXTRA_TIME_FOR_SETUP_DATA;
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> short int *pInt = (short int *) (RetBuffer+PACKET_HEADER_SIZE);
> NumBytes -= (PACKET_HEADER_SIZE+2);
> if ((WORD) NumBytes > *pSizeofData)
> {
> Retval = HEIE_BUFFER_TOO_SMALL;
> NumBytes = *pSizeofData;
> }
> if (*pInt)
> Retval = *pInt;
> (*pSizeofData) = NumBytes;
> memcpy(pData, RetBuffer+PACKET_HEADER_SIZE+2, NumBytes);
> }
> else
> {
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> }
> return Retval;
> }
> __declspec(dllexport) int HEIWriteSetupData(HEIDevice *pDevice, WORD
> SetupType, BYTE *pData, WORD SizeofData)
> {
> BYTE Buffer[600];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD *pWord;
> WORD Total;
> int Error;
> int Retval;
> int NumBytes;
> Buffer[DataOffset] = (BYTE) FUN_WRITE_SETUP_DATA; /* This is the
> function code! */
> Buffer[DataOffset+1] = 0;
> pWord = (WORD *) &Buffer[DataOffset+2];
> *pWord = SetupType;
> Total = DataOffset+4+SizeofData;
> if (Total > sizeof(Buffer))
> {
> #if 0
> BYTE Text[200];
> wsprintf(Text, "Total=%d DataOffset=%d SizeofData=%d
> SizeofBuffer=%d",
> Total, DataOffset, SizeofData, sizeof(Buffer));
> MessageBox(NULL, Text, "HEIWriteSetupData", 0);
> #endif
> return HEIE_DATA_TOO_LARGE;
> }
> memcpy(&Buffer[DataOffset+4], pData, SizeofData);
> NumBytes = sizeof(RetBuffer);
>
> pDevice->Timeout += EXTRA_TIME_FOR_SETUP_DATA;
> Error = SendPacketTwoResponses(pDevice, Buffer, Total, RetBuffer,
> &NumBytes,
> TRUE, FALSE,
> 0, NULL,
> 30000, TRUE, TRUE);
> pDevice->Timeout -= EXTRA_TIME_FOR_SETUP_DATA;
> #if 0
> pDevice->Timeout += EXTRA_TIME_FOR_SETUP_DATA;
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> pDevice->Timeout -= EXTRA_TIME_FOR_SETUP_DATA;
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> NumBytes = sizeof(RetBuffer);
> Error = GetResponse(pDevice, RetBuffer, &NumBytes, 30000, TRUE,
> TRUE);
> #endif
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> short int *pInt = (short int *) (RetBuffer+PACKET_HEADER_SIZE);
> if (*pInt)
> Retval = *pInt;
> }
> else
> {
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> }
> return Retval;
> }
> __declspec(dllexport) int HEIDeleteSetupData(HEIDevice *pDevice,
> WORD SetupType)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD *pWord;
> WORD Total;
> int Error;
> int Retval;
> int NumBytes;
> Buffer[DataOffset] = (BYTE) FUN_DELETE_SETUP_DATA; /* This is
> the function code! */
> Buffer[DataOffset+1] = 0;
> pWord = (WORD *) &Buffer[DataOffset+2];
> *pWord = SetupType;
> Total = DataOffset+4;
> NumBytes = sizeof(RetBuffer);
> pDevice->Timeout += EXTRA_TIME_FOR_SETUP_DATA;
> Error = SendPacketTwoResponses(pDevice, Buffer, Total, RetBuffer,
> &NumBytes,
> TRUE, FALSE,
> 0, NULL,
> 30000, TRUE, TRUE);
> pDevice->Timeout -= EXTRA_TIME_FOR_SETUP_DATA;
>
>
> #if 0
> pDevice->Timeout += EXTRA_TIME_FOR_SETUP_DATA;
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> pDevice->Timeout -= EXTRA_TIME_FOR_SETUP_DATA;
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> NumBytes = sizeof(RetBuffer);
> Error = GetResponse(pDevice, RetBuffer, &NumBytes, 30000, TRUE,
> TRUE);
> #endif
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> short int *pInt = (short int *) (RetBuffer+PACKET_HEADER_SIZE);
> if (*pInt)
> Retval = *pInt;
> }
> else
> {
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> }
> return Retval;
> }
> __declspec(dllexport) int HEIEnumSetupData(HEIDevice *pDevice, WORD
> *pData, WORD *pSizeofDataInWords)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[600];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int Retval;
> int NumBytes;
> Buffer[DataOffset] = (BYTE) FUN_ENUM_SETUP_DATA; /* This is the
> function code! */
> Total = DataOffset+1;
> NumBytes = sizeof(RetBuffer);
> pDevice->Timeout += EXTRA_TIME_FOR_SETUP_DATA;
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> pDevice->Timeout -= EXTRA_TIME_FOR_SETUP_DATA;
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> /*int NumWords; */
> short int *pInt = (short int *) (RetBuffer+PACKET_HEADER_SIZE);
> short int *pNumWords = (short int *) (RetBuffer+PACKET_HEADER_SIZE
> +2);
> if ((WORD) *pNumWords > *pSizeofDataInWords)
> {
> Retval = HEIE_BUFFER_TOO_SMALL;
> *pNumWords = *pSizeofDataInWords;
> }
> if (*pInt)
> Retval = *pInt;
> (*pSizeofDataInWords) = *pNumWords;
> memcpy((char *) pData, (char *) (RetBuffer+PACKET_HEADER_SIZE+4),
> *pNumWords * 2);
> }
> else
> {
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> }
> return Retval;
> }
>
> /* IO ACCESS */
> __declspec(dllexport) int HEIReadIO(HEIDevice *pDevice, BYTE *pData,
> WORD *DataSize)
> {
> BYTE Buffer[100];
> BYTE RetBuffer[1200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int Retval;
> int NumBytes;
>
> Buffer[DataOffset] = FUN_READ_IO; /* This is the function code! */
> Total = DataOffset+1;
> if (pData && *pData == 0xB1)
> {
> Buffer[DataOffset+1] = *pData;
> Total++;
> }
> NumBytes = sizeof(RetBuffer);
> //NumBytes = *DataSize;
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> (pDevice->ParallelPackets) ? FALSE : TRUE, TRUE);
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> short int *pInt = (short int *) &RetBuffer[PACKET_HEADER_SIZE];
> NumBytes -= PACKET_HEADER_SIZE;
> NumBytes -= 2;
> if ((WORD) NumBytes > *DataSize)
> {
> Retval = HEIE_BUFFER_TOO_SMALL;
> NumBytes = *DataSize;
> }
> if (*pInt)
> Retval = (*pInt) | 0x8000;
> memcpy(pData, RetBuffer+PACKET_HEADER_SIZE+2, NumBytes);
> (*DataSize) = NumBytes;
> }
> else
> {
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> (*DataSize) = 0;
> }
> return Retval;
> }
>
> __declspec(dllexport) int HEIWriteIO(HEIDevice *pDevice, BYTE
> *pData, WORD SizeofData, BYTE *pReturnData, WORD *pSizeofReturnData)
> {
> BYTE Buffer[1200];
> BYTE RetBuffer[1200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int Retval;
> int NumBytes;
> Buffer[DataOffset] = FUN_WRITE_IO; /* This is the function code!
> */
>
> Total = DataOffset+1+SizeofData;
> if (Total > sizeof(Buffer))
> return HEIE_DATA_TOO_LARGE;
> memcpy(Buffer+DataOffset+1, pData, SizeofData);
> NumBytes = sizeof(RetBuffer);
> //NumBytes = *pSizeofReturnData;
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> (pDevice->ParallelPackets) ? FALSE : TRUE, TRUE);
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> short int *pInt = (short int *) &RetBuffer[PACKET_HEADER_SIZE];
> if (pReturnData && pSizeofReturnData)
> {
> NumBytes -= PACKET_HEADER_SIZE;
> NumBytes -= 2;
> if ((WORD) NumBytes > *pSizeofReturnData)
> {
> Retval = HEIE_BUFFER_TOO_SMALL;
> NumBytes = *pSizeofReturnData;
> }
> memcpy(pReturnData, RetBuffer+PACKET_HEADER_SIZE+2, NumBytes);
> (*pSizeofReturnData) = NumBytes;
> }
> if (*pInt)
> Retval = (*pInt) | 0x8000;
> }
> else
> {
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> if (pSizeofReturnData)
> (*pSizeofReturnData) = 0;
> }
> return Retval;
> }
>
> __declspec(dllexport) int HEIWriteIONoRead(HEIDevice *pDevice, BYTE
> *pData, WORD SizeofData)
> {
> BYTE Buffer[1200];
> BYTE RetBuffer[1200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int Retval;
> int NumBytes;
> Buffer[DataOffset] = FUN_WRITE_IO_NO_READ; /* This is the
> function code! */
>
> Total = DataOffset+1+SizeofData;
> if (Total > sizeof(Buffer))
> return HEIE_DATA_TOO_LARGE;
> memcpy(Buffer+DataOffset+1, pData, SizeofData);
> NumBytes = sizeof(RetBuffer);
> //NumBytes = *pSizeofReturnData;
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> (pDevice->ParallelPackets) ? FALSE : TRUE, TRUE);
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> short int *pInt = (short int *) &RetBuffer[PACKET_HEADER_SIZE];
> if (*pInt)
> Retval = (*pInt) | 0x8000;
> }
> else
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> return Retval;
> }
>
> __declspec(dllexport) int HEIPetDevice(HEIDevice *pDevice)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int NumBytes;
> Buffer[DataOffset] = FUN_PET_LINK;
> Buffer[DataOffset+1] = 0;
> Total = DataOffset+2;
> NumBytes = sizeof(RetBuffer);
> return _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> }
> __declspec(dllexport) int HEIReadEthernetStats(HEIDevice *pDevice,
> BYTE *pData, WORD *DataSize, BOOL Clear)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int Retval;
> int NumBytes;
> Buffer[DataOffset] = FUN_READ_ETHERNET_STATS; /* This is the
> function code! */
> Buffer[DataOffset+1] = 0;
> Buffer[DataOffset+2] = Clear ? 1 : 0;
> Total = DataOffset+3;
> NumBytes = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> NumBytes -= PACKET_HEADER_SIZE;
> if ((WORD) NumBytes > *DataSize)
> {
> Retval = HEIE_BUFFER_TOO_SMALL;
> NumBytes = *DataSize;
> }
> memcpy(pData, RetBuffer+PACKET_HEADER_SIZE, NumBytes);
> (*DataSize) = NumBytes;
> }
> else
> {
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> (*DataSize) = 0;
> }
> return Retval;
> }
>
> __declspec(dllexport) int HEIReadModuleStatus(HEIDevice *pDevice,
> BYTE *pData, WORD *DataSize, BOOL Reset)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[600];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int Retval;
> int NumBytes;
> Buffer[DataOffset] = FUN_READ_MODULE_STATUS; /* This is the
> function code! */
> if (pData && *pData == 0xB1)
> Buffer[DataOffset+1] = 1;
> else
> Buffer[DataOffset+1] = 0;
> Buffer[DataOffset+2] = Reset ? 1 : 0;
> Total = DataOffset+3;
> NumBytes = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> short int *pInt = (short int *) &RetBuffer[PACKET_HEADER_SIZE];
> NumBytes -= PACKET_HEADER_SIZE;
> NumBytes -= 2;
> if ((WORD) NumBytes > *DataSize)
> {
> Retval = HEIE_BUFFER_TOO_SMALL;
> NumBytes = *DataSize;
> }
> if (*pInt)
> Retval = *pInt;
> memcpy(pData, RetBuffer+PACKET_HEADER_SIZE+2, NumBytes);
> (*DataSize) = NumBytes;
> }
> else
> {
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> (*DataSize) = 0;
> }
> return Retval;
> }
>
>
> /* CCM STUFF */
> #define CCM_READ 0x1E
> #define CCM_WRITE 0x20
>
> __declspec(dllexport) int HEICCMRequest(HEIDevice *pDevice, BOOL
> bWrite, BYTE DataType, WORD Address, WORD DataLen, BYTE *pData)
> {
> BYTE Buffer[320];
> BYTE RetBuffer[320];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int NumBytes;
> BYTE *pRet;
> short int *pError;
> BYTE VerifyData[2];
>
> #if DEBUG_FILE
> DebugString("In HEICCMRequest %u", AppVal);
> #endif
> if(DataLen > 256)
> return HEIE_INVALID_REQUEST;
>
> /* Function */
> Buffer[DataOffset] = FUN_CCM_REQUEST;
>
> /* Unused */
> Buffer[DataOffset+1] = 0;
> /* Request Code. */
> Buffer[DataOffset+2] = 0x01;
>
> /* Direction */
> Buffer[DataOffset+3] = bWrite ? CCM_WRITE : CCM_READ;
>
> /* Length */
> Buffer[DataOffset+4] = (DataLen == 256) ? 0 : (BYTE)DataLen;
>
> /* LSB of Address */
> Buffer[DataOffset+5] = (BYTE) (Address & 0xFF);
>
> /* MSB of Address */
> Buffer[DataOffset+6] = (BYTE) ((Address>>8) & 0xFF);
>
> /* Data Type */
> Buffer[DataOffset+7] = DataType;
> Total = DataOffset+8;
> if (bWrite)
> {
> /* We are writing. */
> memcpy(&Buffer[DataOffset+8], pData, DataLen);
> Total += DataLen;
> }
> NumBytes = sizeof(RetBuffer);
>
> VerifyData[0] = FUN_ACK;
> VerifyData[1] = FUN_CCM_REQUEST;
> Error = SendPacketTwoResponses(pDevice, Buffer, Total, RetBuffer,
> &NumBytes,
> (pDevice->ParallelPackets) ? FALSE : TRUE, TRUE,
> 2, VerifyData,
> 0, TRUE, TRUE);
> if (Error == HEIE_INVALID_RESPONSE)
> {
> short int *pError = (short int *) (RetBuffer+PACKET_HEADER_SIZE+2);
> #if DEBUG_FILE
> DebugString("Error %d (0x%X) from HEICCMRequest %u", *pError,
> *pError, AppVal);
> #endif
> return *pError;
> }
>
> #if 0
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> (pDevice->ParallelPackets) ? FALSE : TRUE, TRUE);
> if (Error && !(Error & HEIW_FIRST_WARNING))
> {
> #if DEBUG_FILE
> DebugString("Error %d (0x%X) from HEICCMRequest %u", Error, Error,
> AppVal);
> #endif
> return Error;
> }
> /* Check and make sure we got an ack. */
> pRet = (RetBuffer+PACKET_HEADER_SIZE);
>
> if (*pRet != FUN_ACK || (*(pRet+1) != FUN_CCM_REQUEST))
> {
> short int *pError = (short int *) (RetBuffer+PACKET_HEADER_SIZE+2);
> #if DEBUG_FILE
> DebugString("Error %d (0x%X) from HEICCMRequest %u", *pError,
> *pError, AppVal);
> #endif
> return *pError;
> }
> NumBytes = sizeof(RetBuffer);
> Error = GetResponse(pDevice, RetBuffer, &NumBytes, 0, TRUE, TRUE);
> #endif
>
> if (Error && !(Error & HEIW_FIRST_WARNING))
> {
> #if DEBUG_FILE
> DebugString("Error %d (0x%X) from HEICCMRequest %u", Error, Error,
> AppVal);
> #endif
> return Error;
> }
> NumBytes -= PACKET_HEADER_SIZE;
> pRet = (RetBuffer + PACKET_HEADER_SIZE);
> if (*pRet != FUN_RESPONSE || *(pRet+1) != FUN_CCM_REQUEST)
> {
> #if DEBUG_FILE
> Error = HEIE_INVALID_RESPONSE;
> DebugString("Error %d (0x%X) from HEICCMRequest %u", Error, Error,
> AppVal);
> #endif
> return HEIE_INVALID_RESPONSE;
> }
>
> pError = (short int *) (RetBuffer+PACKET_HEADER_SIZE+2);
>
> if (*pError)
> {
> #if DEBUG_FILE
> DebugString("Error %d (0x%X) from HEICCMRequest %u", *pError,
> *pError, AppVal);
> #endif
> return *pError;
> }
>
> NumBytes -= 4;
> if(!bWrite && NumBytes != (int)DataLen)
> {
> #if DEBUG_FILE
> Error = HEIE_INVALID_REQUEST;
> DebugString("Error %d (0x%X) from HEICCMRequest %u", Error, Error,
> AppVal);
> #endif
> return HEIE_INVALID_REQUEST;
> }
>
> memcpy(pData, RetBuffer+PACKET_HEADER_SIZE+4, DataLen);
> #if DEBUG_FILE
> DebugString("Leaving HEICCMRequest %u", AppVal);
> #endif
>
> return HEIE_NULL;
> }
>
> __declspec(dllexport) int HEIKSEQRequest(HEIDevice *pDevice, WORD
> DataLenIn, BYTE *pData, WORD *pDataLen)
> {
> BYTE Buffer[320];
> BYTE RetBuffer[320];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int NumBytes;
> BYTE *pRet;
> short int *pError;
> int Retval;
> BYTE VerifyData[2];
> #if DEBUG_FILE
> DebugString("In HEIKSEQRequest %u", AppVal);
> #endif
> if(DataLenIn > 256)
> return HEIE_INVALID_REQUEST;
> /* Function */
> Buffer[DataOffset] = FUN_KSEQ_REQUEST;
>
> /* Unused */
> Buffer[DataOffset+1] = 0;
> /* Request Code. */
> Buffer[DataOffset+2] = (DataLenIn == 256) ? 0 : (BYTE)DataLenIn;
>
> /* Unused */
> Buffer[DataOffset+3] = 0;
>
> /* Copy task code data. */
> memcpy(&Buffer[DataOffset+4], pData, DataLenIn);
> Total = DataOffset+4+DataLenIn;
> NumBytes = sizeof(RetBuffer);
>
> VerifyData[0] = FUN_ACK;
> VerifyData[1] = FUN_KSEQ_REQUEST;
> Error = SendPacketTwoResponses(pDevice, Buffer, Total, RetBuffer,
> &NumBytes,
> (pDevice->ParallelPackets) ? FALSE : TRUE, TRUE,
> 2, VerifyData,
> 0, TRUE, TRUE);
> if (Error == HEIE_INVALID_RESPONSE)
> {
> short int *pError = (short int *) (RetBuffer+PACKET_HEADER_SIZE+2);
> return *pError;
> }
> #if 0
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> (pDevice->ParallelPackets) ? FALSE : TRUE, TRUE);
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> /* Check and make sure we got an ack. */
> pRet = (RetBuffer+PACKET_HEADER_SIZE);
>
> if (*pRet != FUN_ACK || (*(pRet+1) != FUN_KSEQ_REQUEST))
> {
> short int *pError = (short int *) (RetBuffer+PACKET_HEADER_SIZE+2);
> return *pError;
> }
> NumBytes = sizeof(RetBuffer);
> Error = GetResponse(pDevice, RetBuffer, &NumBytes, 0, TRUE, TRUE);
> #endif
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
>
> NumBytes -= PACKET_HEADER_SIZE;
> pRet = (RetBuffer + PACKET_HEADER_SIZE);
> if (*pRet != FUN_RESPONSE || *(pRet+1) != FUN_KSEQ_REQUEST)
> {
> return HEIE_INVALID_RESPONSE;
> }
>
> pError = (short int *) (RetBuffer+PACKET_HEADER_SIZE+2);
>
> if (*pError)
> return *pError;
>
> NumBytes -= 4;
>
> Retval = HEIE_NULL;
> if ((WORD) NumBytes > *pDataLen)
> {
> Retval = HEIE_BUFFER_TOO_SMALL;
> NumBytes = *pDataLen;
> }
>
> memcpy(pData, RetBuffer+PACKET_HEADER_SIZE+4, NumBytes);
> *pDataLen = NumBytes;
>
> #if DEBUG_FILE
> DebugString("Leaving HEIKSEQRequest", Retval);
> #endif
>
> return Retval;
> }
> // Returns number of bytes not written.
> __declspec(dllexport) int HEIWriteComm(HEIDevice *pDevice, WORD
> Num2Write, BYTE *pData)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> WORD *pWord;
> int Error;
> int NumBytes;
> Buffer[DataOffset] = FUN_SERIAL_PORT;
> Buffer[DataOffset+1] = SPF_WRITE_COMM;
> pWord = (WORD *) &Buffer[DataOffset+2];
> *pWord = Num2Write;
> if (Num2Write > (sizeof(Buffer) - DataOffset - 4))
> return HEIE_DATA_TOO_LARGE;
> memcpy(Buffer+DataOffset+4, pData, Num2Write);
> Total = DataOffset+4+Num2Write;
> NumBytes = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> //if (Error) return Error;
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> if (NumBytes)
> return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));
> else
> return HEIE_ZERO_BYTES_RECEIVED;
> }
> __declspec(dllexport) int HEIReadComm(HEIDevice *pDevice, WORD
> *pNum2Read, BYTE *pData)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> WORD *pWord;
> int Error;
> int Retval;
> int NumBytes;
> Buffer[DataOffset] = FUN_SERIAL_PORT;
> Buffer[DataOffset+1] = SPF_READ_COMM;
> pWord = (WORD *) &Buffer[DataOffset+2];
> *pWord = *pNum2Read;
> Total = DataOffset+4;
> NumBytes = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> //if (Error) return Error;
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> short int *pInt = (short int *) (RetBuffer+PACKET_HEADER_SIZE);
> short int *pNumReturned = (short int *) (RetBuffer
> +PACKET_HEADER_SIZE+2);
> if (*pInt)
> Retval = *pInt;
> (*pNum2Read) = *pNumReturned;
> memcpy(pData, RetBuffer+PACKET_HEADER_SIZE+4, *pNumReturned);
> }
> else
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> return Retval;
> }
> __declspec(dllexport) int HEIGetRXAvailable(HEIDevice *pDevice, WORD
> *pAvailable)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int NumBytes;
> Buffer[DataOffset] = FUN_SERIAL_PORT;
> Buffer[DataOffset+1] = SPF_RX_AVAILABLE;
> Total = DataOffset+2;
> NumBytes = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> //if (Error) return Error;
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> if (NumBytes)
> {
> *pAvailable = *((WORD *) (RetBuffer+PACKET_HEADER_SIZE+2));
> return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));
> }
> else
> return HEIE_ZERO_BYTES_RECEIVED;
> }
> __declspec(dllexport) int HEIFlushRXQueue(HEIDevice *pDevice)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int NumBytes;
> Buffer[DataOffset] = FUN_SERIAL_PORT;
> Buffer[DataOffset+1] = SPF_RX_FLUSH;
> Total = DataOffset+2;
> NumBytes = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> //if (Error) return Error;
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> if (NumBytes)
> return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));
> else
> return HEIE_ZERO_BYTES_RECEIVED;
> }
>
> __declspec(dllexport) int HEISetupSerialPort(HEIDevice *pDevice,
> SerialSetup *pSetup, BOOL WriteToFlash)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int NumBytes;
> Buffer[DataOffset] = FUN_SERIAL_PORT;
> Buffer[DataOffset+1] = SPF_SETUP;
> Buffer[DataOffset+2] = (BYTE) WriteToFlash;
> Buffer[DataOffset+3] = 0;
> memcpy(Buffer+DataOffset+4, pSetup, sizeof(SerialSetup));
> Total = DataOffset+4+sizeof(SerialSetup);
> NumBytes = sizeof(RetBuffer);
> if (WriteToFlash)
> {
> pDevice->Timeout += EXTRA_TIME_FOR_SETUP_DATA;
> Error = SendPacketTwoResponses(pDevice, Buffer, Total, RetBuffer,
> &NumBytes,
> TRUE, FALSE,
> 0, NULL,
> 30000, TRUE, TRUE);
> pDevice->Timeout -= EXTRA_TIME_FOR_SETUP_DATA;
> }
> else
> {
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> }
> //if (Error)
> // return Error;
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> #if 0
> if (WriteToFlash)
> pDevice->Timeout += EXTRA_TIME_FOR_SETUP_DATA;
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> if (WriteToFlash)
> pDevice->Timeout -= EXTRA_TIME_FOR_SETUP_DATA;
> if (Error) return Error;
> if (WriteToFlash)
> {
> NumBytes = sizeof(RetBuffer);
> Error = GetResponse(pDevice, RetBuffer, &NumBytes, 30000, TRUE,
> TRUE);
> }
> #endif
> if (NumBytes)
> return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));
> else
> return HEIE_ZERO_BYTES_RECEIVED;
> }
>
> __declspec(dllexport) int HEIReadSerialPortSetup(HEIDevice *pDevice,
> SerialSetup *pSetup)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int NumBytes;
> Buffer[DataOffset] = FUN_SERIAL_PORT;
> Buffer[DataOffset+1] = SPF_READ_SETUP;
> Buffer[DataOffset+2] = 0;
> Buffer[DataOffset+3] = 0;
> Total = DataOffset+4;
> NumBytes = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> //if (Error) return Error;
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> if (NumBytes)
> {
> // Copy data into user buffer.
> memcpy(pSetup, RetBuffer+PACKET_HEADER_SIZE, sizeof(SerialSetup));
> return 0;
> }
> else
> return HEIE_ZERO_BYTES_RECEIVED;
> }
>
> __declspec(dllexport) int HEIGetTXLeft(HEIDevice *pDevice, WORD
> *pLeft)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> //int Retval;
> int NumBytes;
> Buffer[DataOffset] = FUN_SERIAL_PORT;
> Buffer[DataOffset+1] = SPF_TX_LEFT;
> Total = DataOffset+2;
> NumBytes = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> //if (Error) return Error;
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> //Retval = Error;
> if (NumBytes)
> {
> *pLeft = *((WORD *) (RetBuffer+PACKET_HEADER_SIZE+2));
> return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));
> }
> else
> return HEIE_ZERO_BYTES_RECEIVED;
> }
> /* PLC MEMORY STUFF */
> __declspec(dllexport) int HEIReadMemory(HEIDevice *pDevice, WORD
> Type, DWORD Offset, WORD NumBytes, BYTE *pBuffer)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[600];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int Num;
> WORD *pWord;
> DWORD *pDWord;
> Buffer[DataOffset] = FUN_READ_MEMORY;
> Buffer[DataOffset+1] = 0;
>
> pWord = (WORD *) &Buffer[DataOffset+2];
> *pWord++ = Type;
> *pWord++ = NumBytes;
> pDWord = (DWORD *) &Buffer[DataOffset+6];
> *pDWord++ = Offset;
> Total = DataOffset+10;
> Num = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &Num, TRUE,
> FALSE);
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> //if (Error)
> // return Error;
> if (Num)
> {
> short int *pError = (short int *) (RetBuffer+PACKET_HEADER_SIZE);
>
> if (!((*pError) & 0x0FFF) || (*pError == HEIE_LENGTH_WARNING))
> {
> // Copy the memory.
> memcpy(pBuffer, RetBuffer+PACKET_HEADER_SIZE+2, NumBytes);
> }
>
> return *pError;
> }
> else
> return HEIE_ZERO_BYTES_RECEIVED;
>
> /* return 0; */
> }
>
> __declspec(dllexport) int HEIWriteMemory(HEIDevice *pDevice, WORD
> Type, DWORD Offset, WORD NumBytes, BYTE *pBuffer)
> {
> BYTE Buffer[600];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int Num;
> WORD *pWord;
> DWORD *pDWord;
> if (NumBytes > 512)
> return HEIE_DATA_TOO_LARGE;
> Buffer[DataOffset] = FUN_WRITE_MEMORY;
> Buffer[DataOffset+1] = 0;
>
> pWord = (WORD *) &Buffer[DataOffset+2];
> *pWord++ = Type;
> *pWord++ = NumBytes;
> pDWord = (DWORD *) &Buffer[DataOffset+6];
> *pDWord++ = Offset;
>
> memcpy(Buffer+DataOffset+10, pBuffer, NumBytes);
> Total = DataOffset+10+NumBytes;
> Num = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &Num, TRUE,
> FALSE);
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> //if (Error) return Error;
> if (Num)
> return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));
> else
> return HEIE_ZERO_BYTES_RECEIVED;
>
> /* return 0; */
> }
>
> __declspec(dllexport) int HEIAccessMemory(HEIDevice *pDevice, MemRef
> MemRefs[], WORD NumRefs)
> {
> WORD DataOffset = pDevice->DataOffset;
> BYTE Buffer[600];
> BYTE RetBuffer[600];
> BYTE *pSendData;
> WORD x;
> WORD *pWord;
> WORD ReadSize = 2 + 2; // Returned error value is 2 bytes long
> // Returned num MemRefs is 2 bytes long
> WORD TotalSize = 4 + DataOffset; // Header info is 4 bytes long
> int Num;
> int Error;
> Buffer[DataOffset] = FUN_ACCESS_MEMORY;
> Buffer[DataOffset+1] = 0;
> pWord = (WORD *) &Buffer[DataOffset+2];
> *pWord = NumRefs;
> pSendData = &Buffer[DataOffset+4];
> for (x=0; x<NumRefs; x++)
> {
> memcpy(pSendData, &MemRefs[x], sizeof(MemRefDetail));
> TotalSize += sizeof(MemRefDetail);
> pSendData += sizeof(MemRefDetail);
> if (MemRefs[x].Detail.Direction == ACCESS_READ)
> {
> // Read request.
> ReadSize += (MemRefs[x].Detail.NumBytes + sizeof(MemRefDetail));
> }
> else if (MemRefs[x].Detail.Direction == ACCESS_WRITE)
> {
> // Write request.
> memcpy(pSendData, MemRefs[x].pBuffer, MemRefs[x].Detail.NumBytes);
> TotalSize += MemRefs[x].Detail.NumBytes;
> pSendData += MemRefs[x].Detail.NumBytes;
> }
> else
> {
> return HEIE_INVALID_REQUEST;
> }
> if ((TotalSize > sizeof(Buffer)) || (ReadSize > sizeof(RetBuffer)))
> {
> return HEIE_DATA_TOO_LARGE;
> }
> }
> // Ready to send.
> Num = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, TotalSize, RetBuffer, &Num,
> TRUE, FALSE);
> //if (Error) return Error;
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> if (Num)
> {
> short int *pError = (short int *) (RetBuffer+PACKET_HEADER_SIZE);
> short int *pNum = (short int *) (RetBuffer+PACKET_HEADER_SIZE+2);
>
> //if (!*pError && *pNum)
> if (!((*pError) & 0x0FFF) && *pNum)
> {
> // No errors, and we have some read requests returned.
> WORD x;
> MemRefDetail *pReturnDetail = (MemRefDetail *) (RetBuffer
> +PACKET_HEADER_SIZE+4);
> for (x=0; x<NumRefs; x++)
> {
> // Find a read request.
> if (MemRefs[x].Detail.Direction == ACCESS_READ)
> {
> // Read request; Make sure it matches.
> if (MemRefs[x].Detail.Type == pReturnDetail->Type &&
> MemRefs[x].Detail.Offset == pReturnDetail->Offset &&
> MemRefs[x].Detail.NumBytes == pReturnDetail->NumBytes)
> {
> // Requests match, so copy data.
> BYTE *pData = (BYTE *) pReturnDetail;
> pData += sizeof(MemRefDetail);
> memcpy(MemRefs[x].pBuffer, pData, MemRefs[x].Detail.NumBytes);
> // Reset for next one.
> pData += MemRefs[x].Detail.NumBytes;
> pReturnDetail = (MemRefDetail *) pData;
> }
> else
> {
> // Requests don't match, so return error.
> return HEIE_INVALID_RESPONSE;
> }
> }
> }
> }
>
> return *pError;
> }
> else
> return HEIE_ZERO_BYTES_RECEIVED;
> }
>
> __declspec(dllexport) int HEIENumMemory(HEIDevice *pDevice, WORD
> *pSizeofDataInTypes, MemoryTypeDef *pData)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[600];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int Retval;
> int NumBytes;
> Buffer[DataOffset] = (BYTE) FUN_ENUM_MEMORY; /* This is the
> function code! */
> Total = DataOffset+1;
> NumBytes = sizeof(RetBuffer);
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> /* Check for error and not warning. */
> //if (Error)
> // return Error;
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> /*int NumTypes; */
> short int *pInt = (short int *) (RetBuffer+PACKET_HEADER_SIZE);
> short int *pNumTypes = (short int *) (RetBuffer+PACKET_HEADER_SIZE
> +2);
> if ((WORD) *pNumTypes > *pSizeofDataInTypes)
> {
> Retval = HEIE_BUFFER_TOO_SMALL;
> *pNumTypes = *pSizeofDataInTypes;
> }
> if (*pInt)
> Retval = *pInt;
> (*pSizeofDataInTypes) = *pNumTypes;
> memcpy((char *) pData, (char *) (RetBuffer+PACKET_HEADER_SIZE+4),
> (*pNumTypes) * sizeof(MemoryTypeDef));
> }
> else
> {
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> }
> return Retval;
> }
> //BYTE SharedRamArea = 0;
> __declspec(dllexport) int HEIReadSharedRAM(HEIDevice *pDevice, WORD
> Base, WORD Slot, WORD Address, WORD Bytes2Read, BYTE *pBuffer)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[600];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int Num;
> WORD *pWord;
> BYTE SharedRamArea = 0;
> Buffer[DataOffset] = FUN_READ_SHARED_RAM;
> if (Address & 0x8000)
> {
> SharedRamArea = 1;
> Address &= 0x7FFF;
> }
> Buffer[DataOffset+1] = SharedRamArea;
>
> pWord = (WORD *) &Buffer[DataOffset+2];
> *pWord++ = Base;
> *pWord++ = Slot;
> *pWord++ = Address;
> *pWord++ = Bytes2Read;
> Total = DataOffset+10;
> Num = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &Num, TRUE,
> FALSE);
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> //if (Error)
> // return Error;
> if (Num)
> {
> short int *pError = (short int *) (RetBuffer+PACKET_HEADER_SIZE);
>
> //if (!*pError || (*pError == LENGTH_WARNING))
> if (!((*pError) & 0x0FFF) || (*pError == HEIE_LENGTH_WARNING))
> {
> // Copy the memory.
> memcpy(pBuffer, RetBuffer+PACKET_HEADER_SIZE+2, Bytes2Read);
> }
>
> return *pError;
> }
> else
> return HEIE_ZERO_BYTES_RECEIVED;
>
> /* return 0; */
> }
>
> __declspec(dllexport) int HEIWriteSharedRAM(HEIDevice *pDevice, WORD
> Base, WORD Slot, WORD Address, WORD Bytes2Write, BYTE *pBuffer)
> {
> BYTE Buffer[600];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int Num;
> WORD *pWord;
> BYTE SharedRamArea = 0;
> if (Bytes2Write > 256)
> return HEIE_DATA_TOO_LARGE;
> Buffer[DataOffset] = FUN_WRITE_SHARED_RAM;
> if (Address & 0x8000)
> {
> SharedRamArea = 1;
> Address &= 0x7FFF;
> }
> Buffer[DataOffset+1] = SharedRamArea;
>
> pWord = (WORD *) &Buffer[DataOffset+2];
> *pWord++ = Base;
> *pWord++ = Slot;
> *pWord++ = Address;
> *pWord++ = Bytes2Write;
>
> memcpy(Buffer+DataOffset+10, pBuffer, Bytes2Write);
> Total = DataOffset+10+Bytes2Write;
> Num = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &Num, TRUE,
> FALSE);
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> //if (Error) return Error;
> if (Num)
> return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));
> else
> return HEIE_ZERO_BYTES_RECEIVED;
>
> /* return 0; */
> }
>
> /*
> ** Calculate, 16 Bit CRC
> */
> /* number of bits in CRC: don't change it. */
> #define W 16
> /* this the number of bits per char: don't change it. */
> #define B 8
> static unsigned short crctab[1<<B] = {
> 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6,
> 0x70e7,
> 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce,
> 0xf1ef,
> 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7,
> 0x62d6,
> 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff,
> 0xe3de,
> 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4,
> 0x5485,
> 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac,
> 0xd58d,
> 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695,
> 0x46b4,
> 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d,
> 0xc7bc,
> 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802,
> 0x3823,
> 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a,
> 0xb92b,
> 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33,
> 0x2a12,
> 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b,
> 0xab1a,
> 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60,
> 0x1c41,
> 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68,
> 0x9d49,
> 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51,
> 0x0e70,
> 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59,
> 0x8f78,
> 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e,
> 0xe16f,
> 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046,
> 0x6067,
> 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f,
> 0xf35e,
> 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277,
> 0x7256,
> 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c,
> 0xc50d,
> 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424,
> 0x4405,
> 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d,
> 0xd73c,
> 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615,
> 0x5634,
> 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a,
> 0xa9ab,
> 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882,
> 0x28a3,
> 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb,
> 0xbb9a,
> 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3,
> 0x3a92,
> 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8,
> 0x8dc9,
> 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0,
> 0x0cc1,
> 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9,
> 0x9ff8,
> 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1,
> 0x1ef0
> };
> WORD CalcCRC(WORD icrc,
> BYTE *icp,
> WORD icnt)
> {
> register WORD crc = icrc;
> register BYTE *cp = icp;
> register WORD cnt = icnt;
> while( cnt-- )
> crc = (crc<<B) ^ crctab[(crc>>(W-B)) ^ *cp++];
> return( crc );
> }
>
> /*
> **
> ** WinPLC Specific Functions
> **
> */
> __declspec(dllexport) int WPLCSetOSLoad(HEIDevice *pDevice, int Val)
> {
> BYTE Buffer[100];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int NumBytes;
> Buffer[DataOffset] = FUN_SET_OS_LOAD;
> Buffer[DataOffset+1] = ~FUN_SET_OS_LOAD;
> memcpy(&Buffer[DataOffset+2], &Val, sizeof(int));
> Total = DataOffset+2+sizeof(int);
> NumBytes = sizeof(RetBuffer);
> return _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> }
>
> __declspec(dllexport) int WPLCReboot(HEIDevice *pDevice)
> {
> BYTE Buffer[100];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int NumBytes;
> Buffer[DataOffset] = FUN_REBOOT;
> Buffer[DataOffset+1] = ~FUN_REBOOT;
> Total = DataOffset+2;
> NumBytes = sizeof(RetBuffer);
> return _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> }
> __declspec(dllexport) int HEIReboot(HEIDevice *pDevice)
> {
> BYTE Buffer[100];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int NumBytes;
> Buffer[DataOffset] = FUN_REBOOT;
> Buffer[DataOffset+1] = ~FUN_REBOOT;
> Total = DataOffset+2;
> NumBytes = sizeof(RetBuffer);
> return _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> }
>
> __declspec(dllexport) int WPLCRunProgram(HEIDevice *pDevice, BYTE
> *pProgram)
> {
> BYTE Buffer[500];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> BYTE *pArgs, *pData;
> WORD Total;
> int NumBytes;
> short int *pError;
> memset(Buffer, 0, sizeof(Buffer));
> Buffer[DataOffset] = FUN_RUN_PROGRAM;
> Buffer[DataOffset+1] = ~FUN_RUN_PROGRAM;
> pArgs = pProgram;
> if (!*pArgs)
> return -1;
> // Skip whitespace at front.
> while (*pArgs == ' ')
> pArgs++;
> pData = &Buffer[DataOffset+2];
> // Copy program name.
> while (*pArgs && (*pArgs != ' '))
> {
> *pData++ = *pArgs++;
> }
> while (isspace(*pArgs))
> pArgs++;
> strcpy((char *) &Buffer[DataOffset+66], (char *) pArgs);
> Total = DataOffset+2+64+strlen((char *) pArgs)+1;
> NumBytes = sizeof(RetBuffer);
> _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes, TRUE,
> FALSE);
> pError = (short int *) (RetBuffer+PACKET_HEADER_SIZE);
> return *pError;
> }
>
> /*
> **
> ** THIS IS THE MODIFIED SERIAL PORT FUNCTIONS THAT ACCEPT A BYTE FOR
> THE PORT NUMBER
> **
> */
> __declspec(dllexport) int HEIWriteCommEx(HEIDevice *pDevice, BYTE
> Port, WORD Num2Write, BYTE *pData)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> WORD *pWord;
> int Error;
> int NumBytes;
> //Port = (Port - 1) << 4;
> Buffer[DataOffset] = FUN_SERIAL_PORT;
> Buffer[DataOffset+1] = SPF_WRITE_COMM + 0x80; //Port;
> Buffer[DataOffset+2] = Port-1;
> pWord = (WORD *) &Buffer[DataOffset+3];
> *pWord = Num2Write;
> if (Num2Write > (sizeof(Buffer) - DataOffset - 5))
> return HEIE_DATA_TOO_LARGE;
> memcpy(Buffer+DataOffset+5, pData, Num2Write);
> Total = DataOffset+5+Num2Write;
> NumBytes = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> //if (Error) return Error;
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> if (NumBytes)
> return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));
> else
> return HEIE_ZERO_BYTES_RECEIVED;
> }
> __declspec(dllexport) int HEIReadCommEx(HEIDevice *pDevice, BYTE
> Port, WORD *pNum2Read, BYTE *pData)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> WORD *pWord;
> int Error;
> int Retval;
> int NumBytes;
> //Port = (Port - 1) << 4;
> Buffer[DataOffset] = FUN_SERIAL_PORT;
> Buffer[DataOffset+1] = SPF_READ_COMM + 0x80; //Port;
> Buffer[DataOffset+2] = Port-1;
> pWord = (WORD *) &Buffer[DataOffset+3];
> *pWord = *pNum2Read;
> Total = DataOffset+5;
> NumBytes = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> //if (Error) return Error;
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> short int *pInt = (short int *) (RetBuffer+PACKET_HEADER_SIZE);
> short int *pNumReturned = (short int *) (RetBuffer
> +PACKET_HEADER_SIZE+2);
> if (*pInt)
> Retval = *pInt;
> (*pNum2Read) = *pNumReturned;
> memcpy(pData, RetBuffer+PACKET_HEADER_SIZE+4, *pNumReturned);
> }
> else
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> return Retval;
> }
> __declspec(dllexport) int HEIGetRXAvailableEx(HEIDevice *pDevice,
> BYTE Port, WORD *pAvailable)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int NumBytes;
> //Port = (Port - 1) << 4;
> Buffer[DataOffset] = FUN_SERIAL_PORT;
> Buffer[DataOffset+1] = SPF_RX_AVAILABLE + 0x80; //Port;
> Buffer[DataOffset+2] = Port-1;
> Total = DataOffset+3;
> NumBytes = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> //if (Error) return Error;
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> if (NumBytes)
> {
> *pAvailable = *((WORD *) (RetBuffer+PACKET_HEADER_SIZE+2));
> return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));
> }
> else
> return HEIE_ZERO_BYTES_RECEIVED;
> }
> __declspec(dllexport) int HEIFlushRXQueueEx(HEIDevice *pDevice, BYTE
> Port)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int NumBytes;
> //Port = (Port - 1) << 4;
> Buffer[DataOffset] = FUN_SERIAL_PORT;
> Buffer[DataOffset+1] = SPF_RX_FLUSH + 0x80; //Port;
> Buffer[DataOffset+2] = Port-1;
> Total = DataOffset+3;
> NumBytes = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> //if (Error) return Error;
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> if (NumBytes)
> return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));
> else
> return HEIE_ZERO_BYTES_RECEIVED;
> }
> __declspec(dllexport) int HEIFlushTXQueueEx(HEIDevice *pDevice, BYTE
> Port)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int NumBytes;
> //Port = (Port - 1) << 4;
> Buffer[DataOffset] = FUN_SERIAL_PORT;
> Buffer[DataOffset+1] = SPF_TX_FLUSH + 0x80; //Port;
> Buffer[DataOffset+2] = Port-1;
> Total = DataOffset+3;
> NumBytes = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> //if (Error) return Error;
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> if (NumBytes)
> return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));
> else
> return HEIE_ZERO_BYTES_RECEIVED;
> }
> __declspec(dllexport) int HEISetupSerialPortEx(HEIDevice *pDevice,
> BYTE Port, SerialSetup *pSetup, BOOL WriteToFlash)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int NumBytes;
> //Port = (Port - 1) << 4;
> Buffer[DataOffset] = FUN_SERIAL_PORT;
> Buffer[DataOffset+1] = SPF_SETUP + 0x80; //Port;
> Buffer[DataOffset+2] = Port-1;
> Buffer[DataOffset+3] = (BYTE) WriteToFlash;
> Buffer[DataOffset+4] = 0;
> memcpy(Buffer+DataOffset+5, pSetup, sizeof(SerialSetup));
> Total = DataOffset+5+sizeof(SerialSetup);
> NumBytes = sizeof(RetBuffer);
> if (WriteToFlash)
> {
> pDevice->Timeout += EXTRA_TIME_FOR_SETUP_DATA;
> Error = SendPacketTwoResponses(pDevice, Buffer, Total, RetBuffer,
> &NumBytes,
> TRUE, FALSE,
> 0, NULL,
> 30000, TRUE, TRUE);
> pDevice->Timeout -= EXTRA_TIME_FOR_SETUP_DATA;
> }
> else
> {
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> }
> //if (Error)
> // return Error;
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> if (NumBytes)
> return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));
> else
> return HEIE_ZERO_BYTES_RECEIVED;
> }
>
> __declspec(dllexport) int HEIReadSerialPortSetupEx(HEIDevice
> *pDevice, BYTE Port, SerialSetup *pSetup)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int NumBytes;
> //Port = (Port - 1) << 4;
> Buffer[DataOffset] = FUN_SERIAL_PORT;
> Buffer[DataOffset+1] = SPF_READ_SETUP + 0x80; //Port;
> Buffer[DataOffset+2] = Port-1;
> Buffer[DataOffset+3] = 0;
> Buffer[DataOffset+4] = 0;
> Total = DataOffset+5;
> NumBytes = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> //if (Error) return Error;
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> if (NumBytes)
> {
> // Copy data into user buffer.
> memcpy(pSetup, RetBuffer+PACKET_HEADER_SIZE, sizeof(SerialSetup));
> return 0;
> }
> else
> return HEIE_ZERO_BYTES_RECEIVED;
> }
>
> __declspec(dllexport) int HEIGetTXLeftEx(HEIDevice *pDevice, BYTE
> Port, WORD *pLeft)
> {
> BYTE Buffer[200];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> //int Retval;
> int NumBytes;
> //Port = (Port - 1) << 4;
> Buffer[DataOffset] = FUN_SERIAL_PORT;
> Buffer[DataOffset+1] = SPF_TX_LEFT + 0x80; //Port;
> Buffer[DataOffset+2] = Port-1;
> Total = DataOffset+3;
> NumBytes = sizeof(RetBuffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> TRUE, FALSE);
> //if (Error) return Error;
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> //Retval = Error;
> if (NumBytes)
> {
> *pLeft = *((WORD *) (RetBuffer+PACKET_HEADER_SIZE+2));
> return *((short int *) (RetBuffer+PACKET_HEADER_SIZE));
> }
> else
> return HEIE_ZERO_BYTES_RECEIVED;
> }
> __declspec(dllexport) int HEIAccessComm(HEIDevice *pDevice, WORD
> SendDataSize, BYTE *pSendData, WORD *pReturnDataSize, BYTE
> *pReturnData)
> {
> BYTE Buffer[1500];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> WORD *pWord;
> int Error;
> int NumBytes;
> int Retval;
> Buffer[DataOffset] = FUN_SERIAL_PORT;
> Buffer[DataOffset+1] = SPF_ACCESS_COMM;
> pWord = (WORD *) &Buffer[DataOffset+2];
> *pWord = SendDataSize;
> if (SendDataSize > (sizeof(Buffer) - DataOffset - 4))
> return HEIE_DATA_TOO_LARGE;
> memcpy(Buffer+DataOffset+4, pSendData, SendDataSize);
> Total = DataOffset+4+SendDataSize;
> NumBytes = sizeof(Buffer);
>
> Error = _SendPacket(pDevice, Buffer, Total, Buffer, &NumBytes,
> TRUE, FALSE);
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> short int *pInt = (short int *) (Buffer+PACKET_HEADER_SIZE);
> short int *pNumReturned = (short int *) (Buffer+PACKET_HEADER_SIZE
> +2);
> if (*pInt)
> Retval = *pInt;
> if (pReturnData && pReturnDataSize)
> {
> if (*pNumReturned > *pReturnDataSize)
> {
> Retval = HEIE_BUFFER_TOO_SMALL;
> }
> else
> {
> (*pReturnDataSize) = *pNumReturned;
> }
> memcpy(pReturnData, Buffer+PACKET_HEADER_SIZE+4, *pReturnDataSize);
> }
> }
> else
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> return Retval;
> }
>
> __declspec(dllexport) int HEIWriteEZethernetPgmSpace(HEIDevice
> *pDevice, BYTE *pData, WORD SizeofData)
> {
> BYTE Buffer[600];
> BYTE RetBuffer[200];
> WORD DataOffset = pDevice->DataOffset;
> WORD *pWord;
> WORD Total;
> int Error;
> int Retval;
> int NumBytes;
> Buffer[DataOffset] = (BYTE)FUN_USER_CONFIG_PANEL; /* This is the
> function code! */
> Buffer[DataOffset+1] = 0;
> pWord = (WORD *) &Buffer[DataOffset+2];
> Total = DataOffset+4+SizeofData;
> // FYI: Incoming size should never be greater than 316 bytes.
> // 60 bytes control + 255 Max AVG packet size + 1 byte for
> // the start character.
> if (Total > sizeof(Buffer) || SizeofData > 316)
> return HEIE_DATA_TOO_LARGE;
> (void)memcpy(&Buffer[DataOffset+4], pData, SizeofData);
> NumBytes = sizeof(RetBuffer);
>
> pDevice->Timeout += EXTRA_TIME_FOR_SETUP_DATA;
> Error = SendPacketTwoResponses(pDevice, Buffer, Total, RetBuffer,
> &NumBytes,
> TRUE, FALSE,
> 0, NULL,
> 30000, TRUE, TRUE);
> pDevice->Timeout -= EXTRA_TIME_FOR_SETUP_DATA;
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> short int *pInt = (short int *) (RetBuffer+PACKET_HEADER_SIZE);
> if (*pInt)
> Retval = *pInt;
> }
> else
> {
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> }
> return Retval;
> }
>
> /*
> ** ERM Functions.
> */
> #define FUN_COMMAND 6
> #define FUN_READ_DATA 7
> #define FUN_WRITE_DATA 8
> #define FUN_STATUS_INWORK 1
> #define FUN_STATUS_DONE 2
> #define FUN_STATUS_ERROR 3
> __declspec(dllexport) int HEIWriteERMData(HEIDevice *pDevice, WORD
> Base, WORD Slot, BYTE DataType, BYTE *pData, WORD NumBytes, WORD
> Offset)
> {
> WORD Data[6];
> WORD *pOffset;
> WORD *pExtended;
> WORD *pNumBytes;
> int Index = 0;
> // Common header
> Data[Index++] = 0; // Function + Status (ClearFunction until
> all other data is written)
> Data[Index++] = 0; // Error
> // Function specific header
> Data[Index++] = DataType; // Data type
> pOffset = (WORD *) &Data[Index++]; // Pointer to Offset
> pNumBytes = (WORD *) &Data[Index++];// Pointer to num bytes
> pExtended = (WORD *) &Data[Index++]; // Pointer to extended
> *pOffset = Offset;
> *pNumBytes = 256;
> *pExtended = 0;
>
> while (NumBytes)
> {
> int Error;
> //memcpy(&Data[11], pOutputData, *pNumBytes);
> if (*pNumBytes > NumBytes)
> *pNumBytes = NumBytes;
> Data[0] = 0;
> Data[1] = 0;
> // Write Header first.
> Error = HEIWriteSharedRAM(pDevice, Base, Slot, 0x30 + 0x8000,
> sizeof(Data), (BYTE *) Data);
> if (Error)
> {
> //printf("\nError %d (0x%X) from HEIWriteSharedRAM", Error, Error);
> return Error;
> }
> // Next write data.
> Error = HEIWriteSharedRAM(pDevice, Base, Slot, 0x30+sizeof(Data) +
> 0x8000, *pNumBytes, pData);
> if (Error)
> {
> //printf("\nError %d (0x%X) from HEIWriteSharedRAM", Error, Error);
> return Error;
> }
> // Now write the REAL command.
> Data[0] = FUN_WRITE_DATA;
> Error = HEIWriteSharedRAM(pDevice, Base, Slot, 0x30+ 0x8000, 1,
> (BYTE *) Data);
> if (Error)
> {
> //printf("\nError %d (0x%X) from HEIWriteSharedRAM", Error, Error);
> return Error;
> }
> else
> {
> // Wait for it to complete.
> DWORD StartTime = HEIIGetCounter();
> BOOL Done = FALSE;
> do
> {
> BYTE bData[4];
> Error = HEIReadSharedRAM(pDevice, Base, Slot, 0x30+ 0x8000, 4,
> (BYTE *) bData);
> if (Error)
> {
> //printf("\nError %d (0x%X) from HEIReadSharedRAM", Error,
> Error);
> return Error;
> }
> else
> {
> if ((bData[1] & 0xFF) == FUN_STATUS_DONE)
> {
> Done = TRUE;
> }
> else if ((bData[1] & 0xFF) == FUN_STATUS_ERROR)
> {
> return bData[2]; // Return Error
> }
> }
> } while (!Done && TimeDiff(StartTime, HEIIGetCounter()) <
> pDevice->Timeout);
> if (!Done)
> {
> //printf("\nTimeout waiting for request to complete.");
> return HEIE_TIMEOUT;
> }
> }
> pData += *pNumBytes;
> (*pOffset) += *pNumBytes;
> NumBytes -= *pNumBytes;
> }
> #if 0
> if ((DataType == DATA_OUTPUT) && (Flags & 0x01))
> {
> return WPLCDoERMCommand(Base, Slot, COMMAND_PROCESS_IO, 0, 0);
> }
> #endif
> return 0;
> }
> __declspec(dllexport) int HEIReadERMData(HEIDevice *pDevice, WORD
> Base, WORD Slot, BYTE DataType, BYTE *pData, WORD NumBytes, WORD
> Offset)
> {
> WORD Data[6];
> WORD *pOffset;
> WORD *pNumBytes;
> WORD *pExtended;
> int Index = 0;
> // Common header
> Data[Index++] = 0; // Function + Status (ClearFunction until
> all other data is written)
> Data[Index++] = 0; // Error
> // Function specific header
> Data[Index++] = DataType; // Data type
> pOffset = (WORD *) &Data[Index++]; // Pointer to Offset
> pNumBytes = (WORD *) &Data[Index++];// Pointer to num bytes
> pExtended = (WORD *) &Data[Index++]; // Pointer to extended
> *pOffset = Offset;
> *pNumBytes = 256;
> *pExtended = 0;
> //RETAILMSG(1, (TEXT("\r\nWPLCReadERMData Base: %d Slot: %d Type:
> %d Num: %d"), Base, Slot, DataType, NumBytes));
> while (NumBytes)
> {
> int Error;
> Data[0] = 0;
> Data[1] = 0;
> if (*pNumBytes > NumBytes)
> {
> *pNumBytes = NumBytes;
> }
> Error = HEIWriteSharedRAM(pDevice, Base, Slot, 0x30+0x8000,
> sizeof(Data), (BYTE *) Data);
> if (Error)
> {
> //printf("\nError %d (0x%X) from HEIWriteSharedRAM", Error, Error);
> return Error;
> }
> // Now write the REAL command.
> Data[0] = FUN_READ_DATA;
> Error = HEIWriteSharedRAM(pDevice, Base, Slot, 0x30+0x8000, 2,
> (BYTE *) Data);
> if (Error)
> {
> //printf("\nError %d (0x%X) from HEIWriteSharedRAM", Error, Error);
> return Error;
> }
> else
> {
> // Wait for it to complete.
> DWORD StartTime = HEIIGetCounter();
> BOOL Done = FALSE;
> do
> {
> BYTE bData[4];
> Error = HEIReadSharedRAM(pDevice, Base, Slot, 0x30+0x8000, 4,
> bData);
> if (Error)
> {
> //printf("\nError %d (0x%X) from HEIReadSharedRAM", Error,
> Error);
> return Error;
> }
> else
> {
> //RETAILMSG(1, (TEXT("\r\nbData: 0x%X 0x%X 0x%X 0x%X"), bData[0],
> bData[1], bData[2], bData[3]));
> //if (((Data[0]>>8) & 0xFF) == FUN_STATUS_DONE)
> if (bData[1] == FUN_STATUS_DONE)
> {
> // Read the rest of the data.
> Error = HEIReadSharedRAM(pDevice, Base, Slot, 0x30+sizeof(Data)
> +0x8000, *pNumBytes, pData);
> if (Error)
> {
> //printf("\nError %d (0x%X) from HEIReadSharedRAM", Error,
> Error);
> return Error;
> }
> Done = TRUE;
> }
> //else if (((Data[0]>>8) & 0xFF) == FUN_STATUS_ERROR)
> else if (bData[1] == FUN_STATUS_ERROR)
> {
> return Data[2];
> // memcpy(pInputData, &Data[11], *pNumBytes);
> }
> }
> } while (!Done && TimeDiff(StartTime, HEIIGetCounter()) <
> pDevice->Timeout);
> if (!Done)
> {
> //printf("\nTimeout waiting for request to complete.");
> return HEIE_TIMEOUT;
> }
> }
> pData += *pNumBytes;
> (*pOffset) += *pNumBytes;
> NumBytes -= *pNumBytes;
> }
> return 0;
> }
> __declspec(dllexport) int HEIDoERMCommand(HEIDevice *pDevice, WORD
> Base, WORD Slot, WORD Command)
> {
> DWORD StartTime;
> WORD Data[3];
> int Index = 0;
> int Error;
> // Common header
> Data[Index++] = 0; // Command and Status (Set Command to zero until
> rest of data is written)
> Data[Index++] = 0; // Error
>
> // Function specific header
> Data[Index++] = Command;
> Error = HEIWriteSharedRAM(pDevice, Base, Slot, 0x30 + 0x8000,
> sizeof(Data), (BYTE *) Data);
> if (Error)
> {
> //printf("\nError %d (0x%X) from HEIWriteSharedRAM", Error, Error);
> return Error;
> }
> // Now write the REAL command.
> Data[0] = FUN_COMMAND;
> Error = HEIWriteSharedRAM(pDevice, Base, Slot, 0x30+0x8000, 2,
> (BYTE *) Data);
> if (Error)
> {
> //printf("\nError %d (0x%X) from HEIWriteSharedRAM", Error, Error);
> return Error;
> }
> // Wait for it to complete.
> StartTime = HEIIGetCounter();
> while (TimeDiff(StartTime, HEIIGetCounter()) < pDevice->Timeout)
> {
> BYTE bData[4];
> Error = HEIReadSharedRAM(pDevice, Base, Slot, 0x30+0x8000, 4,
> (BYTE *) bData);
> if (!Error)
> {
> if ((bData[1] & 0xFF) == FUN_STATUS_DONE)
> return 0;
> else if ((bData[1] & 0xFF) == FUN_STATUS_ERROR)
> return bData[2];
> }
> }
> return HEIE_TIMEOUT;
> }
>
> __declspec(dllexport) int HEIDoERMCommandEx(HEIDevice *pDevice, WORD
> Base, WORD Slot, WORD Command, BYTE *pExtra, WORD ExtraLen)
> {
> DWORD StartTime;
> BYTE Data[300];
> int Index = 0;
> int Error;
> WORD *pCommand;
> BOOL Done;
> // Common header
> Data[Index++] = 0; // Command and Status (Set Command to zero until
> rest of data is written)
> Data[Index++] = 0; // Error
> Data[Index++] = 0; // Command and Status (Set Command to zero until
> rest of data is written)
> Data[Index++] = 0; // Error
>
> // Function specific header
> pCommand = (WORD *) &Data[Index];
> *pCommand = Command;
> Index += 2;
> memcpy(&Data[Index], pExtra, ExtraLen);
> Error = HEIWriteSharedRAM(pDevice, Base, Slot, 0x30 + 0x8000,
> (WORD)(ExtraLen + 6), Data);
> if (Error)
> {
> //printf("\nError %d (0x%X) from HEIWriteSharedRAM", Error, Error);
> return Error;
> }
> // Now write the REAL command.
> Data[0] = FUN_COMMAND;
> Data[1] = 0;
> Error = HEIWriteSharedRAM(pDevice, Base, Slot, 0x30+0x8000, 2,
> (BYTE *) Data);
> if (Error)
> {
> //printf("\nError %d (0x%X) from HEIWriteSharedRAM", Error, Error);
> return Error;
> }
> // Wait for it to complete.
> Done = FALSE;
> StartTime = HEIIGetCounter();
> do
> {
> BYTE bData[4];
> Error = HEIReadSharedRAM(pDevice, Base, Slot, 0x30+0x8000, 4,
> bData);
> if (!Error)
> {
> if (bData[1] == FUN_STATUS_DONE)
> Done = TRUE;
> else if (bData[1] == FUN_STATUS_ERROR)
> return (int) (((WORD) bData[2]) + (((WORD) bData[3]) << 8));
> }
> } while (!Done && TimeDiff(StartTime, HEIIGetCounter()) < pDevice-
> >Timeout);
> if (!Done)
> return HEIE_TIMEOUT;
> return 0;
> }
>
> NODELIST *EZGetNodeList(unsigned short int *TotalEZ)
> {
> static NODELIST EZList[200];
> static HEIDevice HEIDevices[100];
> static HEITransport TP;
> unsigned short int i, j; // Index variables
> int Error, MaxDevices, MaxEZDevices;
> WORD Timeout = 100;
> WORD Retrys = 2;
> WORD SizeofData;
> BOOL Broadcast = FALSE;
> BYTE Data[500];
> BYTE *pData = Data;
> DeviceDef dd;
> WORD NumDevices;
> HEITransport *tp = &TP;
> ENetAddress *pSourceAddress = (ENetAddress *)NULL;
> tp->Transport = HEIT_WINSOCK;
> tp->Protocol = HEIP_IPX;
> *TotalEZ = 0; // Set to zero until proven otherwise.
> Error = HEIOpenTransport(tp, HEIAPIVERSION, pSourceAddress);
> if (Error)
> {
> //printf("Error returned from HEIOpenTransport()\n");
> return (NODELIST *)NULL;
> }
> MaxDevices = sizeof(HEIDevices) / sizeof(HEIDevice);
> MaxEZDevices = sizeof(EZList) / sizeof(NODELIST);
> NumDevices = MaxEZDevices;
> Error = HEIQueryDevices(tp, HEIDevices, &NumDevices, HEIAPIVERSION);
> if (Error)
> {
> //printf("Error returned from HEIQueryDevices()\n");
> (void)HEIClose();
> return (NODELIST *)NULL;
> }
>
> j = 0;
> for (i = 0; i < NumDevices; i++)
> {
> if (i > MaxDevices)
> {
> goto ReturnIncompleteList;
> }
> Error = HEIOpenDevice(tp, &HEIDevices[i], HEIAPIVERSION,
> Timeout, Retrys, Broadcast);
> if (Error)
> {
> //printf("IsDeviceEZEthernet: Error %d returned from
> HEIOpenDevice\n", Error);
> return (NODELIST *)NULL;
> }
> Error = HEIReadDeviceDef(&HEIDevices[i], (BYTE *) &dd,
> sizeof(dd));
> if (Error)
> {
> //printf("IsDeviceEZEthernet: Error returned from
> HEIReadDeviceDef\n");
> goto ErrorHandler;
> }
> if (dd.ModuleType == MT_AVG_DISP)
> {
> if (j >= MaxEZDevices)
> goto ErrorHandler;
> SizeofData = sizeof(WORD);
> Error = HEIReadSetupData( &HEIDevices[i],
> DT_NODE_NUMBER, pData, &SizeofData);
> if (Error)
> {
> //printf("Error %d returned from
> HEIReadSetupData1\n", Error);
> goto ErrorHandler;
> }
> else
> {
> (void)memcpy(EZList[j].Node_ID, pData, sizeof(WORD));
> }
> // Get the Node Name
> SizeofData = sizeof(EZList[0].Name);
> Error = HEIReadSetupData(&HEIDevices[i], DT_NODE_NAME,
> pData, &SizeofData);
> if (Error)
> {
> //printf("Error returned from HEIReadSetupData2\n");
> goto ErrorHandler;
> }
> else
> {
> (void)memcpy(EZList[j].Name, pData, SizeofData);
> }
> EZList[j].pDevice = &HEIDevices[i];
> j++;
> }
> else
> {
> // Close the device since it is not an EZ_Ethernet.
> (void)HEICloseDevice(&HEIDevices[i]);
> }
> } // End of for
>
> if (j == 0)
> {
> goto ErrorHandler;
> }
> else
> {
> (void)HEIClose();
> *TotalEZ = j;
> return EZList;
> }
>
> ReturnIncompleteList:
> // If we have process the maximum number of devices we can
> // do, return a list of what we got.
> (void)HEIClose();
> *TotalEZ = j;
> return EZList;
> ErrorHandler:
> (void)HEICloseDevice(&HEIDevices[i]);
> (void)HEIClose();
> return (NODELIST *)NULL;
> }
>
> BOOL EZSendPacket(HEIDevice *pDevice, PGM_BUF *pBuffer, BYTE
> *Error_message, unsigned short int Len)
> {
> int Error;
> #if TC_DEBUG
> int i;
> printf("EZSendPacket: Incoming buffer has:\n");
> for (i = 0; i < Len; i++)
> printf("%c", pBuffer->PgmData[i]);
> printf("\n");
> #endif
> Error = HEIWriteEZethernetPgmSpace(pDevice, (BYTE *)pBuffer-
> >PgmData, Len );
> switch (Error)
> {
> case HEIE_DATA_TOO_LARGE:
> {
> (void)memcpy(&Error_message, "Message size too large",
> 81);
> return FALSE;
> }
>
> case HEIE_ZERO_BYTES_RECEIVED:
> {
> (void)memcpy(&Error_message, "Attempted to send zero-
> length message", 81);
> return FALSE;
> }
> case -1:
> {
> // printf("Error %X returned from
> HEIWriteEZethernetPgmSpace!\n", Error);
> (void)memcpy(&Error_message,
> "HEIWriteEZethernetPgmSpace call failed with -1", 81);
> return FALSE;
> }
> case NO_ERROR:
> {
> //printf("Successfull send from
> HEIWriteEZethernetPgmSpace\n");
> Error_message[0] = '\0';
> return TRUE;
> }
>
> default:
> {
> //printf("Error %X returned from
> HEIWriteEZethernetPgmSpace!\n", Error);
> (void)memcpy(&Error_message,
> "HEIWriteEZethernetPgmSpace call failed with unknown error", 81);
> return FALSE;
> }
> }
> return TRUE;
> }
>
> int WPLCWriteERMData(HEIDevice *pDevice, WORD Base, WORD Slot, BYTE
> DataType, BYTE *pData, WORD NumBytes, WORD Offset)
> {
> return HEIWriteERMData(pDevice, Base, Slot, DataType, pData,
> NumBytes, Offset);
> }
> int WPLCReadERMData(HEIDevice *pDevice, WORD Base, WORD Slot, BYTE
> DataType, BYTE *pData, WORD NumBytes, WORD Offset)
> {
> return HEIReadERMData(pDevice, Base, Slot, DataType, pData,
> NumBytes, Offset);
> }
> int WPLCDoERMCommand(HEIDevice *pDevice, WORD Base, WORD Slot, WORD
> Command)
> {
> return HEIDoERMCommand(pDevice, Base, Slot, Command);
> }
> int WPLCDoERMCommandEx(HEIDevice *pDevice, WORD Base, WORD Slot,
> WORD Command, BYTE *pExtra, WORD ExtraLen)
> {
> return HEIDoERMCommandEx(pDevice, Base, Slot, Command, pExtra,
> ExtraLen);
> }
>
> __declspec(dllexport) int SetCRCMode(int Mode)
> {
> int Old = DoCRC;
> DoCRC = Mode;
> return Old;
> }
>
> /* CONFIG DATA ACCESS */
> __declspec(dllexport) int HEIReadConfigData(HEIDevice *pDevice, BYTE
> *pData, WORD *DataSize)
> {
> BYTE Buffer[100];
> BYTE RetBuffer[1200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int Retval;
> int NumBytes;
>
> Buffer[DataOffset] = FUN_READ_CONFIG_DATA; /* This is the function
> code! */
> Total = DataOffset+1;
> if (pData && *pData == 0xB1)
> {
> Buffer[DataOffset+1] = *pData;
> Total++;
> }
> NumBytes = sizeof(RetBuffer);
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> (pDevice->ParallelPackets) ? FALSE : TRUE, TRUE);
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> short int *pInt = (short int *) &RetBuffer[PACKET_HEADER_SIZE];
> NumBytes -= PACKET_HEADER_SIZE;
> NumBytes -= 2;
> if ((WORD) NumBytes > *DataSize)
> {
> Retval = HEIE_BUFFER_TOO_SMALL;
> NumBytes = *DataSize;
> }
> if (*pInt)
> Retval = (*pInt) | 0x8000;
> memcpy(pData, RetBuffer+PACKET_HEADER_SIZE+2, NumBytes);
> (*DataSize) = NumBytes;
> }
> else
> {
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> (*DataSize) = 0;
> }
> return Retval;
> }
>
> __declspec(dllexport) int HEIWriteConfigData(HEIDevice *pDevice,
> BYTE *pData, WORD SizeofData, BYTE *pReturnData, WORD
> *pSizeofReturnData)
> {
> BYTE Buffer[1200];
> BYTE RetBuffer[1200];
> WORD DataOffset = pDevice->DataOffset;
> WORD Total;
> int Error;
> int Retval;
> int NumBytes;
> Buffer[DataOffset] = FUN_WRITE_CONFIG_DATA; /* This is the
> function code! */
>
> Total = DataOffset+1+SizeofData;
> if (Total > sizeof(Buffer))
> return HEIE_DATA_TOO_LARGE;
> memcpy(Buffer+DataOffset+1, pData, SizeofData);
> NumBytes = sizeof(RetBuffer);
> //NumBytes = *pSizeofReturnData;
>
> Error = _SendPacket(pDevice, Buffer, Total, RetBuffer, &NumBytes,
> (pDevice->ParallelPackets) ? FALSE : TRUE, TRUE);
> /* Check for error and not warning. */
> if (Error && !(Error & HEIW_FIRST_WARNING))
> return Error;
> Retval = Error;
> if (NumBytes)
> {
> short int *pInt = (short int *) &RetBuffer[PACKET_HEADER_SIZE];
> if (pReturnData && pSizeofReturnData)
> {
> NumBytes -= PACKET_HEADER_SIZE;
> NumBytes -= 2;
> if ((WORD) NumBytes > *pSizeofReturnData)
> {
> Retval = HEIE_BUFFER_TOO_SMALL;
> NumBytes = *pSizeofReturnData;
> }
> memcpy(pReturnData, RetBuffer+PACKET_HEADER_SIZE+2, NumBytes);
> (*pSizeofReturnData) = NumBytes;
> }
> if (*pInt)
> Retval = (*pInt) | 0x8000;
> }
> else
> {
> Retval = HEIE_ZERO_BYTES_RECEIVED;
> if (pSizeofReturnData)
> (*pSizeofReturnData) = 0;
> }
> return Retval;
> }
>
> /*
> **
> ** HOST ETHERNET INTERFACE (HEI) - HEADER FILE
> **
> ** Copyright 1996-2001 - Host Automation Products, Inc.
> *
> */
> #if !defined(__HEI_H)
> #define __HEI_H
>
> /* Force structure alignment on single byte boundary */
> #pragma pack(1)
> #if !defined(P_ERMA) & !defined(P_ECOM) & !defined(EBC) & !
> defined(P_ERMA) & !defined(BOOTER) & !defined(PROFIBUS)
> typedef struct
> {
> unsigned IgnoreUserMain : 1;
> unsigned IgnoreVbUserMain : 1;
> unsigned IgnoreDebugMsg : 1;
> unsigned UnusedBits : 29;
> BYTE UnusedBytes[28];
> } StartupSettings;
> #endif
> typedef struct
> {
> WORD SizeofEthernetStats;
> DWORD MissedFrameCount;
> DWORD TransmitCollisionCount;
> DWORD DiscardedPackets;
> DWORD BadCRCCount;
>
> DWORD UnknownTypeCount;
> DWORD SendErrorCount;
> } EthernetStats;
> typedef struct
> {
> BYTE Version;
> BYTE Bytes2Follow;
>
> #if defined (ANSI_C)
> BYTE UnusedBytess[16]; /* Support Info */
> #else
> BYTE SUP_FUN_POLLING : 1; /* Polling one base */
> BYTE SUP_FUN_READ_VER_INFO : 1; /* Version Info */
> BYTE SUP_FUN_READ_SUPPORT_INFO : 1; /* Support Info */
> BYTE SUP_FUN_READ_DEVICE_INFO : 1; /* Device Info */
> BYTE SUP_FUN_POLLING_ALL : 1; /* Polling all bases (returns
> ethernet address) */
> BYTE SUP_FUN_WRITE_IO : 1; /* Write IO base */
> BYTE SUP_FUN_READ_IO : 1; /* Read IO Base */
> BYTE SUP_FUN_READ_BASE_DEF : 1; /* ReadBaseDef */
>
> BYTE SUP_FUN_ENUM_SETUP_DATA : 1; /* Enumerate setup data */
> BYTE SUP_FUN_READ_SETUP_DATA : 1; /* Read setup data */
> BYTE SUP_FUN_WRITE_SETUP_DATA : 1; /* Write setup data */
> BYTE SUP_FUN_DELETE_SETUP_DATA : 1; /* Delete setup data */
> BYTE SUP_FUN_READ_ETHERNET_STATS : 1; /* Read ethernet
> statistics */
> BYTE SUP_FUN_PET_LINK : 1; /* Used to keep the link sense
> timer from firing in the absense of ReadIO or WriteIO messages */
> BYTE SUP_FUN_ADDRESSED_BROADCAST : 1; /* Used to broadcast to a
> particular ethernet address. */
> BYTE SUP_FUN_READ_MODULE_STATUS : 1; /* Read module status short
> BYTEs */
>
> BYTE SUP_FUN_EXTENDED : 1; /* Extended function */
> BYTE SUP_FUN_QUERY_SETUP_DATA : 1; /* Query for particular data
> type/value */
> BYTE SUP_FUN_INIT_BASE_DEF : 1; /* Initialize base def from
> backplane. */
> BYTE SUP_FUN_DATA_BROADCAST : 1; /* Broadcast to a particular
> data type */
> BYTE SUP_FUN_CCM_REQUEST : 1; /* Perform CCM Request */
> BYTE SUP_FUN_KSEQ_REQUEST : 1; /* Perform KSEQ Request */
> BYTE SUP_FUN_BACKPLANE_REQUEST : 1; /* Perform backplane request
> */
> BYTE SUP_FUN_WRITE_BASE_DEF : 1; /* Write Base Def */
>
> BYTE SUP_FUN_EXTEND_RESPONSE : 1; /* Extends the response
> packet. */
> BYTE SUP_FUN_ACK : 1; /* Acknowledge */
> BYTE SUP_FUN_NAK : 1; /* NOT Acknowledge */
> BYTE SUP_FUN_RESPONSE : 1; /* Response */
> BYTE SUP_FUN_SERIAL_PORT : 1; /* Execute serial port function
> (see below) */
> BYTE SUP_FUN_WRITE_MEMORY : 1; /* Write a particular memory
> type */
> BYTE SUP_FUN_READ_MEMORY : 1; /* Read a particular memory type */
> BYTE SUP_FUN_ENUM_MEMORY : 1; /* Get list of all memory types */
> BYTE SUP_FUN_READ_SHARED_RAM : 1; /* Read shared ram */
> BYTE SUP_FUN_WRITE_SHARED_RAM : 1; /* Write shared ram */
> BYTE SUP_FUN_ACCESS_MEMORY : 1; /* Access (read/write) multiple
> memory types */
> BYTE SUP_FUN_COMM_RESPONSE : 1; /* Response to PLC generated
> COMM request */
> BYTE SUP_FUN_COMM_REQ_ACK : 1; /* Function from PLC generated
> COMM request */
> BYTE SUP_FUN_WRITE_IO_NO_READ : 1; /* Write IO base with
> returned read */
> BYTE SUP_FUN_COMM_NO_REQ_ACK : 1; /* Function from PLC generated
> COMM request */
> BYTE SUP_FUN_RUN_PROGRAM : 1; /* Function to execute a program */
> BYTE SUP_FUN_REMOTE_API : 1; /* Function to execute a function
> on remote device */
> BYTE SUP_FUN_NOTIFY : 1; /* Indicates a notification */
> BYTE SUP_FUN_COMPLETION : 1; /* Indicates completion of some
> activity */
> BYTE SUP_FUN_SET_OS_LOAD : 1; /* Set Load OS Parm. */
> BYTE SUP_FUN_REBOOT : 1; /* Reboot OS */
> BYTE SUP_FUN_EXTEND_RESPONSE_FIX : 1; /* Fixed version that extends
> the response packet. */
> BYTE SUP_NEW_STYLE_IO : 1; /* This device supports new style I/O
> requests */
> BYTE SUP_HOT_SWAP : 1; /* True if this device supports hot
> swap */
> BYTE SUP_TCP_IP : 1; /* TRUE if this device supports TCP/IP */
> BYTE SUP_HTTP : 1; /* TRUE if this device supports HTTP */
> BYTE Reserved : 6;
>
> BYTE UnusedBytes[9]; /* Unused */
> #endif
> } SupportDef;
>
> /* Defines for Flags in WPLCSystemInformation structure */
> #define WPLC_FLAG_BATT_LOW 0x01
> /* Masks for LED indicator */
> #define WPLC_LED_POWER 0x01
> #define WPLC_LED_RUN 0x02
>
> typedef struct
> {
> DWORD Flags; /* Bit 0: Battery Low indicator. */
> /* Bit 1-31: Unused */
> DWORD RAMSize; /* Total size of RAM in WinPLC */
> DWORD FlashSize; /* Total size of Flash memory in WinPLC */
> DWORD BattRAMSize; /* Total size of Battery-backed ram in WinPLC */
> DWORD DipSwitches; /* Status of dip switches */
> /* Note: Dip Switches #6 & #7 are reserved for system use. */
> DWORD LEDs; /* LED status indicator (see WPLC_LED_XXXX defines) */
> DWORD OSSize; /* Size of the WinPLC OS Image */
> DWORD FFSTotal; /* Total size of the WinPLC flashed based file
> system */
> DWORD FFSFree; /* Free size of the WinPLC flashed based file
> system */
> DWORD RAMPercentFree; /* Percent of RAM that is free. */
> DWORD RAMPhysicalFree; /* Physical RAM that is free. */
> DWORD VendorID; /* Vendor ID from the WinPLC */
> DWORD CPUClockFrequency;
> BYTE ENetAddress[6];
> BYTE Unused[198];
> } WPLCSystemInformation;
>
>
> /* ERM Defs */
> #define BIT_INPUT 0
> #define BIT_OUTPUT 1
> #define WORD_INPUT 2
> #define WORD_OUTPUT 3
> /* sERMDevice (128 bytes each) */
> typedef struct
> {
> BYTE AddressMode; /* Defines format of address field (see AM_XXX
> below) */
> BYTE Protocol; /* HEIP_HOST, HEIP_IPX, or HEIP_IP, 0 ==
> Unused */
> struct
> {
> union
> {
> /* Use this for AM_ETHER addressing (Protocol: HEIP_IPX or
> HEIP_HOST) */
> BYTE EtherAddr[6]; /* Ethernet network address */
> /* Use this for AM_NODENUM addressing (Protocol: HEIP_IPX or
> HEIP_HOST or HEIP_IP) */
> DWORD Nodenum;
> /* Use this for AM_IPADDR addressing (Protocol: HEIP_IPX or
> HEIP_HOST or HEIP_IP) */
> BYTE IPAddr[4];
> #if defined (ANSI_C)
> } AM;
> #else
> };
> #endif
> BYTE Netnum[4]; /* Used for HEIP_IPX protocol; HEIP_IP */
> WORD Port; /* Used for HEIP_IPX and HEIP_IP protocols */
> union
> {
> BYTE FrameType; /* Used for HEIP_IPX protocol (See FT_XXXX) */
> BYTE GatewayAddress[4]; /* Gateway to use for this device (0's
> for no gateway) */
> #if defined (ANSI_C)
> } AM2;
> #else
> };
> #endif
> /* BYTE Reserved[3];*/
> } Address;
> WORD Timeout; /* Timeout time for this device */
> WORD Retrys; /* Number of time to retry a request before
> reporting error. */
> BYTE ModuleIDs[32]; /* Module ID's for each slot in the
> device */
> WORD Flags; /* See ERM_FLAG_??? defines */
> WORD DataOffsets[4]; /* Data offsets for each type (BIT_INPUT,
> BIT_OUTPUT, */
> /* WORD_INPUT, WORD_OUTPUT) if with a PLC */
> WORD DataSizes[4]; /* Data sizes (in bytes) for each type if
> with a PLC */
> WORD WatchDog; /* Watchdog timeout value to use for this
> device */
> WORD PetFrequency; /* Freq to pet the device to keep WatchDog
> from firing */
> /* Specified in milliseconds. If zero no pets will be
> done */
> WORD FailuresBeforeStandby; /* Number of consecutive failures to
> put device in */
> /* standby mode. */
> BYTE Reserved[50]; /* Reserved (set to zero) */
> } sERMDevice;
> /* Address mode 0 is undefined */
> #define AM_NODENUM 1
> #define AM_NAME 2 /* Not supported in ERM module. */
> #define AM_IPADDR 3
> #define AM_ETHER 4
> /* Interface defines */
> #define IF_UNDEFINED 0 /* ERM I/F not defined / detected */
> #define IF_PLC 1 /* ERM will use a PLC style interface */
> #define IF_WINPLC 2 /* ERM will use a WinPLC style interface
> */
> #define ERM_FLAG_IGNORE_WARNINGS 1 /* If set, warnings from this
> device are ignored */
> #define ERM_FLAG_AUTO_HOT_SWAP 2 /* If set, terminator hot swap is
> automatic */
> /* Frame type defines */
> #define FT_802_2 1
> #define FT_802_3 2
> #define FT_ETHER_II 3
>
> typedef struct sERMConfig
> {
> BYTE Version; /* Version of sERMConfig 0=Unconfigured; 1=
> Current Version */
> BYTE Interface; /* See IF_XXX above. */
> WORD PLCAddresses[4]; /* Address for each type. (BIT_INPUT,
> BIT_OUTPUT, */
> /* WORD_INPUT, WORD_OUTPUT) if with a PLC */
> WORD PLCDataSizes[4]; /* Size (in bytes) for each type if with a
> PLC. */
> DWORD StandbyCycleTime; /* Time to wait when a module is not
> responding before */
> /* trying to access the module again */
> /* If zero, the module will not be accessed again */
> DWORD NotSupportedCycleTime; /* Time to wait when a module is not
> supported before */
> /* trying to access the module again */
> /* If zero, the module will not be accessed again */
> WORD AssumePLCScanTime; /* PLC Scan time to assume for timeout
> purposes if zero, */
> /* default is used */
> BYTE Unused[228];
> } sERMConfig;
> #define MAX_ERM_DEVICES 16
>
> typedef struct sERMDeviceInfo
> {
> BYTE State;
> BYTE Supported : 1;
> BYTE GotAddressInfo : 1;
> BYTE ARPReplyPending : 1;
> BYTE GotBaseDef : 1;
> BYTE GotSupportInfo : 1;
> BYTE GotWatchDogSetupAck : 1;
> BYTE GotWatchDogSetupComplete : 1;
> WORD TotalRetrys;
> WORD LastError;
> } sERMDeviceInfo;
>
> typedef struct sERMInfo
> {
> BYTE Version; /* Version of sERMInfo 1 = current version */
> BYTE AutoDetectedInterface; /* Interface which was auto detected by
> Hx-ERM module */
> BYTE PLCType; /* PLC Type that Hx-ERM module is in rack with
> */
> BYTE BytesInUsedByERM; /* Number of Input bytes that Hx-ERM
> uses */
> /* Currently 32 Bits (4 Bytes) of Error Info */
> BYTE BytesOutUsedByERM; /* Number of Output bytes that Hx-ERM
> uses */
> /* Currently 16 Bits (2 Bytes) of disable bits */
> sERMDeviceInfo DeviceInfo[MAX_ERM_DEVICES];
> WORD Error; /* Error value from ERM */
> WORD Status; /* Bit per device error status */
> BYTE RunMode : 1; /* 1 if in Run Mode; 0 if not */
> BYTE ERMState;
> WORD MinScan; /* Minimum scan time in ms */
> WORD MaxScan; /* Miximum scan time in ms */
> DWORD TotalScans; /* Total Number of scans */
> DWORD TotalTime; /* Total Time for TotalScans */
> DWORD ReadRetrys; /* Number of PLC Read Retrys */
> DWORD WriteRetrys; /* Number of PLC Write Retrys */
> DWORD DeviceRetrys; /* Number of Device Retrys */
> DWORD DeviceTime; /* Total Time spent on device comm */
> BYTE Base; /* Base number that Hx-ERM module is in */
> BYTE Slot; /* Slot number that Hx-ERM module is in */
> BYTE EthernetAddress[6]; /* Ethernet address of controlling WinPLC
> (0 for PLC) */
> BYTE Unused[113];
> } sERMInfo;
> typedef struct sDevCommand
> {
> BYTE Version; /* Version of sDevCommand 1 = current version
> */
> BYTE Command; /* Command to give to Device (see DEV_CMD_XXX
> values) */
> BYTE Data[254]; /* Command specific data */
> } sDevCommand;
> #define DEV_CMD_REINIT 1 /* Used to tell Device to do a
> reinitialization */
> #define DEV_CMD_RESET_STATS 2 /* Used to tell Device to clear
> error / stat info */
> #define DEV_CMD_RESET_ERROR 3 /* Used to clear LastError value for
> one or more devices */
> /* Data[0]: bits 0-7 correspond to devies num 0-7 */
> /* Data[1]: bits 0-7 correspond to devies num 8-15 */
>
> /* Hx-ERM Errors. */
> #define ERM_CONFIG_ERROR_BITS_IN_TOO_FEW 1 /* Config error: Bits
> In configured not enough */
> #define ERM_CONFIG_ERROR_BITS_OUT_TOO_FEW 2 /* Config error:
> Bits Out configured not enough */
> #define ERM_CONFIG_ERROR_BITS_IN_OVERLAPS_SYS_DATA 3 /* Configured
> Bit Inputs overlap system input bits */
> #define ERM_CONFIG_ERROR_BITS_OUT_OVERLAPS_SYS_DATA 4 /* Configured
> Bit Outputs overlap system output bits */
> #define ERM_MULTIPLE_DEVICES_WITH_SAME_NODE_NUM 5 /* More than one
> device found with same node number */
> #define ERM_MULTIPLE_DEVICES_WITH_SAME_IP_ADDRESS 6 /* More than
> one device foudn with same IP address */
> #define ERM_MODULE_NOT_RESPONDING 7 /* Device is not
> responding to a function request */
> #define ERM_MODULE_NOT_SUPPORTED 8 /* Device not supported;
> may be firmware or cfg error */
> #define ERM_MODULE_TIMEOUT 9 /* Device timed out on a
> function request (after retrys) */
> #define ERM_MODULE_NO_GATEWAY_ADDRESS 13 /* Gateway address
> needed, but not specified */
> #define ERM_NO_SUBNET_MASK 14 /* Subnet mask needed, but
> not specified */
> #define ERM_MODULE_MISMATCHED_MODULE_IDS 15 /* Configured module
> Id's don't match modules in device */
> #define ERM_MODULE_INCORRECT_BITS_IN 16 /* Number of bit inputs
> specified is less than actual */
> #define ERM_MODULE_INCORRECT_BITS_OUT 17 /* Number of bit
> outputs specified is less than actual */
> #define ERM_MODULE_INCORRECT_WORDS_IN 18 /* Number of word
> inputs specified is less than actual */
> #define ERM_MODULE_INCORRECT_WORDS_OUT 19 /* Number of word
> outputs specified is less than actual */
> #define ERM_MODULE_BASE_DEF_ERROR 20 /* Invalid base def for
> this device */
> #define ERM_CONFIG_MISSING 21 /* Hx-ERM hasn't been
> configured */
> #define ERM_MODULE_BASE_DEF_BUFFER_OVERFLOW 22 /* Overflow of
> entire BaseDefBuffer */
> #define ERM_MODULE_BASE_DEF_OVERFLOW 23 /* Overflow of previous
> Device BaseDef */
> #define ERM_MODULE_WRITE_PACKET_BUFFER_OVERFLOW 24 /* Overflow of
> entire WritePacketBuffer */
> #define ERM_MODULE_WRITE_PACKET_OVERFLOW 25 /* Overflow of
> previous WritePacketBuffer */
> #define ERM_CONFIG_IO_BUFFER_OVERFLOW 26 /* Overflow of entire
> IO buffer */
> #define ERM_CONFIG_ERROR_WORDS_IN_TOO_FEW 27 /* Config error:
> Words In configured not enough */
> #define ERM_CONFIG_ERROR_WORDS_OUT_TOO_FEW 28 /* Config error:
> Words Out configured not enough */
> /* ERM Backplane errors */
> #define ERM_BPERROR_OBJ_NOT_FOUND 221 /* Internal
> backplane error */
> #define ERM_BPERROR_UNK_PLC_FAMILY 223 /* PLC Family
> unknown */
> #define ERM_BPERROR_INVALID_STATUS 224 /* Invalid backplane
> status value */
> #define ERM_BPERROR_CCM_CODEERROR 225 /* Code Error returned
> from PLC */
> #define ERM_BPERROR_CCM_ERROR 226 /* General Error returned
> from PLC */
> #define ERM_BPERROR_TIMEOUT 227 /* Timeout on PLC backplane
> request */
> #define ERM_BPERROR_NO_MORE_OBJECTS 228 /* Backplane queue
> full */
> #define ERM_BPERROR_INVALID_REQUEST 231 /* Internal request
> error */
> /* Serial port defines */
> #define SERIAL_1_STOP_BIT 0
> #define SERIAL_2_STOP_BITS 1
> #define SERIAL_7_DATA_BITS 0
> #define SERIAL_8_DATA_BITS 1
> #define SERIAL_NO_PARITY 0
> #define SERIAL_ODD_PARITY 2
> #define SERIAL_EVEN_PARITY 3
> #define SERIAL_SLAVE 0
> #define SERIAL_MASTER 1
> #define SERIAL_PROXY 1
> #define SERIAL_NO_RTS 0
> #define SERIAL_USE_RTS 1
>
> typedef struct
> {
> DWORD BaudRate; /* Baud rate to use i.e. 9600 */
> /* If Baud rate == 0 then serial port is disabled */
>
> #if defined (ANSI_C)
> BYTE ConfigData;
> #else
> BYTE StopBits : 1; /* 0 == 1 Stop bit; 1 == 2 Stop bits */
> BYTE DataBits : 1; /* 0 == 7 Data bits; 1 == 8 Data bits */
> BYTE Parity : 2; /* 0 == 1 == None; 2 == Odd; 3 == Even */
> BYTE Mode : 1; /* 0 == Slave; 1 == Master/Proxy */
> BYTE UseRTS : 1; /* 0 == Don't use RTS line; 1 == Use RTS line */
> BYTE Reserved : 2; /* Reserved locations */
> #endif
> BYTE PreTransmitDelay; /* If UseRTS == 1 delay this many ms (times
> 2) before starting transmit */
> BYTE PostTransmitDelay; /* If UseRTS == 1 delay this many ms
> (times 2) after ending transmit */
> BYTE Unused; /* Unused byte (set to zero) */
> } SerialSetup;
> /* Flags for IPSetup */
> #define IPF_USE_BRAM_SETUP 0x00000001
> #define IPF_USE_ZERO_BCAST 0x00000002
> #define IPF_ENABLE_DHCP 0x00000004
> #define IPF_USE_DNS 0x00000008
> #define IPF_USE_WINS 0x00000010
> typedef struct
> {
> DWORD Flags; /* Flags see IPF_XXX above */
> BYTE Gateway[16]; /* Gateway address */
> BYTE IPAddress[16]; /* IP Address */
> BYTE Subnet[16]; /* Subnet address */
> BYTE DNSAddr[16]; /* Primary DNS (used if IPF_USE_DNS flag is
> set) */
> BYTE WINSAddr[16]; /* Primary WINS (used if IPF_USE_WINS flag is
> set) */
> BYTE Unused[172]; /* Unused (clear to zero) */
> } IPSetup;
>
> typedef struct
> {
> WORD Mode; /* Mode for ErrorLightSetup see ELS_XXXX below */
> WORD InitVal; /* Initial value used for ELS_SET and ELS_CYCLE */
> WORD OnTime; /* OnTime used for ELS_CYCLE */
> WORD OffTime; /* OffTime used for ELS_CYCLE */
> WORD Num; /* Number of times to loop for ELS_CYCLE */
> WORD Val1; /* Unused value */
> WORD Val2; /* Unused value */
> WORD Val3; /* Unused value */
> } ErrorLightSetup;
>
> #define ELS_OFF 0 /* Turns the error light off */
> #define ELS_SET 1 /* Sets the error light to the value of
> InitVal */
> #define ELS_CYCLE 2 /* Cycles error light. Begins with value of
> InitVal */
> /* When light is turned on, it stays on for OnTime */
> /* When light is turned off, it stays off for OffTime */
> /* Cycles lights Num times */
> typedef struct
> {
> BYTE MajorVersion;
> BYTE MinorVersion;
> WORD BuildVersion;
> } VersionDef;
>
> typedef struct
> {
> BYTE SizeofVersionInfo;
> VersionDef BootVersion;
> VersionDef OSVersion;
> BYTE NumOSExtensions;
> VersionDef OSExt[10];
> } VersionInfoDef;
>
> /* Module type defines */
> #define MT_EBC 0 /* Ethernet base controller */
> #define MT_ECOM 1 /* Ethernet communications module */
> #define MT_WPLC 2 /* WinPLC */
> #define MT_DRIVE 3 /* Drive card */
> #define MT_ERMA 4 /* Ethernet remote master */
> #define MT_CTRIO 5 /* Counter I/O card */
> #define MT_AVG_DISP 6 /* AVG Display Adapter card */
> #define MT_PBC 7 /* Profibus controller */
> #define MT_PBCC 8 /* Profibus IO coprocessor */
> #define MT_UNK 0xFF
> /* Module Family defines for MT_EBC, MT_ECOM, MT_WPLC, MT_ERMA */
> #define MF_005 0
> #define MF_205 2
> #define MF_305 3
> #define MF_405 4
> #define MF_TERM 10
> /* Module Family defines for MT_DRIVE */
> #define MF_100_SERIES 1 /* Hitachi L100 and SJ100 drives */
> #define MF_J300 2 /* Hitachi J300 drive */
> #define MF_300_SERIES 3 /* Hitachi SJ300 drive */
> #define MF_GS 4 /* GS Series drives GS-EDRV*/
> /* Module Family defines for MT_AVG_DISP */
> #define MF_EZ_TOUCH 1 /* AVG EZ-Touch Ethernet adapter */
> typedef struct
> {
> BYTE PLCFamily; /* See MF_XXX defines above */
> BYTE Unused1;
> BYTE ModuleType; /* See MT_XXX defines above */
> BYTE StatusCode;
> BYTE EthernetAddress[6]; /* Hardware ethernet address */
> WORD RamSize; /* In K-Byte increments */
> WORD FlashSize; /* In K-Byte increments */
> BYTE DIPSettings; /* Settings of the 8 dip switches. */
> BYTE MediaType; /* 0 == 10-Base T */
> /* 1 == 10-Base F */
> DWORD EPFCount; /* Early power fail count (405 EBC)*/
> #if defined (ANSI_C)
> BYTE Status;
> #else
> BYTE RunRelay : 1; /* 405 EBC Run Relay Status */
> BYTE BattLow : 1; /* 405 EBC Battery Low indicator */
> BYTE UnusedBits : 6; /* Unused status bits */
> #endif
> WORD BattRamSize; /* Size in K-Bytes of battery-backed ram */
> BYTE ExtraDIPS; /* Extra Dip switches on Terminator EBC's */
> BYTE ModelNumber;
> BYTE EtherSpeed; /* 0=10MBit; 1=100MBit */
> BYTE PLDRev[2];
> BYTE Unused[14];
> } DeviceDef;
> typedef struct
> {
> DWORD Timeout; /* Timeout 0 == Don't use link monitor */
> BYTE Mode; /* Mode: */
> /* 0 == Clear outputs */
> /* 1 == Set outputs to given I/O data pattern */
> BYTE Data[251]; /* Pattern: Used with set outputs, same format */
> /* as data for HEIWriteIO call. */
> } LinkMonitor;
> typedef struct
> {
> BYTE Algorithm; /* Algorithm to use for encryption */
> /* 0 == No encryption */
> /* 1 == Private key encryption */
> /* */
> BYTE Unused[3]; /* Reserved for later */
> BYTE Key[60]; /* Encryption key (null terminated) */
> } Encryption;
>
> typedef struct
> {
> WORD Type; /* Type of memory */
> DWORD Size; /* Size of memory */
> DWORD UnitSize; /* 0 = DWORD, 1 = BYTE, 2 = WORD, 4 = DWORD */
> DWORD Unused[3]; /* Unused */
> } MemoryTypeDef;
>
> typedef struct
> {
> WORD SizeofSettings ; /* sizeof(HEISettings) */
>
> /* Action items. */
> DWORD Flags; /* Flags used to control things. */
> /* Bit: Function: */
> /* 0-31 Unused */
>
> /* RXWX Config items. */
> WORD RXWXACKTimeout ; /* Timeout for receiving ACK / NAK */
> WORD RXWXResponseTimeout ; /* Timeout for receiving response. */
> WORD RXWXMaxRetrys ; /* Number of times to retry a transaction.
> */
>
> /* RXWX Stat Items. */
> WORD RXWXMaxACKTime ; /* STAT: Max number of ms we have waited
> for an ack. */
> WORD RXWXMaxRSPTime ; /* STAT: Max number of ms we have waited
> for a response. */
> DWORD RXWXACKRetrys ; /* STAT: Number of retrys for an ack.
> */
> DWORD RXWXRSPRetrys ; /* STAT: Number of retrys for a response.
> */
> DWORD RXWXCompleted ; /* STAT: Number of successfully completed
> transactions */
> DWORD RXWXTimeouts ; /* STAT: Number of timeouts on
> transactions (after retrys) */
> DWORD RXWXOverruns ; /* STAT: Number of times the PLC requested
> a transaction while */
> /* one was being processed. */
> DWORD RXWXErrors ; /* STAT: Number of times an invalid code
> was found or a transaction */
> /* was NAKed. */
>
> /* Other stuff */
> BYTE Version; /* Version of this structure. Currently 0 */
>
> /* K-Sequence Retrys */
> WORD KSeqMaxRetrys; /* Max number of times to retry a K-
> Sequence request */
> WORD KSeqRetrys; /* STAT: Number of K-Sequence retrys.
> */
> WORD KSeqTimeouts; /* STAT: Number of K-Sequence timeouts. */
>
> BYTE Unused[81]; /* Reserved for future use. (Configure
> protocol, etc. */
> } HEISettings;
>
> typedef struct
> {
> BYTE RunRelayMode; /* Relay Mode */
> /* See Relay modes below. */
> DWORD SerialTimeout; /* Used for RRM_DRIVE_COMM_BAD */
> DWORD EthernetTimeout; /* Used for RRM_DRIVE_COMM_BAD */
> BYTE Unused[55];
> } ModuleSetup;
>
> typedef struct
> {
> /*
> ** GS Series drive setup timeouts.
> ** In order for a value to be used, set the most significant bit.
> */
> WORD ReceiveCharTimeout[4];
> WORD CommandResponseTimeout[4];
> WORD WriteCacheClearTime; /* 250 ms default */
> WORD TimeoutsBeforeAutoBaud; /* 50 ms default */
> WORD RTSPreTransmitDelay; /* 4 ms default */
> WORD RTSPostTransmitDelay; /* 4 ms default */
> WORD AutoBaudDelay; /* 10 ms default */
> WORD ProcessSlaveIdle; /* 10 ms default */
> WORD RetryDelay; /* 20 ms default */
> WORD Unused[49];
> } DriveSetup;
>
> /* Relay Modes */
> #define RRM_LINK_GOOD 0 /* Run relay on when link is good (default)
> */
> #define RRM_LINK_NOT_GOOD 1 /* Run relay on when link is not good */
> #define RRM_POWERUP_ON 2 /* EBC turns run relay mode on on
> powerup */
> #define RRM_MANUAL_ON 3 /* Run relay mode is controlled by control
> software */
> #define RRM_DRIVE_COMM_BAD 4 /* Relay on if serial or ethernet comm
> lost (for Drive controller card) */
>
> #define ACCESS_READ 0
> #define ACCESS_WRITE 1
> typedef struct sMemRefDetail
> {
> BYTE Direction; /* ACCESS_READ == Read, ACCESS_WRITE == Write */
> WORD Type; /* Memory type */
> DWORD Offset; /* Memory Offset */
> WORD NumBytes; /* Number of bytes */
> } MemRefDetail;
> typedef struct
> {
> MemRefDetail Detail;
> BYTE *pBuffer; /* Data buffer */
> } MemRef;
> /* RescanFlags */
> #define RESCAN_LEAVE_IMAGE_RAM 0 /* Don't clear the image RAM */
> #define RESCAN_CLEAR_IMAGE_RAM 1 /* Clear the image RAM */
> /* Protocol Defines */
> #define HEIP_HOST 1
> #define HEIP_IPX 2
> #define HEIP_IP 3
> #define HEIP_SERIAL 4
>
> #if !defined(FIRMWARE)
> #if defined(HEIDEFS)
> typedef int BOOL;
> typedef unsigned char BYTE;
> typedef unsigned short WORD;
> typedef unsigned long DWORD;
> #define FALSE 0
> #define TRUE 1
> #endif /* #if defined(HEIDEFS) */
> #define HEIAPIVERSION 3
> #define HEIAPIVERSIONSTRING "3"
> #define HEIT_HOST 1
> #define HEIT_IPX 2
> #define HEIT_WINSOCK 4
> #define HEIT_OTHER_TRANSPORT 8
> #define HEIT_UNIX 16
> #define HEIT_SERIAL 32
> /* Encryption Algorithms */
> #define HEIEN_NONE 0
> #define HEIEN_A1 1
> #define PACKET_HEADER_SIZE 9
> #if defined(HEIDOS)
> #define __declspec(dllexport)
> #endif /* #if defined(HEIDOS) */
> #if defined(HEI16)
> #define __declspec(dllexport)
> #endif /* #if defined(HEI16) */
> #if defined(HEIUNIX)
> #define __declspec(dllexport)
> #endif /* #if defined(HEIT_UNIX) */
>
> /* Default values for HEIOpenDevice */
> #define DefDevTimeout 100
> #define DefDevRetrys 3
> #define DefDevUseAddressedBroadcast FALSE
>
> typedef struct
> {
> union
> {
> /* Use this for HEIP_HOST protocol addressing. */
> struct
> {
> short Family; /* AF_UNSPEC == 0 */
> char Nodenum[6]; /* Ethernet network address */
> unsigned short LANNum; /* Lana number */
> } AddressHost;
> /* Use this for HEIP_IPX protocol addressing. */
> struct
> {
> short Family; /* AF_IPX == 6 */
> char Netnum[4]; /* Network number */
> char Nodenum[6]; /* Ethernet network address */
> unsigned short Socket; /* Socket number == 0x7070 */
> } AddressIPX;
> /* Use this for HEIP_IP protocol addressing. */
> struct
> {
> short Family; /* AF_INET == 2 */
> unsigned short Port; /* Port number == 0x7070 */
> union /* Internet address */
> {
> struct { unsigned char b1,b2,b3,b4; } bAddr;/* Byte addressing */
> struct { unsigned short w1,w2; } wAddr; /* Word addressing */
> unsigned long lAddr; /* DWord addressing */
> } AddressingType;
> char Zero[8]; /* Initialize to zeros */
> } AddressIP;
> /* This is the generic address buffer. */
> BYTE Raw[20];
> #ifdef ANSI_C /* ANSI C cannot have anonymous structures */
> } Address;
> #else
> };
> #endif
> } ENetAddress;
>
> #if defined(__cplusplus)
> extern "C"
> {
> #endif /* #if defined(__cplusplus) */
> /* INITIALIZATION / SHUTDOWN */
> __declspec(dllexport) int HEIOpen(WORD HEIAPIVersion);
> __declspec(dllexport) int HEIClose();
>
> /* Protocol Stuff */
> typedef struct
> {
> WORD Transport; /* HEIT_HOST */
> /* HEIT_IPX */
> /* HEIT_NETBIOS */
> /* HEIT_WINSOCK */
> WORD Protocol; /* HEIP_HOST*/
> /* HEIP_IPX */
> /* HEIP_IP */
> /* HEIP_NETBIOS */
> /* Encryption stuff. */
> Encryption Encrypt; /* Set this up before calling
> HEIOpenTransport */
> /* .Algorithm == HEIEN_NONE OR HEIEN_A1 */
> /* .Key == Encryption key */
>
> /* DWORD NetworkAddress; */
> ENetAddress *pSourceAddress; /* Used for multiple ethernet cards.
> This address is the address of the card to use. */
> /*int (*pSendPacket)(HEIDevice *pDevice, BYTE *pPacket, WORD
> PacketSize);*/
> /*int (*pReceivePacket)(HEIDevice *pDevice, BYTE *pResponse, int
> *pResponseSize);*/
> #if HEIAPIVERSION==3
> BYTE Reserved[48]; /* Reserved bytes, set to zero */
> #endif
> } HEITransport;
>
> __declspec(dllexport) int HEIOpenTransport(HEITransport
> *pTransport, WORD Version, ENetAddress *pSourceAddress);
> /* __declspec(dllexport) int HEIOpenTransport(HEITransport
> *pTransport, WORD Version, DWORD NetworkAddress );*/
> /* __declspec(dllexport) int HEIOpenTransport(HEITransport
> *pTransport, WORD Version, DWORD NetworkAddress = 0); */
> __declspec(dllexport) int HEICloseTransport(HEITransport
> *pTransport);
>
>
> /* DEVICE Stuff */
> typedef struct
> {
> union
> {
> /* Use this for HEIP_HOST protocol addressing. */
> struct
> {
> short Family; /* AF_UNSPEC == 0 */
> char Nodenum[6]; /* Ethernet network address */
> unsigned short LANNum; /* Lana number */
> } AddressHost;
> /* Use this for HEIP_IPX protocol addressing. */
> struct
> {
> short Family; /* AF_IPX == 6 */
> char Netnum[4]; /* Network number */
> char Nodenum[6]; /* Ethernet network address */
> unsigned short Socket; /* Socket number == 0x7070 */
> } AddressIPX;
> /* Use this for HEIP_IP protocol addressing. */
> struct
> {
> short Family; /* AF_INET == 2 */
> unsigned short Port; /* Port number == 0x7070 */
> union /* Internet address */
> {
> struct { unsigned char b1,b2,b3,b4; } bAddr;/* Byte addressing */
> struct { unsigned short w1,w2; } wAddr; /* Word addressing */
> unsigned long lAddr; /* DWord addressing */
> } AddressingType;
> char Zero[8]; /* Initialize to zeros */
> } AddressIP;
> struct
> {
> BYTE CommPort;
> BYTE ByteSize;
> BYTE Parity;
> BYTE StopBits;
> DWORD Baud;
> void *hLocal;
> } AddressSerial;
> /* This is the generic address buffer. */
> BYTE Raw[20];
> } Address;
> WORD wParam; /* Application can use this. */
> DWORD dwParam; /* Application can use this. */
> WORD Timeout; /* Timeout value in ms (can be changed without
> closing the device). */
> WORD Retrys; /* Number of times to retry (can be changed
> without closing the device). */
> BYTE ENetAddress[6]; /* The ethernet address is placed here in
> the HEIQueryDevices call. */
> WORD RetryCount; /* Number of retrys which have occured. */
> WORD BadCRCCount; /* Number of packets received with bad CRC */
> WORD LatePacketCount; /* Number of packets received, but after a
> timeout */
> BOOL ParallelPackets; /* Setting this to TRUE (after
> HEIOpenDevice) will enable an application */
> /* to send multiple HEIReadIO, HEIWriteIO, HEICCMRequest
> or HEIKSEQRequest requests */
> /* (to different) modules before waiting for any
> responses. */
> /* The application will then need to implement its own
> retry / timeout mechanism */
> /* while waiting for the responses. */
> /* The application uses HEIGetResponse to see if a response
> for a module has arrived. */
> /* NOTE: The application should not send multiple requests
> to a single module */
> /* without waiting for the response in between. */
> /* Internal - Do not touch!! */
> BOOL UseAddressedBroadcast; /* Need to close the device and reopen
> it to change this! */
> BOOL UseBroadcast;
> DWORD _dwParam;
> WORD DataOffset;
> HEITransport *_pTransport; /* Need to close the device and reopen
> it to change this! */
> int SizeOfData;
> BYTE *pData;
> void *pBuffer;
> unsigned short LastAppVal;
> #if HEIAPIVERSION==3
> BYTE UseProxy;
> BYTE ProxyBase;
> BYTE ProxySlot;
> BYTE ProxyDevNum;
> BYTE Reserved[44]; /* Reserved bytes, set to zero */
> #endif
> } HEIDevice;
>
> __declspec(dllexport) int HEIQueryDevices(HEITransport *pTransport,
> HEIDevice *pDevices, WORD *pNumDevices, WORD HEIAPIVersion);
>
> __declspec(dllexport) int HEIOpenDevice(HEITransport *pTransport,
> HEIDevice *pDevice, WORD HEIAPIVersion, WORD Timeout, WORD Retrys,
> BOOL UseAddressedBroadcast);
> /* __declspec(dllexport) int HEIOpenDevice(HEITransport
> *pTransport, HEIDevice *pDevice, WORD HEIAPIVersion, WORD
> Timeout=DefDevTimeout, WORD Retrys=DefDevRetrys, BOOL
> UseAddressedBroadcast=DefDevUseAddressedBroadcast); */
> __declspec(dllexport) int HEICloseDevice(HEIDevice *pDevice);
>
> __declspec(dllexport) int HEIQueryDeviceData(HEITransport
> *pTransport, HEIDevice *pDevices, WORD *pNumDevices, WORD
> HEIAPIVersion, WORD DataType, BYTE *pData, WORD SizeofData);
>
> /* SUPPORT INFORMATION */
> __declspec(dllexport) int HEIReadSupportInfo(HEIDevice *pDevice,
> BYTE *pSupportInfo, WORD SizeOfSupportInfo);
>
>
> /* VERSION INFORMATION */
> __declspec(dllexport) int HEIReadVersionInfo(HEIDevice *pDevice,
> BYTE *pVerInfo, WORD SizeVerInfo);
>
>
> /* BASE DEFINITION */
> __declspec(dllexport) int HEIReadBaseDef(HEIDevice *pDevice, BYTE
> *pBaseDefInfo, WORD *pSizeOfBaseDefInfo);
> __declspec(dllexport) int HEIWriteBaseDef(HEIDevice *pDevice, BYTE
> *pInputBaseDef, WORD SizeOfInputBaseDef, BYTE *pOutputBaseDef, WORD
> *pSizeOfOutputBaseDef);
> __declspec(dllexport) int HEIInitBaseDef(HEIDevice *pDevice, BYTE
> *pBaseDefInfo, WORD *pSizeOfBaseDefInfo);
> __declspec(dllexport) int HEIRescanBase(HEIDevice *pDevice, DWORD
> RescanFlags, BYTE *pBaseDefInfo, WORD *pSizeOfBaseDefInfo);
>
>
> /* DEVICE DEFINITION */
> __declspec(dllexport) int HEIReadDeviceDef(HEIDevice *pDevice, BYTE
> *pModuleDefInfo, WORD SizeOfModuleDefInfo);
> /* IO ACCESS */
> __declspec(dllexport) int HEIReadIO(HEIDevice *pDevice, BYTE
> *pData, WORD *DataSize);
> __declspec(dllexport) int HEIWriteIO(HEIDevice *pDevice, BYTE
> *pData, WORD SizeofData, BYTE *pReturnData, WORD *pSizeofReturnData);
> __declspec(dllexport) int HEIWriteIONoRead(HEIDevice *pDevice, BYTE
> *pData, WORD SizeofData);
> __declspec(dllexport) int HEIReadIOEx(HEIDevice *apDevice[], BYTE
> *apData[], WORD aSizeofData[], int aErrorCode[], int DeviceCount);
> __declspec(dllexport) int HEIWriteIOEx(HEIDevice *apDevice[], BYTE
> *apData[], WORD aSizeofData[], BYTE *apReturnData[], WORD
> aSizeofReturnData[], int aErrorCode[], int DeviceCount);
> /* CONFIG */
> __declspec(dllexport) int HEIReadConfigData(HEIDevice *pDevice,
> BYTE *pData, WORD *DataSize);
> __declspec(dllexport) int HEIWriteConfigData(HEIDevice *pDevice,
> BYTE *pData, WORD SizeofData, BYTE *pReturnData, WORD
> *pSizeofReturnData);
> // NOTE: You can also Use HEIWriteIO to write config data using
> type DF_CONFIG
>
> /* SETUP */
> __declspec(dllexport) int HEIReadSetupData(HEIDevice *pDevice, WORD
> SetupType, BYTE *pData, WORD *pSizeofData);
> __declspec(dllexport) int HEIWriteSetupData(HEIDevice *pDevice,
> WORD SetupType, BYTE *pData, WORD SizeofData);
> __declspec(dllexport) int HEIDeleteSetupData(HEIDevice *pDevice,
> WORD SetupType);
> __declspec(dllexport) int HEIEnumSetupData(HEIDevice *pDevice, WORD
> *pData, WORD *pSizeofDataInWords);
> /* WATCHDOG */
> __declspec(dllexport) int HEIPetDevice(HEIDevice *pDevice);
> /* STATISTICS */
> __declspec(dllexport) int HEIReadEthernetStats(HEIDevice *pDevice,
> BYTE *pData, WORD *DataSize, BOOL Clear);
> /* __declspec(dllexport) int HEIReadEthernetStats(HEIDevice
> *pDevice, BYTE *pData, WORD *DataSize, BOOL Clear=FALSE); */
> /* MODULES STATUS */
> __declspec(dllexport) int HEIReadModuleStatus(HEIDevice *pDevice,
> BYTE *pData, WORD *DataSize, BOOL Reset);
> /* __declspec(dllexport) int HEIReadModuleStatus(HEIDevice
> *pDevice, BYTE *pData, WORD *DataSize, BOOL Reset=FALSE); */
> /* Multiple Packet Stuff. */
> __declspec(dllexport) int HEIGetResponse(HEIDevice *pDevice, BYTE
> *pResponse, int *pResponseSize, BOOL CheckAppVal);
> /* __declspec(dllexport) int HEIGetResponse(HEIDevice *pDevice,
> BYTE *pResponse, int *pResponseSize, BOOL CheckAppVal=TRUE); */
> /* ECOM STUFF */
> __declspec(dllexport) int HEICCMRequest(HEIDevice *pDevice, BOOL
> bWrite, BYTE DataType, WORD Address, WORD DataLen, BYTE *pData);
> __declspec(dllexport) int HEIKSEQRequest(HEIDevice *pDevice, WORD
> DataLenIn, BYTE *pData, WORD *pDataLen);
> /* SERIAL PORT STUFF */
> __declspec(dllexport) int HEIWriteComm(HEIDevice *pDevice, WORD
> Num2Write, BYTE *pData);
> __declspec(dllexport) int HEIReadComm(HEIDevice *pDevice, WORD
> *pNum2Read, BYTE *pData);
> __declspec(dllexport) int HEIGetRXAvailable(HEIDevice *pDevice,
> WORD *pAvailable);
> __declspec(dllexport) int HEIFlushRXQueue(HEIDevice *pDevice);
> __declspec(dllexport) int HEIGetTXLeft(HEIDevice *pDevice, WORD
> *pLeft);
> __declspec(dllexport) int HEISetupSerialPort(HEIDevice *pDevice,
> SerialSetup *pSetup, BOOL WriteToFlash);
> __declspec(dllexport) int HEIReadSerialPortSetup(HEIDevice
> *pDevice, SerialSetup *pSetup);
>
> /* SERIAL PORT STUFF (EX) */
> __declspec(dllexport) int HEIWriteCommEx(HEIDevice *pDevice,BYTE
> Port ,WORD Num2Write, BYTE *pData);
> __declspec(dllexport) int HEIReadCommEx(HEIDevice *pDevice, BYTE
> Port, WORD *pNum2Read, BYTE *pData);
> __declspec(dllexport) int HEIGetRXAvailableEx(HEIDevice *pDevice,
> BYTE Port, WORD *pAvailable);
> __declspec(dllexport) int HEIFlushRXQueueEx(HEIDevice *pDevice,
> BYTE Port);
> __declspec(dllexport) int HEIFlushTXQueueEx(HEIDevice *pDevice,
> BYTE Port);
> __declspec(dllexport) int HEIGetTXLeftEx(HEIDevice *pDevice, BYTE
> Port, WORD *pLeft);
> __declspec(dllexport) int HEISetupSerialPortEx(HEIDevice *pDevice,
> BYTE Port, SerialSetup *pSetup, BOOL WriteToFlash);
> __declspec(dllexport) int HEIReadSerialPortSetupEx(HEIDevice
> *pDevice, BYTE Port, SerialSetup *pSetup);
> __declspec(dllexport) int HEIAccessComm(HEIDevice *pDevice, WORD
> SendDataSize, BYTE *pSendData, WORD *pReturnDataSize, BYTE
> *pReturnData);
>
> /* MEMORY STUFF (see below for types) */
> __declspec(dllexport) int HEIReadMemory(HEIDevice *pDevice, WORD
> Type, DWORD Offset, WORD NumBytes, BYTE *pBuffer);
> __declspec(dllexport) int HEIWriteMemory(HEIDevice *pDevice, WORD
> Type, DWORD Offset, WORD NumBytes, BYTE *pBuffer);
> __declspec(dllexport) int HEIENumMemory(HEIDevice *pDevice, WORD
> *pNumWords, MemoryTypeDef *pBuffer);
> __declspec(dllexport) int HEIAccessMemory(HEIDevice *pDevice,
> MemRef MemRefs[], WORD NumRefs);
>
> /* SHARED RAM STUFF (for Intelligent modules) */
> __declspec(dllexport) int HEIReadSharedRAM(HEIDevice *pDevice, WORD
> Base, WORD Slot, WORD Address, WORD Bytes2Read, BYTE *pBuffer);
> __declspec(dllexport) int HEIWriteSharedRAM(HEIDevice *pDevice,
> WORD Base, WORD Slot, WORD Address, WORD Bytes2Write, BYTE *pBuffer);
>
> /* WinPLC specific functions */
> #ifndef WINPLC
> __declspec(dllexport) int WPLCSetOSLoad(HEIDevice *pDevice, int Val);
> __declspec(dllexport) int WPLCReboot(HEIDevice *pDevice);
> __declspec(dllexport) int WPLCRunProgram(HEIDevice *pDevice, BYTE
> *pProgram);
> __declspec(dllexport) int HEIWriteERMData(HEIDevice *pDevice, WORD
> Base, WORD Slot, BYTE DataType, BYTE *pData, WORD NumBytes, WORD
> Offset);
> __declspec(dllexport) int HEIReadERMData(HEIDevice *pDevice, WORD
> Base, WORD Slot, BYTE DataType, BYTE *pData, WORD NumBytes, WORD
> Offset);
> __declspec(dllexport) int HEIDoERMCommand(HEIDevice *pDevice, WORD
> Base, WORD Slot, WORD Command);
> __declspec(dllexport) int HEIDoERMCommandEx(HEIDevice *pDevice,
> WORD Base, WORD Slot, WORD Command, BYTE *pExtra, WORD ExtraLen);
> __declspec(dllexport) int WPLCWriteERMData(HEIDevice *pDevice, WORD
> Base, WORD Slot, BYTE DataType, BYTE *pData, WORD NumBytes, WORD
> Offset);
> __declspec(dllexport) int WPLCReadERMData(HEIDevice *pDevice, WORD
> Base, WORD Slot, BYTE DataType, BYTE *pData, WORD NumBytes, WORD
> Offset);
> __declspec(dllexport) int WPLCDoERMCommand(HEIDevice *pDevice, WORD
> Base, WORD Slot, WORD Command);
> __declspec(dllexport) int WPLCDoERMCommandEx(HEIDevice *pDevice,
> WORD Base, WORD Slot, WORD Command, BYTE *pExtra, WORD ExtraLen);
> #endif
> /*
> ** Query timeout function
> */
> /* Sets new query timeout value and returns the old query timeout
> value */
> __declspec(dllexport) DWORD HEISetQueryTimeout(DWORD NewTimeout);
> /* Gets current query timeout value */
> __declspec(dllexport) DWORD HEIGetQueryTimeout();
> /*
> ** Async Handler for handling extra packets.
> */
> __declspec(dllexport) int HEISetAsyncHandler(void (*pFun)(HEIDevice
> *pDevice, BYTE *pResponse, int ResponseLen));
> __declspec(dllexport) int HEIGetAsyncHandler(void (**pFun)
> (HEIDevice *pDevice, BYTE *pResponse, int ResponseLen));
> /*
> ** EZ-Ethernet defs
> */
> typedef signed char SBIT8;
> #define MAX_PGM_DATA_LEN 255 // Max packet sent by AVG.
> #define MAX_ERR_MSG_SZ 40 // Forty bytes of error message space.
> #define MAC_LEN 6 // Six bytes for MAC address
> #define SPARE_BYTES 4 // Four spare bytes for future use.
> #ifndef NO_ERROR
> #define NO_ERROR 0L
> #endif
> typedef struct
> {
> unsigned char Name[20];
> unsigned char Node_ID[2];
> HEIDevice *pDevice;
> } NODELIST;
>
> /*
> ** Layout of the control buffer.
> */
> typedef struct CntlBuffer
> {
> BYTE TaskCode; /* Taskcode byte (future use)*/
> BYTE PanelLock; /* 1 - Panel has lock, 0 - not
> locked*/
> BYTE AdapterLock; /* 1 - Adapter has lock, 0 - not
> locked*/
> BYTE InStatus; /* Incoming status*/
> BYTE OutStatus; /* Outgoing status*/
> SBIT8 Seq; /* Sequence number assigned by
> panel*/
> BYTE ErrorOffset; /* Offset into error array*/
> BYTE ItemCnt[2]; /* Two bytes since read tags can
> be > 256.*/
> BYTE ErrMsg[MAX_ERR_MSG_SZ]; /* 40 character string.*/
> BYTE EcomOffset; /* Used for panel to panel
> communications.*/
> BYTE Mac[MAC_LEN]; /* Stores mac address of
> responding device.*/
> BYTE Spare[SPARE_BYTES]; /* Future use*/
> } CNTL_BUF;
> /*
> ** Layout of the program shared ram frame
> */
> typedef struct PgmBuffer
> {
> CNTL_BUF CntlBuf;
> BYTE PgmData[MAX_PGM_DATA_LEN];
>
> } PGM_BUF;
>
> /*
> ** EZ-Ethernet functions
> */
> __declspec(dllexport) int HEIWriteEZethernetPgmSpace(HEIDevice
> *pDevice, BYTE *pData, WORD SizeofData);
> __declspec(dllexport) BOOL EZSendPacket(HEIDevice *pDevice, PGM_BUF
> *pBuffer, BYTE *Error_message, unsigned short int Len);
> __declspec(dllexport) NODELIST *EZGetNodeList(unsigned short int
> *TotalEZ);
> __declspec(dllexport) int SetCRCMode(int Mode);
> __declspec(dllexport) int SendPacketTwoResponses(HEIDevice
> *pDevice, BYTE *pPacket, WORD PacketSize, BYTE *pResponse, int
> *pResponseSize,
> BOOL WaitForResponse, BOOL ReturnWarnings, WORD
> Bytes2Verify, BYTE *pVerifyData,
> WORD ExtraTime, BOOL ProcessTimeout, BOOL CheckAppVal);
> #if defined(__cplusplus)
> }
> #endif /* #if defined(__cplusplus) */
> #endif /* #if !defined(FIRMWARE) */
> /* Errors */
> #define HEIE_NULL 0 /* No Error */
> #define HEIE_FIRST_ERROR 0x8000 /* Number for First Error */
> #define HEIE_LAST_ERROR 0xFFFF /* Number for Last Error */
> #define HEIE_NOT_IMPLEMENTED 0x8000 /* Function not implemented */
> #define HEIE_VER_MISMATCH 0x8001 /* Version passed to function
> not correct for library */
> #define HEIE_UNSUPPORTED_TRANSPORT 0x8002 /* Supplied transport
> not supported */
> #define HEIE_INVALID_DEVICE 0x8003 /* Supplied device is not
> valid */
> #define HEIE_BUFFER_TOO_SMALL 0x8004 /* Supplied buffer is too
> small */
> #define HEIE_ZERO_BYTES_RECEIVED 0x8005 /* Zero bytes were
> returned in the packet */
> #define HEIE_TIMEOUT 0x8006 /* Timeout error */
> #define HEIE_UNSUPPORTED_PROTOCOL 0x8007 /* Supplied protocol not
> supported */
> #define HEIE_IP_ADDR_NOT_INITIALIZED 0x8008 /* The devices IP
> address has not be set. NOTE: Need to use */
> /* addressed broadcast to talk to the module (with IP)
> to setup */
> /* the IP address. */
> #define HEIE_NULL_TRANSPORT 0x8009 /* No transport specified. */
> #define HEIE_IPX_NOT_INSTALLED 0x800A /* IPX Transport not
> installed. */
> #define HEIE_IPX_OPEN_SOCKET 0x800B /* Error opening IPX Socket.
> */
> #define HEIE_NO_PACKET_DRIVER 0x800C /* No packet driver found. */
> #define HEIE_CRC_MISMATCH 0x800D /* CRC did not match. */
> #define HEIE_ALLOCATION_ERROR 0x800E /* Memory allocation error
> failed. */
> #define HEIE_NO_IPX_CACHE 0x800F /* No cache has been allocated
> for IPX */
> #define HEIE_INVALID_REQUEST 0x8010 /* Invalid request */
> #define HEIE_NO_RESPONSE 0x8011 /* No response was available./
> requested */
> #define HEIE_INVALID_RESPONSE 0x8012 /* Invalid format response
> was received. */
> #define HEIE_DATA_TOO_LARGE 0x8013 /* Given data is too large */
> #define HEIE_LOAD_PROC_ERROR 0x8014 /* Error loading procedures */
> #define HEIE_NOT_LOADED 0x8015 /* Attempted command before
> successfull OpenTransport */
> #define HEIE_ALIGNMENT_ERROR 0x8016 /* Data not aligned on proper
> boundary */
> #define HEIE_FILE_NOT_OPEN 0x8017 /* File not open */
> #define HEIE_LOAD_ERROR 0x8100 /* Mask for WinSock load Error
> see below (from HEIOpenTransport) */
> #define HEIE_LAST_LOAD_ERROR 0x811F /* Last in the range of
> WinSock load Errors */
> #define HEIE_IO_ERROR 0x9000 /* Mask for IO Error condition
> (from HEIReadModuleStatus, HEIReadIO, or HEIWriteIO) */
> #define HEIE_IO_WARNING 0xA000 /* Mask for IO Warning condition
> (from HEIReadModuleStatus, HEIReadIO, or HEIWriteIO) */
> #define HEIE_IO_INFO 0xC000 /* Mask for IO Info condition
> (from HEIReadModuleStatus, HEIReadIO, or HEIWriteIO) */
> #define HEIE_ICMP_PKT_FOUND 65
> #define HEIE_ARP_PKT_FOUND 66
> #define HEIE_TYPE_NOT_HANDLED 67
> #define HEIE_LINK_SENSE_TRIGGERED 68
> #define HEIE_UNK_IP_PACKET 100
> #define HEIE_UNK_ETHERTYPE 101
> #define HEIE_UNK_PACKET_TYPE 102
> #define HEIE_UNK_802X_PACKET_TYPE 103
> #define HEIE_UNK_LLC_TYPE 104
> #define HEIE_CRC_DOES_NOT_MATCH 105
> #define HEIE_CRC_NO_DATA 106
> #define HEIE_ENET_ADDR_REPROGRAMMED 107
> #define HEIE_NULL_DATA_POINTER 108
> #define HEIE_SIZE_ERROR 109
> #define HEIE_NOT_FOUND 110
> #define HEIE_INVALID_TYPE 111
> #define HEIE_RAM_ALREADY_LOCKED 112
> #define HEIE_INVALID_REQUEST_INT 113
> #define HEIE_TIMEOUT_ERROR 114
> #define HEIE_FLASH_PROGRAM_ERROR 115
> #define HEIE_INVALID_OS 116
> #define HEIE_INVALID_LOCATION 117
> #define HEIE_INVALID_SLOT_NUMBER 118
> #define HEIE_INVALID_DATA 119
> #define HEIE_MODULE_BUSY 120
> #define HEIE_CHANNEL_FAILURE 121
> #define HEIE_UNUSED_CHANNELS_EXIST 122
> #define HEIE_INVALID_UDP_PORT 123
> #define HEIE_SHUTDOWN_OS 124
> #define HEIE_NOT_MY_IP_ADDRESS 125
> #define HEIE_PROTECTION_ERROR 126
> #define HEIE_UNK_TYPE_ERROR 127
> #define HEIE_BACKPLANE_INIT_ERROR 128
> #define HEIE_UNK_RESPONSE 129
> #define HEIE_UNK_RXWX_FORMAT 130
> #define HEIE_UNK_ACK 131
> #define HEIE_UNK_NAK 132
> #define HEIE_RANGE_ERROR 133
> #define HEIE_LENGTH_WARNING 134
> #define HEIE_INVALID_BASE_NUMBER 135
> #define HEIE_INVALID_MODULE_TYPE 136
> #define HEIE_INVALID_OFFSET 137
> #define HEIE_INVALID_BOOT_VER_FOR_OS 138
> #define HEIE_BROKEN_TRANSMITTER 139
> #define HEIE_INVALID_ADDRESS 140
> #define HEIE_TIMING 141
> #define HEIE_CHANNEL_FAILURE_MULTI 142
> #define HEIE_SERIAL_SETUP_ERROR 143
> #define HEIE_NOT_INITIALIZED 144
> #define HEIE_INVALID_MODE 145
> #define HEIE_COMM_FAILURE 146
> #define HEIE_OPERATION_ABORTED 147
> #define HEIE_INVALID_RX_CHAR 148
> #define HEIE_REQUEST_NAKED 149
> #define HEIE_INVALID_OPERATION 150
> #define HEIE_VAL_ALREADY_USED 151
> /* define HEIE_MODULE_ERROR 152 */
> #define HEIE_MODULE_NOT_RESPONDING 153
> #define HEIE_BASE_CHANGED 154 /* I/O Base has changed */
> #define HEIE_MODULE_FAILURE 155
> #define HEIE_PARITY_ERROR 156
> #define HEIE_FRAMING_ERROR 157
> #define HEIE_OVER_RUN_ERROR 158
> #define HEIE_BUFFER_OVERFLOW 159
> #define HEIE_ABORT 160
> #define HEIE_BUSY 161
> #define HEIE_DRIVE_TRIP 162 /* Drive has tripped */
> #define HEIE_COMMAND_PENDING 163
>
> #define HEIE_CHANNELS_UNUSED_0 200
> #define HEIE_CHANNELS_UNUSED_1 201
> #define HEIE_CHANNELS_UNUSED_2 202
> #define HEIE_CHANNELS_UNUSED_3 203
> #define HEIE_CHANNELS_UNUSED_4 204
> #define HEIE_CHANNELS_UNUSED_5 205
> #define HEIE_CHANNELS_UNUSED_6 206
> #define HEIE_CHANNELS_UNUSED_7 207
> #define HEIE_CHANNELS_UNUSED_8 208
> #define HEIE_CHANNELS_UNUSED_9 209
> #define HEIE_CHANNELS_UNUSED_10 210
> #define HEIE_CHANNELS_UNUSED_11 211
> #define HEIE_CHANNELS_UNUSED_12 212
> #define HEIE_CHANNELS_UNUSED_13 213
> #define HEIE_CHANNELS_UNUSED_14 214
> #define HEIE_CHANNELS_UNUSED_15 215
> #define HEIE_CHANNELS_UNUSED_16 216
>
> /* Winsock Load Errors
> If OpenTransport for WinSock fails, it will return one of the
> following errors:
> 0x8014 Error getting addresses from WinSock.DLL
> 0x8100 System was out of memory, executable file was corrupt, or
> relocations were invalid.
> 0x8101 Unused
> 0x8102 File was not found.
> 0x8103 Path was not found.
> 0x8104 Unused
> 0x8105 Attempt was made to dynamically link to a task, or there was
> a sharing or network-protection error.
> 0x8106 Library required separate data segments for each task.
> 0x8107 Unused
> 0x8108 There was insufficient memory to start the application.
> 0x8109 Unused
> 0x810A Windows version was incorrect.
> 0x810B Executable file was invalid. Either it was not a Windows
> application or there was an error in the .EXE image.
> 0x810C Application was designed for a different operating system.
> 0x810D Application was designed for MS-DOS 4.0.
> 0x810E Type of executable file was unknown.
> 0x810F Attempt was made to load a real-mode application (developed
> for an earlier version of Windows).
> 0x8110 Attempt was made to load a second instance of an executable
> file containing multiple data segments that were not marked read-only.
> 0x8111 Unused
> 0x8112 Unused
> 0x8113 Attempt was made to load a compressed executable file. The
> file must be decompressed before it can be loaded.
> 0x8114 Dynamic-link library (DLL) file was invalid. One of the DLLs
> required to run this application was corrupt.
> 0x8115 Application requires Microsoft Windows 32-bit extensions.
> 0x8116-0x811F Unused
> */
>
> /* Warnings */
> #define HEIW_FIRST_WARNING 0x2000 /* Number for First Error */
> #define HEIW_LAST_WARNING 0x2FFF /* Number for Last Error */
> #define HEIW_RETRY 0x2000 /* One or more retrys have occurred.
> */
>
> /* These are masks for values returned from HEIReadIO and/or
> HEIWriteIO and indicate that some */
> /* error/warning/info condition exists for some module in the base
> (it could be an I/O */
> /* module or it could be the ethernet module. The function
> HEIReadModuleStatus can then be used */
> /* to retrieve the actual conditions. Note that more than one of
> the conditions can exist at any time. */
> #define MASK_DEVICE_ERROR 0x1000
> #define MASK_DEVICE_WARNING 0x2000
> #define MASK_DEVICE_INFO 0x4000
>
> /* Data Types */
> #define DT_IP_ADDRESS 0x0010 /* 4 Byte IP address */
> #define DT_NODE_NUMBER 0x0020 /* 4 Byte Node Number */
> #define DT_SUBNET_MASK 0x0030 /* 4 Byte Subnet Mask */
> #define DT_GATEWAY_ADDRESS 0x0040 /* 4 Byte Gateway Address */
> #define DT_ERASE_COUNT 0x0050 /* 4 Byte used internally */
> #define DT_SERIAL_SETUP 0x0011 /* 8 Byte Serial Setup (see
> SerialSetup)*/
> #define DT_SET_PARM 0x8011 /* 8 Byte Parm Setup (see PARM_XXXX
> defines) */
> #define DT_SETUP_ERROR_LIGHT 0x8012 /* 16 Byte Error Light Setup
> (see ErrorLightSetup) */
> #define DT_STARTUP_SETTINGS 0x0013 /* 32 Byte Startup settings data
> (see StartupSettings above) */
> #define DT_TIME_OF_DAY 0x8013 /* SYSTEMTIME structure */
> #define DT_TYPE_STRING 0x0033 /* 32 Byte ASCII String for netedit
> type identification */
> #define DT_ENCRYPT_KEY_FLASH 0x0014 /* 64 Byte key data from FALSH
> See Encryption structure */
> #define DT_ENCRYPT_KEY_RAM 0x8014 /* 64 Byte key data from RAM -
> This is the working copy! */
> /* See Encryption structure */
> #define DT_MODULE_SETUP 0x0024 /* 64 Byte data from FLASH. See
> ModuleSetup structure */
> #define DT_RXWX_SETTINGS 0x0015 /* 128 Bytes settings see
> HEISettings */
> #define DT_SETTINGS 0x0015 /* 128 Bytes settings see HEISettings
> */
> #define DT_DRIVE_SETUP 0x0025 /* 128 Byte DriveSetup structure */
> #define DT_NODE_NAME 0x0016 /* 256 Byte Node Name */
> #define DT_DESCRIPTION 0x0026 /* 256 Byte Node Description */
> #define DT_LINK_MONITOR 0x8006 /* 256 Byte Link monitor setup
> (Ram Based) */
> /* See LinkMonitor structure below */
> #define DT_IP_SETUP 0x0036 /* 256 Byte IP Setup structure (see
> IPSetup) */
> #define DT_WPLC_SYS_INFO 0x0046 /* 256 Byte WinPLC system info
> (see WPLCSystemInformation) */
> #define DT_ERM_CONFIG 0x0056 /* 256 Byte ERM Config info (see
> sERMConfig) */
> #define DT_ERM_INFO 0x8016 /* 256 Byte ERM Info (see sERMInfo) */
> #define DT_DEV_COMMAND 0x8026 /* 32 Byte ERM Command (see
> sDevCommand) */
> #define DT_BASE_DEF 0x0017 /* 512 Byte Base Def (405
> HEIWriteBaseDef) */
> #define DT_RXWX_NODE_ADDR_1 0x0027 /* 512 Byte node address data
> for addr 00-31 */
> #define DT_RXWX_NODE_ADDR_2 0x0037 /* 512 Byte node address data
> for addr 32-63 */
> #define DT_RXWX_NODE_ADDR_3 0x0047 /* 512 Byte node address data
> for addr 64-95 */
> #define DT_R_W_IO_DEF 0x0057 /* 512 Byte read/write IO def (for
> Drive card) (base 0) (see MemoryItemBase) */
> #define DT_ERM_DEV_00_03 0x0067 /* 512 Byte ERM device data
> (Devices numbers 00 - 03) (See sERMDevice) */
> #define DT_ERM_DEV_04_07 0x0077 /* 512 Byte ERM device data
> (Devices numbers 04 - 07) (See sERMDevice) */
> #define DT_ERM_DEV_08_11 0x0087 /* 512 Byte ERM device data
> (Devices numbers 08 - 11) (See sERMDevice) */
> #define DT_ERM_DEV_12_15 0x0097 /* 512 Byte ERM device data
> (Devices numbers 12 - 15) (See sERMDevice) */
> #define DT_RESET 0x8010 /* 4 Byte (32-Bit) reset flag.
> (RESET_XXX values below) */
> #define DT_BOOT_OS 0x0023 /* 32 Byte OS Boot data */
> #define DT_MODULE_INIT_BASE 0x8057 /* 512 Byte Module
> Initialization data: (from I/O Base) */
>
> /* Common functions. */
> #define FUN_POLLING 0x00 /* Polling one module */
> #define FUN_READ_VER_INFO 0x01 /* Read Version Info from module */
> #define FUN_READ_SUPPORT_INFO 0x02 /* Read Support Info from
> module */
> /* 0x03 UNUSED */
> #define FUN_READ_DEVICE_INFO 0x04 /* Read Device Info from module */
> #define FUN_POLLING_ALL 0x05 /* Polling all bases on the network
> (returns ethernet address) */
> /* Used as a broadcast function to locate devices on the
> network. */
> #define FUN_WRITE_IO 0x06 /* Write IO data to the base */
> #define FUN_READ_IO 0x07 /* Read IO data from Base */
> #define FUN_READ_BASE_DEF 0x08 /* Read Base Definition */
> #define FUN_QUERY_SETUP_DATA 0x09 /* Query the network for a
> particular type of data with a particular value */
> #define FUN_ENUM_SETUP_DATA 0x0A /* Enumerate the types of data
> stored in a module */
> #define FUN_READ_SETUP_DATA 0x0B /* Read a particular type of data
> from a module */
> #define FUN_WRITE_SETUP_DATA 0x0C /* Write a particular type of
> data to a module */
> #define FUN_DELETE_SETUP_DATA 0x0D /* Delete a particular type of
> data from a module */
> #define FUN_READ_ETHERNET_STATS 0x0E /* Read ethernet statistics
> from the module. */
> #define FUN_WRITE_BASE_DEF 0x0F /* Write Base Definition (305/405
> EBC) */
> /* 0x10 UNUSED */
> /* 0x11 UNUSED */
> /* 0x12 UNUSED */
> /* 0x13 UNUSED */
> #define FUN_PET_LINK 0x14 /* Used to keep the link sense timer
> from firing in the absense of ReadIO or WriteIO messages */
> #define FUN_ADDRESSED_BROADCAST 0x15 /* Used to broadcast to a
> particular ethernet address. Used to setup IP address in a new
> module. */
> #define FUN_DATA_BROADCAST 0x16 /* Used to broadcast to a
> particular data type. */
> #define FUN_READ_MODULE_STATUS 0x17 /* Read the status bytes from
> each of the slots of the module. */
> #define FUN_INIT_BASE_DEF 0x18 /* Initialize the base def by re-
> reading from the backplane */
> #define FUN_CCM_REQUEST 0x19 /* Perform a CCM Request with an
> ECom Module */
> #define FUN_KSEQ_REQUEST 0x1A /* Perform a K-Seq Request with an
> ECom Module */
> #define FUN_BACKPLANE_REQUEST 0x1B /* Perform a backplane request
> on an ECom Module */
> #define FUN_EXTEND_RESPONSE 0x1C /* Extends the response packet. */
> #define FUN_ACK 0x20 /* Acknowledge */
> #define FUN_NAK 0x21 /* Not acknowledge */
> #define FUN_RESPONSE 0x22 /* Response */
> #define FUN_SERIAL_PORT 0x23 /* Execute serial port function (see
> below) */
> #define FUN_WRITE_MEMORY 0x24 /* Write a particular memory type */
> #define FUN_READ_MEMORY 0x25 /* Read a particular memory type */
> #define FUN_ENUM_MEMORY 0x26 /* Get list of all memory types */
> #define FUN_ACCESS_MEMORY 0x27 /* Access (Read/Write) multiple
> memory types */
> #define FUN_READ_SHARED_RAM 0x28 /* Read shared ram */
> #define FUN_WRITE_SHARED_RAM 0x29 /* Write shared ram */
> #define FUN_WRITE_IO_NO_READ 0x30 /* Write IO without returned read
> */
> #define FUN_COMM_RESPONSE 0x31 /* Response to PLC generated COMM
> request */
> #define FUN_COMM_REQ_ACK 0x32 /* Function from PLC generated COMM
> request */
> #define FUN_COMM_NO_REQ_ACK 0x33 /* Function from PLC generated
> COMM request */
> #define FUN_RUN_PROGRAM 0x34 /* Function to execute a program */
> #define FUN_REMOTE_API 0x35 /* Function to execute a function on
> remote device */
> #define FUN_NOTIFY 0x36 /* Indicates a notification */
> #define FUN_COMPLETION 0x37 /* Indicates completion of some
> activity */
> #define FUN_PROXY 0x38 /* Indicates a proxy function request */
> #define FUN_QUERY_RESPONSE 0x55 /* This is a response to a query
> function */
> #define FUN_USER_CONFIG_PANEL 0x60 /* User specific data for
> AVG Panel */
> #define FUN_WRITE_CONFIG_DATA 0x61 /* Write Config data to the
> base */
> #define FUN_READ_CONFIG_DATA 0x62 /* Read Config data from Base */
> #define FUN_UNSUPPORTED 0x99 /* This function will never be
> supported by any device (internal use only) */
> #define FUN_SET_OS_LOAD 0xF9 /* Set Load OS Parm. */
> #define FUN_REBOOT 0xFA /* Reboot OS */
>
> /* Serial port functions */
> #define SPF_WRITE_COMM 0x01 /* Writes one or more characters to
> the serial port */
> #define SPF_READ_COMM 0x02 /* Reads zero or more characters from
> the serial port */
> #define SPF_RX_AVAILABLE 0x03 /* Returns number of characters
> available in the input queue */
> #define SPF_RX_FLUSH 0x04 /* Flushs the serial port input queue
> */
> #define SPF_SETUP 0x05 /* Setup serial port (see SerialSetup
> above) */
> #define SPF_TX_LEFT 0x06 /* Returns number of characters left
> in the output queue */
> #define SPF_READ_SETUP 0x07 /* Read Setup serial port (see
> SerialSetup above) */
> #define SPF_ACCESS_COMM 0x08 /* Used to read / write multiple
> ports */
> #define SPF_TX_FLUSH 0x09 /* Flushs the serial port output
> queue */
> /* Serial port commands for HEIAccessComm */
> #define SPC_WRITE_PORT 0x01
> #define SPC_READ_PORT 0x02
> #define SPC_RX_FLUSH 0x04
> #define SPC_TX_FLUSH 0x09
> #define SPC_ERROR 0x80
> #define SPC_READ_RESPONSE 0x82
> #define SPC_DONE 0xFF
> /* Reset values */
> #define RESET_DRIVE_RELAY 0x01 /* Reset relay on ethernet drive
> card */
> /* Parm values */
> #define PARM_RETURN_SYS_ERRORS 0x01
>
> /*
> Memory Types.
> Description of memory types.
> A memory type is a 16 bit value that is divided up as follows:
> FEDCBA9876543210
> PKAAFFFFTTTTUNNN
> ||| | | ||
> ||| | | ||-- Number: Index number from 0 to 7
> ||| | | |
> ||| | | |-- Undefined (set to zero)
> ||| | |
> ||| | |-- Type: 0000 = General Purpose
> ||| | 0001 = Program
> ||| | 0010 = System
> ||| | 0011 = Timer
> ||| | 0100 = Counter
> ||| | 0101 = Setup
> ||| | 0110 = Input
> ||| | 0111 = Output
> ||| | 1000 = Undefined
> ||| | 1001 = Undefined
> ||| | 1010 = Undefined
> ||| | 1011 = Undefined
> ||| | 1100 = Undefined
> ||| | 1101 = Undefined
> ||| | 1110 = Undefined
> ||| | 1111 = Undefined
> ||| |
> ||| |-- Format: 0000 = Bit
> ||| 0001 = Byte
> ||| 0010 = Word
> ||| 0011 = DWord
> ||| 0100 = Float
> ||| 0101 = Undefined
> ||| 0110 = Undefined
> ||| 0111 = Undefined
> ||| 1000 = Undefined
> ||| 1001 = Undefined
> ||| 1010 = Undefined
> ||| 1011 = Undefined
> ||| 1100 = Undefined
> ||| 1101 = Undefined
> ||| 1110 = Undefined
> ||| 1111 = Undefined
> |||
> |||-- Access: 00 = Read / write
> || 01 = Read Only
> || 10 = Write Only
> || 11 = Undefined
> ||
> ||-- Kind of memory: 0 = Ram; 1 = Flash
> |
> |-- Protection: 1 = Protected; 0 = Not Protected
>
>
> Example:
> V-Memory in Koyo boxes (205/405) is General Purpose, WORD format,
> Read / Write, RAM.
> this would make the type be: 0000 0010 0000 0000 = 0200h = 512
>
> CR Memory in Koyo boxes is General Purpose, Bit format, Read /
> Write, RAM,
> this would make the type be: 0000 0000 0000 0000 = 0000h = 0
>
> Scratch Pad Memory in Koyo boxes is System, Byte Format, Read /
> Write, RAM.
> this would make the type be: 0000 0001 0010 0000 = 0120h = 288
>
> SP's in Koyo boxes is System, Bit Format, Read Only, RAM
> this would make the type be: 0001 0000 0010 0000 = 1020h = 4128
> */
> #define MT_KOYO_V 0x0200 /* V-Memory */
> #define MT_KOYO_C 0x0000 /* C-Memory */
> #define MT_KOYO_Z 0x0120 /* Scratch Pad Memory */
> #define MT_KOYO_SP 0x1020 /* SP-Memory */
> #define MT_DRIVE_FIRST 0x300 /* First memory type for Hitachi
> Drives */
> #define MT_HITACHI_D 0x300 /* Hitachi Drive Memory: Monitoring
> functions */
> #define MT_HITACHI_F 0x301 /* Hitachi Drive Memory: Basic Profile
> functions */
> #define MT_HITACHI_A 0x302 /* Hitachi Drive Memory: Standard
> functions */
> #define MT_HITACHI_B 0x303 /* Hitachi Drive Memory: Fine tuning
> functions */
> #define MT_HITACHI_C 0x304 /* Hitachi Drive Memory: Intelligent
> terminal functions */
> #define MT_HITACHI_H 0x305 /* Hitachi Drive Memory: Sensorless
> vector functions */
> #define MT_HITACHI_O 0x306 /* Hitachi Drive Memory: Other
> functions */
> #define MT_HITACHI_OP 0x307 /* Hitachi Drive Memory: Option Board */
> #define MT_HITACHI_R 0x308 /* Hitachi Drive Memory: Reference
> codes */
> /* The following offsets can only be used with HEIReadMemory (not
> HEIAccessMemory) */
> #define MT_INFO_OFFSET 0x100 /* Add MT_INFO_OFFSET to above
> MT_HITACHI_? types to get MemoryTypeInfo for the given ID */
> #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 */
> #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) */
> #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) */
> #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) */
> typedef struct
> {
> DWORD MinVal; /* Minimum value for this type */
> DWORD MaxVal; /* Maximum value for this type */
> BYTE Magnitude; /* Magnitude of type. See MAG_XXXX values */
> BYTE RunModeEdit; /* If TRUE, this field can be edited in run mode */
> BYTE ReadOnly; /* If TRUE, this field is read-only */
> BYTE FieldType; /* Type of memory. see FIELD_XXXX values */
> BYTE NumBits; /* If FieldType == FIELD_BIT, this tells the number
> of bits */
> BYTE StartBit; /* If FieldType == FIELD_BIT, this tells the
> starting bit number */
> BYTE Size; /* Internal size in bytes */
> WORD Addr; /* Internal address */
> BYTE Unused[13]; /* Unused */
> WORD NameLength; /* Length of pName (including null terminator) */
> char Name[224]; /* Name string for the given memory type */
> } MemoryTypeInfo;
>
> typedef struct
> {
> WORD Type;
> WORD Id;
> } MemoryItem;
> typedef struct
> {
> MemoryItem Items[16];
> } MemoryItemSlot;
> typedef struct
> {
> MemoryItemSlot Slot[8];
> } MemoryItemBase;
> #define FIELD_NORMAL 0
> #define FIELD_CODE 1
> #define FIELD_BIT 2
> #define MAG_00001 0
> #define MAG_00010 1
> #define MAG_00100 2
> #define MAG_01000 3
>
> /* Hitachi Drive type defines */
> #define L100 1
> #define SJ100 2
> #define J300 3
> #define SJ300 4
> /* GS Drive type defines */
> #define GS1 1
> #define GS2 2
> #define GS3 3
> #define GS4 4
> /* Defines for Data formats */
> #define DF_BIT_IN 0x03
> #define DF_BIT_OUT 0x04
> #define DF_BYTE_IN 0x10
> #define DF_BYTE_OUT 0x11
> #define DF_WORD_IN 0x05
> #define DF_WORD_OUT 0x06
> #define DF_DWORD_IN 0x08
> #define DF_DWORD_OUT 0x09
> #define DF_DOUBLE_IN 0x12
> #define DF_DOUBLE_OUT 0x13
> #define DF_FLOAT_IN 0x14
> #define DF_FLOAT_OUT 0x15
> #define DF_CONFIG 0x16
>
> /* Data type defines for HX-ERM */
> #define DATA_SIZE_INFO 0 /* Used to read the size info for */
> #define DATA_INPUT 1 /* Used to read/write all input data */
> #define DATA_OUTPUT 2 /* Used to read/write all output data */
> #define DATA_DESCRIPTION 3 /* Used to read description/layout of I/
> O data */
> #define DATA_COMMAND 4 /* Used to read/write to command buffer */
> #define DATA_ERMINFO 5 /* Used to read sERMInfo structure */
> /* Commands for the HX-ERM module */
> #define COMMAND_PROCESS_IO 1
> #define COMMAND_ABORT 2
> #define COMMAND_PROCESS_COMMAND_BUFFER 3
>
> /* Restore structure alignment boundary */
> #pragma pack()
>
> #endif /* #if !defined(__HEI_H) */
>
>
> #include "defs.h"
> #include <memory.h>
> #include <malloc.h>
> #include "hei.h"
> #define TimeDiff(StartTime, EndTime) (((DWORD)EndTime >
> (DWORD)StartTime) ? ((DWORD)EndTime - (DWORD)StartTime) :
> ((DWORD)EndTime + ((DWORD)ULONG_MAX - (DWORD)StartTime) + 1))
> DWORD HEIIGetCounter();
> int GetResponseEx(HEIDevice *apDevice[], BYTE *apData[], WORD
> aSizeofData[], int aErrorCode[], int DeviceCount)
> {
> int Done = TRUE;
> int idx = 0;
> for(idx = 0; idx < DeviceCount; idx++)
> {
> /* Handle NULL device */
> if(!apDevice[idx])
> continue;
> if(aErrorCode[idx] == HEIE_NO_RESPONSE)
> {
> BYTE Buff[500];
> int BuffLen = sizeof(Buff);
> aErrorCode[idx] = HEIGetResponse(apDevice[idx], Buff, &BuffLen,
> TRUE);
> /* If no response, continue */
> if(aErrorCode[idx] == HEIE_NO_RESPONSE)
> {
> Done = FALSE;
> continue;
> }
> /* Check for error and not warning. */
> if(aErrorCode[idx] && !(aErrorCode[idx] & HEIW_FIRST_WARNING))
> {
> /* Set data size to 0 */
> aSizeofData[idx] = 0;
> }
> else
> {
> if(BuffLen)
> {
> short int *pInt = (short int *)&Buff[PACKET_HEADER_SIZE];
> BuffLen -= PACKET_HEADER_SIZE;
> BuffLen -= 2;
> if((WORD)BuffLen > aSizeofData[idx])
> {
> BuffLen = aSizeofData[idx];
> aErrorCode[idx] = HEIE_BUFFER_TOO_SMALL;
> }
> if(*pInt)
> aErrorCode[idx] = (*pInt) | 0x8000;
> memcpy(apData[idx], Buff+PACKET_HEADER_SIZE+2, BuffLen);
> aSizeofData[idx] = BuffLen;
> }
> else
> {
> /* Set data size to 0 */
> aSizeofData[idx] = 0;
> aErrorCode[idx] = HEIE_ZERO_BYTES_RECEIVED;
> }
> }
> }
> }
> return Done;
> }
> DWORD StartHEIReadIO(HEIDevice *pDevice, BYTE *pData, WORD
> *pSizeofData, int *pErrorCode)
> {
> DWORD StartTime = 0;
> BOOL OldPP = FALSE;
> /* Force parallel packet mode */
> OldPP = pDevice->ParallelPackets;
> pDevice->ParallelPackets = TRUE;
> /* Init error code */
> *pErrorCode = HEIE_NO_RESPONSE;
> /* Log the time */
> StartTime = HEIIGetCounter();
> /* Send request */
> HEIReadIO(pDevice, pData, pSizeofData);
> /* Restore parallel packet mode */
> pDevice->ParallelPackets = OldPP;
> return StartTime;
> }
> __declspec(dllexport) int HEIReadIOEx
> (
> HEIDevice *apDevice[],
> BYTE *apData[],
> WORD aSizeofData[],
> int aErrorCode[],
> int DeviceCount
> )
> {
> int idx = 0;
> BOOL Done = FALSE;
> DWORD *pStartTime = (DWORD *)calloc(sizeof(DWORD), DeviceCount);
> int MaxStarted = 0;
> int StartAt = 0;
> /* Reset retry count */
> for(idx = 0; idx < DeviceCount; idx++)
> if(apDevice[idx])
> apDevice[idx]->SizeOfData = 0;
> while(!Done)
> {
> /* Start a request */
> for(idx = StartAt; idx < DeviceCount; idx++)
> {
> /* Handle NULL device */
> if(!apDevice[idx])
> {
> StartAt = idx + 1;
> if(idx+1 > MaxStarted)
> MaxStarted = idx + 1;
> }
> /* If request not started, start it */
> else if(!pStartTime[idx])
> {
> pStartTime[idx] = StartHEIReadIO(apDevice[idx], apData[idx],
> &aSizeofData[idx], &aErrorCode[idx]);
> StartAt = idx + 1;
> if(idx+1 > MaxStarted)
> MaxStarted = idx + 1;
> break;
> }
> }
> /* Test for completion of requests */
> GetResponseEx(apDevice, apData, aSizeofData, aErrorCode,
> MaxStarted);
> /* When all have been started, we're done until proven otherwise */
> Done = MaxStarted == DeviceCount;
>
> /* Test for timeout of requests */
> for(idx = 0; idx < MaxStarted; idx++)
> {
> /* Handle NULL device */
> if(!apDevice[idx])
> continue;
> /* If request started, test timeout */
> if(aErrorCode[idx] == HEIE_NO_RESPONSE && pStartTime[idx])
> {
> /* Check timeout for device */
> if(TimeDiff(pStartTime[idx], HEIIGetCounter()) >= apDevice[idx]-
> >Timeout)
> {
> /* Timed out, check retries */
> if(apDevice[idx]->SizeOfData < apDevice[idx]->Retrys)
> {
> apDevice[idx]->SizeOfData++;
> apDevice[idx]->RetryCount++;
> /* Reset */
> pStartTime[idx] = 0;
> aErrorCode[idx] == HEIE_NO_RESPONSE;
> if(idx < StartAt)
> StartAt = idx;
>
> /* Not done */
> Done = FALSE;
> }
> /* No more retries */
> else
> {
> /* Set error code */
> aErrorCode[idx] = HEIE_TIMEOUT;
>
> /* This device is done */
> }
> }
> /* Started but not timed out */
> else
> /* Not done */
> Done = FALSE;
> }
> /* If not started... */
> else if(!pStartTime[idx])
> {
> /* Can't be done */
> Done = FALSE;
> }
> }
> }
> free(pStartTime);
> return 0;
> }
> DWORD StartHEIWriteIO(HEIDevice *pDevice, BYTE *pData, WORD
> SizeofData, BYTE *pReturnData, WORD *pSizeofReturnData, int
> *pErrorCode)
> {
> DWORD StartTime = 0;
> BOOL OldPP = FALSE;
> /* Force parallel packet mode */
> OldPP = pDevice->ParallelPackets;
> pDevice->ParallelPackets = TRUE;
> /* Init error code */
> *pErrorCode = HEIE_NO_RESPONSE;
> /* Log the time */
> StartTime = HEIIGetCounter();
> /* Send request */
> HEIWriteIO(pDevice, pData, SizeofData, pReturnData,
> pSizeofReturnData);
> /* Restore parallel packet mode */
> pDevice->ParallelPackets = OldPP;
> return StartTime;
> }
> __declspec(dllexport) int HEIWriteIOEx
> (
> HEIDevice *apDevice[],
> BYTE *apData[],
> WORD aSizeofData[],
> BYTE *apReturnData[],
> WORD aSizeofReturnData[],
> int aErrorCode[],
> int DeviceCount
> )
> {
> int idx = 0;
> BOOL Done = FALSE;
> DWORD *pStartTime = (DWORD *)calloc(sizeof(DWORD), DeviceCount);
> int MaxStarted = 0;
> int StartAt = 0;
> /* Reset retry count */
> for(idx = 0; idx < DeviceCount; idx++)
> if(apDevice[idx])
> apDevice[idx]->SizeOfData = 0;
> while(!Done)
> {
> /* Start a request */
> for(idx = StartAt; idx < DeviceCount; idx++)
> {
> /* Handle NULL device */
> if(!apDevice[idx])
> {
> StartAt = idx + 1;
> if(idx+1 > MaxStarted)
> MaxStarted = idx + 1;
> }
> /* If request not started, start it */
> else if(!pStartTime[idx])
> {
> pStartTime[idx] = StartHEIWriteIO(apDevice[idx], apData[idx],
> aSizeofData[idx], apReturnData[idx], &aSizeofReturnData[idx],
> &aErrorCode[idx]);
> StartAt = idx + 1;
> if(idx+1 > MaxStarted)
> MaxStarted = idx + 1;
> break;
> }
> }
> /* Test for completion of requests */
> GetResponseEx(apDevice, apReturnData, aSizeofReturnData,
> aErrorCode, MaxStarted);
> /* When all have been started, we're done until proven otherwise */
> Done = MaxStarted == DeviceCount;
>
> /* Test for timeout of requests */
> for(idx = 0; idx < MaxStarted; idx++)
> {
> /* Handle NULL device */
> if(!apDevice[idx])
> continue;
> /* If request started, test timeout */
> if(aErrorCode[idx] == HEIE_NO_RESPONSE && pStartTime[idx])
> {
> /* Check timeout for device */
> if(TimeDiff(pStartTime[idx], HEIIGetCounter()) >= apDevice[idx]-
> >Timeout)
> {
> /* Timed out, check retries */
> if(apDevice[idx]->SizeOfData < apDevice[idx]->Retrys)
> {
> apDevice[idx]->SizeOfData++;
> apDevice[idx]->RetryCount++;
> /* Reset */
> pStartTime[idx] = 0;
> aErrorCode[idx] == HEIE_NO_RESPONSE;
> if(idx < StartAt)
> StartAt = idx;
>
> /* Not done */
> Done = FALSE;
> }
> /* No more retries */
> else
> {
> /* Set error code */
> aErrorCode[idx] = HEIE_TIMEOUT;
>
> /* This device is done */
> }
> }
> /* Started but not timed out */
> else
> /* Not done */
> Done = FALSE;
> }
> /* If not started... */
> else if(!pStartTime[idx])
> {
> /* Can't be done */
> Done = FALSE;
> }
> }
> }
> free(pStartTime);
> return 0;
> }
>
> #if 0
> int GetResponseEx(HEIDevice *apDevice[], BYTE *apData[], WORD
> aSizeofData[], int aErrorCode[], int DeviceCount)
> {
> int Done = TRUE;
> int idx = 0;
> for(idx = 0; idx < DeviceCount; idx++)
> {
> /* Handle NULL device */
> if(!apDevice[idx])
> continue;
> if(aErrorCode[idx] == HEIE_NO_RESPONSE)
> {
> BYTE Buff[500];
> int BuffLen = sizeof(Buff);
> aErrorCode[idx] = HEIGetResponse(apDevice[idx], Buff, &BuffLen,
> TRUE);
> /* If no response, continue */
> if(aErrorCode[idx] == HEIE_NO_RESPONSE)
> {
> Done = FALSE;
> continue;
> }
> /* Check for error and not warning. */
> if(aErrorCode[idx] && !(aErrorCode[idx] & HEIW_FIRST_WARNING))
> {
> /* Set data size to 0 */
> aSizeofData[idx] = 0;
> }
> else
> {
> if(BuffLen)
> {
> short int *pInt = (short int *)&Buff[PACKET_HEADER_SIZE];
> BuffLen -= PACKET_HEADER_SIZE;
> BuffLen -= 2;
> if((WORD)BuffLen > aSizeofData[idx])
> {
> BuffLen = aSizeofData[idx];
> aErrorCode[idx] = HEIE_BUFFER_TOO_SMALL;
> }
> if(*pInt)
> aErrorCode[idx] = (*pInt) | 0x8000;
> memcpy(apData[idx], Buff+PACKET_HEADER_SIZE+2, BuffLen);
> aSizeofData[idx] = BuffLen;
> }
> else
> {
> /* Set data size to 0 */
> aSizeofData[idx] = 0;
> aErrorCode[idx] = HEIE_ZERO_BYTES_RECEIVED;
> }
> }
> }
> }
> return Done;
> }
> __declspec(dllexport) int HEIReadIOEx
> (
> HEIDevice *apDevice[],
> BYTE *apData[],
> WORD aSizeofData[],
> int aErrorCode[],
> int DeviceCount,
> DWORD Timeout
> )
> {
> DWORD StartTime = HEIIGetCounter();
> int idx = 0;
> BOOL Done = FALSE;
> BOOL OldPP = FALSE;
> for(idx = 0; idx < DeviceCount; idx++)
> {
> /* Handle NULL device */
> if(!apDevice[idx])
> continue;
> /* Force parallel packet mode */
> OldPP = apDevice[idx]->ParallelPackets;
> apDevice[idx]->ParallelPackets = TRUE;
> /* Init error code */
> aErrorCode[idx] = HEIE_NO_RESPONSE;
> /* Send request */
> HEIReadIO(apDevice[idx], apData[idx], &aSizeofData[idx]);
> /* Check for response */
> GetResponseEx(apDevice, apData, aSizeofData, aErrorCode, idx+1);
> /* Restore parallel packet mode */
> apDevice[idx]->ParallelPackets = OldPP;
> }
> /* Spin on GetResponseEx waiting for timeout */
> while(!Done)
> {
> Done = GetResponseEx(apDevice, apData, aSizeofData, aErrorCode,
> idx);
> if(TimeDiff(StartTime, HEIIGetCounter()) >= Timeout)
> return HEIE_TIMEOUT;
> }
> return 0;
> }
> __declspec(dllexport) int HEIWriteIOEx
> (
> HEIDevice *apDevice[],
> BYTE *apData[],
> WORD aSizeofData[],
> BYTE *apReturnData[],
> WORD aSizeofReturnData[],
> int aErrorCode[],
> int DeviceCount,
> DWORD Timeout
> )
> {
> DWORD StartTime = HEIIGetCounter();
> int idx = 0;
> BOOL Done = FALSE;
> BOOL OldPP = FALSE;
> for(idx = 0; idx < DeviceCount; idx++)
> {
> /* Handle NULL device */
> if(!apDevice[idx])
> continue;
> /* Force parallel packet mode */
> OldPP = apDevice[idx]->ParallelPackets;
> apDevice[idx]->ParallelPackets = TRUE;
> /* Init error code */
> aErrorCode[idx] = HEIE_NO_RESPONSE;
> /* Send request */
> HEIWriteIO(apDevice[idx], apData[idx], aSizeofData[idx],
> apReturnData[idx], &aSizeofReturnData[idx]);
> /* Check for response */
> GetResponseEx(apDevice, apReturnData, aSizeofReturnData,
> aErrorCode, idx+1);
> /* Restore parallel packet mode */
> apDevice[idx]->ParallelPackets = OldPP;
> }
> /* Spin on GetResponseEx waiting for timeout */
> while(!Done)
> {
> Done = GetResponseEx(apDevice, apReturnData, aSizeofReturnData,
> aErrorCode, idx);
> if(TimeDiff(StartTime, HEIIGetCounter()) >= Timeout)
> return HEIE_TIMEOUT;
> }
> return 0;
> }
> #endif
>
> /*
> ** HEI.C - Platform dependent code for communicating with Host
> Automation Products
> ** line of ethernet modules using the WinSock transport.
> **
> ** Copyright (C) - 1996-1998 Host Automation Products, Inc.
> **
> */
> #include "winsock.h" /* Needed for winsock calls */
> #include "wsipx.h" /* Needed for winsock IPX calls */
> #include "mmsystem.h" /* Needed for timer stuff */
> #include "hei.h"
> #include <memory.h>
> /*
> ** Notes for porting code to another platform:
> **
> ** This file contains the transport/system dependant code for use
> with the
> ** Host Ethernet Interface (HEI). There are nine functions which
> must be
> ** implemented by this code:
> **
> ** 1) int HEIIOpen();
> ** 2) int HEIIClose();
> ** 3) int HEIIOpenTransport(HEITransport *pTransport);
> ** 4) int HEIICloseTransport(HEITransport *pTransport);
> ** 5) int HEIIOpenDevice(HEITransport *pTransport, HEIDevice
> *pDevice);
> ** 6) int HEIICloseDevice(HEIDevice *pDevice);
> ** 7) int HEIIReceivePacket(HEIDevice *pDevice, BYTE *pResponse,
> int *pResponseSize);
> ** 8) int HEIISendPacket(HEIDevice *pDevice, BYTE *pPacket, WORD
> PacketSize);
> ** 9) DWORD HEIIGetCounter();
> **
> ** Make changes in this file, do not change HEI.C or any structures
> in HEI.H!
> ** If you find that you must change something in HEI.C, contact the
> person
> ** you got this source from.
> **
> ** Feel free to remove any of the WinSock specific code from this
> module.
> **
> ** To compile the code for ANSI C, ANSI_C must be defined!
> **
> ** See all sections containing "TODO_FOR_OTHER_SYSTEM" for further
> details.
> **
> */
>
> /* Counter for the number of times that OpenTransport has been
> called */
> static int WinSockLoadCount = 0;
> /*
> ** Windows version gets stored here. It is used for setting winsock
> options
> ** Win 16 is slightly different than Win 32.
> */
> WORD WinVer=0;
> /* This is the port number to use when talking to a module. */
> #define PORT_ID 0x7070
> /* This function should return a millisecond resolution tick
> counter. */
> DWORD HEIIGetCounter()
> {
> /*return timeGetTime(); */
> LARGE_INTEGER freq, count;
> QueryPerformanceFrequency(&freq);
> QueryPerformanceCounter(&count);
> return (DWORD)((count.QuadPart * 1000) / freq.QuadPart);
> }
>
> /*
> ** This function is called from within HEIOpen. It gives the
> opportunity
> ** to do initialization type stuff. NOTE: This function may be
> called more
> ** than once!
> **
> ** RETURNS: 0 on success
> ** non-zero on error.
> */
> int HEIIOpen()
> {
> /* Save the windows version for later use. */
> DWORD dwVersion = GetVersion();
> WinVer = LOWORD(dwVersion);
> /*
> ** TODO_FOR_OTHER_SYSTEM
> ** Do system level init stuff here.
> ** Be aware that this may be called more than once.
> */
> return HEIE_NULL;
> }
>
> /*
> ** This function is called from within HEIClose. It gives the
> opportunity
> ** to do shutdown type stuff. NOTE: This function may be called more
> ** than once!
> **
> ** RETURNS: 0 on success
> ** non-zero on error.
> */
> int HEIIClose()
> {
> /*
> ** TODO_FOR_OTHER_SYSTEM
> ** Do system level shut down stuff here.
> ** Be aware that this may be called more than once.
> */
> return HEIE_NULL;
> }
>
> /*
> ** This function is called from within HEIOpenTransport. It is used
> to prepare
> ** the given Transport to be used in subsequent HEIOpenDevice calls.
> **
> ** RETURNS: 0 on success
> ** non-zero on error.
> */
> int HEIIOpenTransport(HEITransport *pTransport)
> {
> switch (pTransport->Transport)
> {
> case HEIT_WINSOCK: /* Open Transport type HEIT_WINSOCK */
> {
> /* WinSock Transport. Protocol must be either IPX or IP */
> if (pTransport->Protocol == HEIP_IPX || pTransport->Protocol ==
> HEIP_IP)
> {
> /* Keep track of load count, Initialize winsock if zero. */
> if (!WinSockLoadCount)
> {
> WSADATA wsaData;
> WORD wVersionRequested = MAKEWORD(2, 0);
>
> /* Initialize winsock dll */
> if(WSAStartup(wVersionRequested, &wsaData) == SOCKET_ERROR)
> return WSAGetLastError();
> }
> WinSockLoadCount++;
> }
> else
> return HEIE_UNSUPPORTED_PROTOCOL;
> break;
> }
>
> case HEIT_OTHER_TRANSPORT:
> {
> /*
> ** TODO_FOR_OTHER_SYSTEM
> ** Do one time init stuff by keeping track of the number of times
> this
> ** transport has been opened.
> ** Don't return HEIE_UNSUPPORTED_TRANSPORT
> */
> return HEIE_UNSUPPORTED_TRANSPORT;
> }
>
> default:
> return HEIE_UNSUPPORTED_TRANSPORT;
> }
>
> return HEIE_NULL;
> }
>
>
> /*
> ** This function is called from within HEICloseTransport. It
> indicates
> ** that the given Transport is no longer in use.
> **
> ** RETURNS: 0 on success
> ** non-zero on error.
> */
> int HEIICloseTransport(HEITransport *pTransport)
> {
> switch (pTransport->Transport)
> {
> case HEIT_WINSOCK: /* Close Transport type HEIT_WINSOCK */
> {
> /* WinSock Transport. Protocol must be IPX or IP */
> if (pTransport->Protocol == HEIP_IPX || pTransport->Protocol ==
> HEIP_IP)
> {
> /* Decrement load count. Shut down WinSock if zero */
> if (WinSockLoadCount)
> {
> WinSockLoadCount--;
> if (!WinSockLoadCount)
> WSACleanup();
> }
> }
> else
> return HEIE_UNSUPPORTED_PROTOCOL;
>
> break;
> }
>
> case HEIT_OTHER_TRANSPORT:
> {
> /*
> ** TODO_FOR_OTHER_SYSTEM
> ** Decrement load counter, do cleanup stuff if zero.
> ** Don't return HEIE_UNSUPPORTED_TRANSPORT
> */
> return HEIE_UNSUPPORTED_TRANSPORT;
> }
>
> default:
> return HEIE_UNSUPPORTED_TRANSPORT;
> }
>
> return HEIE_NULL;
> }
>
>
> /*
> ** This function is called from within HEIOpenDevice. It is used to
> prepare
> ** the given Device to be used with the given Transprot.
> **
> ** RETURNS: 0 on success
> ** non-zero on error.
> */
> int HEIIOpenDevice(HEITransport *pTransport, HEIDevice *pDevice)
> {
> switch (pTransport->Transport)
> {
> case HEIT_WINSOCK: /* Open Device type HEIT_WINSOCK */
> {
> /* WinSock Transport. */
> SOCKET sock;
> struct sockaddr *pRemAddr, *pMyAddr;
> int SizeRemAddr, SizeMyAddr;
> u_long NonBlockingMode;
> if (pTransport->Protocol == HEIP_IPX)
> {
> static SOCKADDR_IPX RemAddr, MyAddr;
> /* Initialize remote address */
> if (!pDevice->UseBroadcast)
> memcpy(&RemAddr, pDevice->Address.Raw, sizeof(SOCKADDR_IPX));
> if (pTransport->pSourceAddress)
> {
> MyAddr.sa_family = pTransport->pSourceAddress->AddressIPX.Family;
> memcpy(MyAddr.sa_netnum, pTransport->pSourceAddress-
> >AddressIPX.Netnum, 4);
> memcpy(MyAddr.sa_nodenum, pTransport->pSourceAddress-
> >AddressIPX.Nodenum, 6);
> MyAddr.sa_socket = pTransport->pSourceAddress->AddressIPX.Socket;
> }
> else
> {
> /* Initialize MyAddr to all zeros so that windows can tell me
> who I am! */
> MyAddr.sa_family = AF_IPX;
> /*memcpy(MyAddr.sa_netnum, &pTransport->NetworkAddress, 4);*/
> memset(MyAddr.sa_netnum, 0, 4);
> memset(MyAddr.sa_nodenum, 0, 6);
> MyAddr.sa_socket = 0x00;
> }
> /* get socket handle */
> sock = socket(AF_IPX, /* IPX family */
> SOCK_DGRAM, /* Datagram */
> NSPROTO_IPX);
> pRemAddr = (struct sockaddr *) &RemAddr;
> pMyAddr = (struct sockaddr *) &MyAddr;
> SizeRemAddr = sizeof(RemAddr);
> SizeMyAddr = sizeof(MyAddr);
> }
> else if (pTransport->Protocol == HEIP_IP)
> {
> static struct sockaddr_in RemAddr, MyAddr;
> /*
> ** If Protocol is IP and we are not using broadcast, and
> ** Address.Raw[19] == 1 then the IP address in the module
> ** is undefined.
> */
> if (!pDevice->UseBroadcast && (pDevice->Address.Raw[19] == 1))
> return HEIE_IP_ADDR_NOT_INITIALIZED;
>
> /* Initialize remote address */
> if (!pDevice->UseBroadcast)
> memcpy(&RemAddr, pDevice->Address.Raw, sizeof(RemAddr));
> if (pTransport->pSourceAddress)
> {
> MyAddr.sin_family = pTransport->pSourceAddress->AddressIP.Family;
> MyAddr.sin_port = pTransport->pSourceAddress->AddressIP.Port;
> MyAddr.sin_addr.s_addr = pTransport->pSourceAddress-
> >AddressIP.AddressingType.lAddr;
> }
> else
> {
> /* Initialize MyAddr to all zeros so that windows can tell me
> who I am! */
> MyAddr.sin_family = AF_INET;
> MyAddr.sin_port = 0;
> MyAddr.sin_addr.s_addr = 0;
> }
> /* get socket handle */
> sock = socket(AF_INET, /* IP family */
> SOCK_DGRAM, /* Datagram */
> IPPROTO_UDP);
> pRemAddr = (struct sockaddr *) &RemAddr;
> pMyAddr = (struct sockaddr *) &MyAddr;
> SizeRemAddr = sizeof(RemAddr);
> SizeMyAddr = sizeof(MyAddr);
> }
> else
> return HEIE_UNSUPPORTED_PROTOCOL;
>
> if(sock == INVALID_SOCKET)
> return WSAGetLastError();
> if (bind (sock, pMyAddr, SizeMyAddr) == SOCKET_ERROR)
> {
> int Error = WSAGetLastError();
> closesocket(sock);
> return Error;
> }
> if (pDevice->UseBroadcast)
> {
> int rSetSockOpt;
>
> if (WinVer < 0x0332) /* Check for WinVer < 3.50 */
> {
> /* 16 Bit uses int type. */
> int AllowBroadcast = TRUE;
> rSetSockOpt = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const
> char *) &AllowBroadcast, sizeof(AllowBroadcast));
> }
> else
> {
> /* 32 Bit uses long type. */
> long AllowBroadcast = TRUE;
> rSetSockOpt = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const
> char *) &AllowBroadcast, sizeof(AllowBroadcast));
> }
>
> if (rSetSockOpt == SOCKET_ERROR)
> {
> int Error = WSAGetLastError();
> closesocket(sock);
> return Error;
> }
> }
> else
> {
> if (connect (sock, pRemAddr, SizeRemAddr) == SOCKET_ERROR)
> {
> int Error = WSAGetLastError();
> closesocket(sock);
> return Error;
> }
> }
> /* Setup for non-blocking mode */
> NonBlockingMode = 1;
> if (ioctlsocket (sock, FIONBIO, &NonBlockingMode) == SOCKET_ERROR)
> {
> int Error = WSAGetLastError();
> closesocket(sock);
> return Error;
> }
>
> pDevice->_dwParam = (DWORD) sock;
> break;
> }
>
> case HEIT_OTHER_TRANSPORT:
> {
> /*
> ** TODO_FOR_OTHER_SYSTEM
> ** Prepare to communicate with the given device.
> ** The address to talk to is stored in pDevice->Address (see
> HEI.H for format)
> ** Be aware that pDevice->UseBroadcast indicates that we
> ** will be broadcasting to the module.
> ** For IP, pDevice->Address.Raw[19] == 1 (after a query)
> ** if the given module's IP address is not initialized. In
> ** this case, the only way to talk to it (using IP) is by
> ** using addressed broadcast.
> ** You can use pDevice->_dwParam to store whatever (such as
> ** a socket number).
> ** Don't return HEIE_UNSUPPORTED_TRANSPORT
> */
> return HEIE_UNSUPPORTED_TRANSPORT;
> }
>
> default:
> return HEIE_UNSUPPORTED_TRANSPORT;
> }
>
> return HEIE_NULL;
> }
>
> /*
> ** This function is called from within HEICloseDevice. It indicates
> ** that the given Device is no longer in use.
> **
> ** RETURNS: 0 on success
> ** non-zero on error.
> */
> int HEIICloseDevice(HEIDevice *pDevice)
> {
> switch (pDevice->_pTransport->Transport)
> {
> case HEIT_WINSOCK: /* Close Device type HEIT_WINSOCK */
> {
> /* WinSock Transport. */
> if (pDevice->_pTransport->Protocol == HEIP_IPX || pDevice-
> >_pTransport->Protocol == HEIP_IP)
> {
> SOCKET sock = (SOCKET) pDevice->_dwParam;
>
> if (closesocket(sock) == SOCKET_ERROR)
> return WSAGetLastError();
> }
> else
> return HEIE_UNSUPPORTED_PROTOCOL;
> break;
> }
>
> case HEIT_OTHER_TRANSPORT:
> {
> /*
> ** TODO_FOR_OTHER_SYSTEM
> ** Do device type shutdown stuff.
> ** Don't return HEIE_UNSUPPORTED_TRANSPORT
> */
> return HEIE_UNSUPPORTED_TRANSPORT;
> }
>
> default:
> return HEIE_UNSUPPORTED_TRANSPORT;
> }
>
> return HEIE_NULL;
> }
>
>
> /*
> ** This is the code for receiving a packet from the ethernet driver
> for the given
> ** device. The response should be stored in the given response
> buffer - pResponse.
> ** On entry, pResponseSize contains the size of the response buffer
> (pResponse).
> ** On exit, pResponseSize MUST contain the number of bytes copied
> to the response buffer.
> **
> ** RETURNS: 0 on success
> ** non-zero on error.
> */
> int HEIIReceivePacket(HEIDevice *pDevice, BYTE *pResponse, int
> *pResponseSize)
> {
> int Retval = HEIE_NULL;
>
> switch (pDevice->_pTransport->Transport)
> {
> case HEIT_WINSOCK: /* GetResponse from HEIT_WINSOCK */
> {
> int NumBytes;
> SOCKET sock = (SOCKET) pDevice->_dwParam;
>
> if (pDevice->UseBroadcast)
> {
> struct sockaddr FromAddr;
> int FromLen = sizeof(FromAddr);
>
> NumBytes = recvfrom(sock, (char *) pResponse, *pResponseSize, 0,
> &FromAddr, &FromLen);
>
> if (pDevice->pData)
> {
> /* Need to copy FROM address. */
> int Num2Copy = FromLen;
>
> if (pDevice->SizeOfData < Num2Copy)
> {
> Retval = HEIE_BUFFER_TOO_SMALL;
> Num2Copy = pDevice->SizeOfData;
> }
>
> memcpy(pDevice->pData, &FromAddr, Num2Copy);
> }
> }
> else
> {
> NumBytes = recv(sock, (char *) pResponse, *pResponseSize, 0);
> }
>
> if (NumBytes == SOCKET_ERROR)
> {
> /* Check to see if the error is WSAWOULDBLOCK. */
> int Error = WSAGetLastError();
>
> if (Error != WSAEWOULDBLOCK)
> {
> *pResponseSize = 0;
> Retval = Error;
> }
> else
> {
> Retval = HEIE_NO_RESPONSE;
> }
> }
> else
> {
> (*pResponseSize) = NumBytes;
> }
>
> break;
> }
> case HEIT_OTHER_TRANSPORT:
> {
> /*
> ** TODO_FOR_OTHER_SYSTEM
> ** Receive a packet for the given device into the buffer pResponse.
> ** *pResponseSize indicates the length of the pResponse buffer.
> ** If pDevice->UseBroadcast && pDevice->pData,
> ** then we need to copy the FROM address into pDevice->pData.
> ** pDevice->SizeOfData tells how long the buffer pDevice->pData is.
> ** Store the number of bytes received in (*pResponseSize).
> ** Don't return HEIE_UNSUPPORTED_TRANSPORT
> */
> return HEIE_UNSUPPORTED_TRANSPORT;
> }
>
> default:
> return HEIE_UNSUPPORTED_TRANSPORT;
> }
>
> return Retval;
> }
>
>
> /*
> ** This is the code for sending the given packet for the given device.
> ** pPacket is the pointer to the actual packet data, and PacketSize
> is the
> ** number of bytes in the packet to be sent.
> **
> ** RETURNS: 0 on success
> ** non-zero on error.
> */
> int HEIISendPacket(HEIDevice *pDevice, BYTE *pPacket, WORD PacketSize)
> {
> switch (pDevice->_pTransport->Transport)
> {
> case HEIT_WINSOCK: /* Send packet of type HEIT_WINSOCK */
> {
> /* WinSock Transport. */
> SOCKET sock = (SOCKET) pDevice->_dwParam;
> if (pDevice->UseBroadcast)
> {
> /* Initialize remote address */
> struct sockaddr *pRemAddr = (struct sockaddr *) NULL;
> int SizeRemAddr = 0;
> if (pDevice->_pTransport->Protocol == HEIP_IP)
> {
> static struct sockaddr_in RemAddr;
>
> RemAddr.sin_family = AF_INET;
> RemAddr.sin_port = PORT_ID;
> RemAddr.sin_addr.s_addr = INADDR_BROADCAST;
>
> pRemAddr = (struct sockaddr *) &RemAddr;
> SizeRemAddr = sizeof(RemAddr);
> }
> else if (pDevice->_pTransport->Protocol == HEIP_IPX)
> {
> static SOCKADDR_IPX RemAddr;
>
> RemAddr.sa_family = AF_IPX;
> memset(RemAddr.sa_netnum, 0, 4);
> memset(RemAddr.sa_nodenum, 0xFF, 6);
> RemAddr.sa_socket = PORT_ID;
> if (pDevice->_pTransport->pSourceAddress)
> memcpy(RemAddr.sa_netnum, pDevice->_pTransport->pSourceAddress-
> >AddressIPX.Netnum, 4);
> /*memcpy(RemAddr.sa_netnum, &pDevice->_pTransport-
> >NetworkAddress, 4);*/
>
> pRemAddr = (struct sockaddr *) &RemAddr;
> SizeRemAddr = sizeof(RemAddr);
> }
> if (sendto(sock, (char *) pPacket, PacketSize, 0, pRemAddr,
> SizeRemAddr) == SOCKET_ERROR)
> return WSAGetLastError();
> }
> else
> {
> if (send(sock, (char *) pPacket, PacketSize, 0) == SOCKET_ERROR)
> return WSAGetLastError();
> }
>
> return HEIE_NULL;
> }
> case HEIT_OTHER_TRANSPORT:
> {
> /*
> ** TODO_FOR_OTHER_SYSTEM
> ** Send a packet to the given device.
> ** If pDevice->UseBroadcast, then we need to broadcast the packet.
> ** Don't return HEIE_UNSUPPORTED_TRANSPORT
> */
> return HEIE_UNSUPPORTED_TRANSPORT;
> }
>
> default:
> return HEIE_UNSUPPORTED_TRANSPORT;
> }
> }
>
>
>
>
>
> <HEISrc.zip>_______________________________________________
> Lista de correo Cconclase Cconclase en listas.conclase.net
> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
Más información sobre la lista de distribución Cconclase