//============================================================================
/// Summary  : Edgetech FSDW Commands
/// Filename : EdgetechFSDWCommands.cc
/// Author   : Reed Christenson, reed@bluefinrobotics.com
/// Project  : Edgetech FSDW Driver
/// Revision : 0.0
/// Created  : 2002.04.15
/// Modified : 2002.04.15
//============================================================================
// From RESON SeaBat 7k DATA FORMAT INTERFACE CONTROL DOCUMENT 
//      Draft Version 0.32

// RGH March 12, 2004 - Assume Phase 2 and later, uncomment fields
//

#include <sys/timeb.h>

#include "EdgetechFSDWCommands.h"

#define DEBUG_OFF False 

EdgetechFSDWCommands::EdgetechFSDWCommands()
{
    // Set some defaults in the command structure.
    cmdStruct.sizeNetworkFrame = sizeof(EdgetechFSDWNetworkFrame);
    cmdStruct.sizeNetworkFrameAndData = 0;
    cmdStruct.sizeDataRecordFrame = sizeof(EdgetechFSDWDataRecordFrame);
    cmdStruct.sizeDataRecordFrameAndData = 0;
    cmdStruct.sizePlcCommandFrame = sizeof(EdgetechFSDWPayloadControllerCommand);
    cmdStruct.sizePlcCommandFrameAndData = 0;
    cmdStruct.nfPtr = NULL;
    cmdStruct.drfPtr = NULL;
    cmdStruct.plccfPtr = NULL;
    cmdStruct.responsePtr = NULL;
    //
    EdgetechFSDWCommands::initPlcCommandFrame();
    EdgetechFSDWCommands::initDataRecordFrame();
    EdgetechFSDWCommands::initNetworkFrame();
}

EdgetechFSDWCommands::~EdgetechFSDWCommands()
{
    // Clear up pointers and acquired memory.

    clean(cmdStruct.nfPtr);
    clean(cmdStruct.drfPtr);
    clean(cmdStruct.plccfPtr);
    clean(cmdStruct.responsePtr);
}

// Setup some default values for NetworkFrame structure.
void EdgetechFSDWCommands::initNetworkFrame()
{
  Boolean debug = DEBUG_OFF;

    U32 size;
    cmdStruct.networkFrame.version = PLC_PROTOCOL_VERSION;
    cmdStruct.networkFrame.offset = cmdStruct.sizeNetworkFrame;
    cmdStruct.networkFrame.totalPackets = 1;
    cmdStruct.networkFrame.totalRecords = 1; // uncommented
    cmdStruct.networkFrame.transmissionIdentifier = 0; //uncommented
    cmdStruct.networkFrame.packetSize = 0;
    cmdStruct.networkFrame.totalSize = 0; // uncommented
    cmdStruct.networkFrame.sequenceNumber = 0;

    // New for ICD V0.53
    cmdStruct.networkFrame.destDeviceIdentifier = 0;
    cmdStruct.networkFrame.destEnumerator = 0;
    cmdStruct.networkFrame.srcEnumerator = 0;
    cmdStruct.networkFrame.srcDeviceIdentifier = 0;

    dprintf("Size of network frame structure is %d\n", sizeof(cmdStruct.networkFrame));
}


// Set Network Frame.
int EdgetechFSDWCommands::setNetworkFrame(U16 transmissionIdentifier,
                                       U32 totalPackets,
                                       U16 totalRecords,
                                       U32 totalSize,
                                       U32 sequenceNumber)
{
  Boolean debug = DEBUG_OFF;
    unsigned int index = 0, size = 0;
//     //unsigned int sizeFullMessage, sizeNetworkFrame, sizeRecordFrame;

    //Syslog::write("DBG: setNetworkFrame...");

    if(cmdStruct.drfPtr == NULL)
    {
        Syslog::write("ERROR: No message provided for Edgetech FSDW Network Frame!");
        return(-1);
    }

    if(cmdStruct.nfPtr != NULL)
    {
        // Make sure we don't leak memory!
        clean(cmdStruct.nfPtr );
    }
    cmdStruct.sizeNetworkFrameAndData =
        cmdStruct.sizeDataRecordFrameAndData + cmdStruct.sizeNetworkFrame;

    cmdStruct.nfPtr = new unsigned char[cmdStruct.sizeNetworkFrameAndData];
    if(cmdStruct.nfPtr == NULL)
    {
	Syslog::write("setNetworkFrame: Unable to allocate space for Network Frame And Message!");
	return(-1);
    }
    memset(cmdStruct.nfPtr, 0, cmdStruct.sizeNetworkFrameAndData);

    size = 0;
    // U16 version (set in constructor)
    size += sizeU16;
    // U16 offset (set in constructor)
    size += sizeU16;
    // U32 totalPackets
    cmdStruct.networkFrame.totalPackets = totalPackets;
    size += sizeU32;
    // U16 totalRecords
    cmdStruct.networkFrame.totalRecords = totalRecords;
    size += sizeU16;
    // U16 trasmissionIdentifier
    cmdStruct.networkFrame.transmissionIdentifier = transmissionIdentifier;
    size += sizeU16;
    // U32 packetSize
    cmdStruct.networkFrame.packetSize = cmdStruct.sizeNetworkFrameAndData;
    size += sizeU32;
    // U32 totalSize
    if(totalPackets > 1)
    {
       cmdStruct.networkFrame.totalSize = totalSize;
    }
    else
    {
       cmdStruct.networkFrame.totalSize = cmdStruct.sizeDataRecordFrameAndData;
    }
    size += sizeU32;
    // U32 sequenceNumber
    cmdStruct.networkFrame.sequenceNumber = sequenceNumber;
    size += sizeU32;

    cmdStruct.networkFrame.destDeviceIdentifier = 0;
    size += sizeU32;
    cmdStruct.networkFrame.destEnumerator = 0;
    size += sizeU16;
    cmdStruct.networkFrame.srcEnumerator = 0;
    size += sizeU16;
    cmdStruct.networkFrame.srcDeviceIdentifier = 0;
    size += sizeU32;

    dprintf("Serializing NF, %d bytes...\n",size);
    index = 0;
    memcpy(&cmdStruct.nfPtr[index], &cmdStruct.networkFrame.version, size);
    index += size;
    
    // DYNAMIC DATA
    dprintf("Adding DRF to NF, index at %d...\n",index);
    memcpy(&cmdStruct.nfPtr[index], &cmdStruct.drfPtr[0], cmdStruct.sizeDataRecordFrameAndData);
    //index += cmdStruct.sizeRecordFrameAndData;
    
    return(0);
}

// Display Record Frame.
void EdgetechFSDWCommands::displayNetworkFrame(U32 showFrame) const
{
    U32 size;
    // This output can be interupted by other processes also using Syslog::write().
    Syslog::write("_____Reson TCP and UDP Network Frame (NF)_____");
    Syslog::write("                version = %d",cmdStruct.networkFrame.version);
    Syslog::write("                 offset = %d",cmdStruct.networkFrame.offset);
    Syslog::write("          total packets = %d",cmdStruct.networkFrame.totalPackets);
    Syslog::write("          total records = %d",cmdStruct.networkFrame.totalRecords);
    Syslog::write("transmission identifier = %d",cmdStruct.networkFrame.transmissionIdentifier);
    Syslog::write("            packet size = %d",cmdStruct.networkFrame.packetSize);
    Syslog::write("             total size = %d",cmdStruct.networkFrame.totalSize);
    Syslog::write("        sequence number = %d",cmdStruct.networkFrame.sequenceNumber);
    Syslog::write("         dest Device Id = %d",cmdStruct.networkFrame.destDeviceIdentifier);
    Syslog::write("        dest Enumerator = %d",cmdStruct.networkFrame.destEnumerator);
    Syslog::write("         src Enumerator = %d",cmdStruct.networkFrame.srcEnumerator);
    Syslog::write("          src Device Id = %d",cmdStruct.networkFrame.srcDeviceIdentifier);

    if(cmdStruct.nfPtr != NULL)
    {
	switch(showFrame)
	{
	case ShowFrameOnly:
	    size = cmdStruct.sizeNetworkFrame;
	    EdgetechFSDWCommands::showRawFrame(cmdStruct.nfPtr, size);
	    break;
	case ShowFrameAndData:
	    size = cmdStruct.sizeNetworkFrameAndData;
	    EdgetechFSDWCommands::showRawFrame(cmdStruct.nfPtr, size);
	    break;
	case ShowDataOnly:
	    size = cmdStruct.sizeNetworkFrameAndData - cmdStruct.sizeNetworkFrame;
	    EdgetechFSDWCommands::showRawFrame(&cmdStruct.nfPtr[cmdStruct.sizeNetworkFrame],
					    size);
	    break;
	case None:
	default:
	    size = 0;
	}
    }
}

// Setup some default values for DataRecordFrame structure.
void EdgetechFSDWCommands::initDataRecordFrame()
{
    Boolean debug = DEBUG_OFF;
    // Setup some default values for DataRecordFrame structure.
    cmdStruct.dataRecordFrame.version = PLC_PROTOCOL_VERSION;
    // Offset doesn't include version,   offset,  checksum.
    cmdStruct.dataRecordFrame.offset = cmdStruct.sizeDataRecordFrame - sizeU16 - sizeU16 - sizeU32;
    cmdStruct.dataRecordFrame.syncPattern = DATA_RECORD_FRAME_SYNC_PATTERN;
    cmdStruct.dataRecordFrame.size = 0;
    cmdStruct.dataRecordFrame.optionalDataOffset = 0;
    cmdStruct.dataRecordFrame.optionalDataIdentifier = 0;
    EdgetechFSDWCommands::set7kTime(&cmdStruct.dataRecordFrame.time7k);
    cmdStruct.dataRecordFrame.recordVersion = PLC_RECORD_VERSION;
    cmdStruct.dataRecordFrame.recordTypeIdentifier = 0;
    cmdStruct.dataRecordFrame.deviceIdentifier = 0;

    // Changed for ICD V0.53
    cmdStruct.dataRecordFrame.reserved1 = 0;
    cmdStruct.dataRecordFrame.systemEnumerator = 0;
    cmdStruct.dataRecordFrame.sequentialRecordCounter = 0;
    cmdStruct.dataRecordFrame.flags = 0;
    cmdStruct.dataRecordFrame.reserved2 = 0;
    cmdStruct.dataRecordFrame.reserved3 = 0;
    cmdStruct.dataRecordFrame.totalRecords = 0;
    cmdStruct.dataRecordFrame.fragmentNumber = 0;
    cmdStruct.dataRecordFrame.version = PLC_PROTOCOL_VERSION;


    cmdStruct.dataRecordFrame.checksum = 0;
    dprintf("Size of Data Record frame structure is %d\n", sizeof(cmdStruct.dataRecordFrame));
}

// Set Data Record Frame.
int EdgetechFSDWCommands::setDataRecordFrame( U32 recordTypeIdentifier,
					   U32 deviceIdentifier,
					   U16 subsystemIdentifier,
					   U16 systemEnumerator,
					   U32 dataSetNumber,
					   TimeIF::TimeSpec *setTime,
					   U32 checksum,
					   U16 flags,
					   U32 sequentialRecordCounter,
					   I64 pointerRecordPrevious,
					   I64 pointerRecordNext,
					   U32 optionalDataOffset,
					   U32 optionalDataIdentifier,
					   U16 recVersion,
					   U16 reserved1)
{
  Boolean debug = DEBUG_OFF;
    unsigned int index, size;

    if(cmdStruct.plccfPtr == NULL)
    {
	Syslog::write("ERROR: setDataRecordFrame: No message provided for Data Record Frame!");
	return(-1);
    }

    if(cmdStruct.drfPtr != NULL)
    {
	// Make sure we don't leak memory!
	delete[] cmdStruct.drfPtr;
	cmdStruct.drfPtr = NULL;
    }
    cmdStruct.sizeDataRecordFrameAndData =
	cmdStruct.sizePlcCommandFrameAndData + cmdStruct.sizeDataRecordFrame;

    dprintf("Size of DRF and data = %d\n", cmdStruct.sizeDataRecordFrameAndData);
    cmdStruct.drfPtr = new unsigned char[cmdStruct.sizeDataRecordFrameAndData];
    if(cmdStruct.drfPtr == NULL)
    {
	Syslog::write("setDataRecordFrame: Unable to allocate space for Data Record Frame And Data!");
	return(-1);
    }
    memset(cmdStruct.drfPtr, 0, cmdStruct.sizeDataRecordFrameAndData);

    index = 0;
    size = 0;
    // version (set in constructor) U16
    size += sizeU16;
    // offset (set in constructor) U16
    size += sizeU16;
    // syncPattern (set in constructor) U32
    size += sizeU32;
    // size U32
    cmdStruct.dataRecordFrame.size = cmdStruct.sizeDataRecordFrameAndData;
    size += sizeU32;
    // optionalDataOffset U32
    cmdStruct.dataRecordFrame.optionalDataOffset = optionalDataOffset;
    size += sizeU32;
    // optionalDataIdentifier U32
    cmdStruct.dataRecordFrame.optionalDataIdentifier = optionalDataIdentifier;
    size += sizeU32;
    // time7k T7K
    EdgetechFSDWCommands::set7kTime(&cmdStruct.dataRecordFrame.time7k, setTime);
    size += sizeT7K;
    // reserved U16
    cmdStruct.dataRecordFrame.recordVersion = recVersion;
    size += sizeU16;
    // recordTypeIdentifier U32
    cmdStruct.dataRecordFrame.recordTypeIdentifier = recordTypeIdentifier;
    size += sizeU32;
    // deviceIdentifier U32
    cmdStruct.dataRecordFrame.deviceIdentifier = deviceIdentifier;
    size += sizeU32;


    // subsystemIdentifier U16
    cmdStruct.dataRecordFrame.reserved1 = reserved1;
    size += sizeU16;
    // systemEnumerator U16
    cmdStruct.dataRecordFrame.systemEnumerator = systemEnumerator;
    size += sizeU16;
    // sequentialRecordCounter U32
    cmdStruct.dataRecordFrame.sequentialRecordCounter = sequentialRecordCounter;
    size += sizeU32;
    // flags U16
    cmdStruct.dataRecordFrame.flags = flags;
    size += sizeU16;
    // reserved U16
    cmdStruct.dataRecordFrame.reserved2 = 0;
    size += sizeU16;
    // reserved U16
    cmdStruct.dataRecordFrame.reserved3 = 0;
    size += sizeU32;

    cmdStruct.dataRecordFrame.totalRecords = 0;
    size += sizeU32;

    cmdStruct.dataRecordFrame.fragmentNumber = 0;
    size += sizeU32;

    dprintf("Serializing dataRecordFrame, %d bytes...\n", size);
    index = 0;
    // Copy everything up to this point.
    memcpy(&cmdStruct.drfPtr[index], &cmdStruct.dataRecordFrame.version, size);
    index += size;

    // DATA SECTION
    dprintf("Serializing command frame and data, %d bytes at %d...\n",
	   cmdStruct.sizePlcCommandFrameAndData, index);
    memcpy(&cmdStruct.drfPtr[index], cmdStruct.plccfPtr, cmdStruct.sizePlcCommandFrameAndData);
    index += cmdStruct.sizePlcCommandFrameAndData;

    dprintf("Serializing checksum, %d bytes at %d...\n", sizeU32, index);
    cmdStruct.dataRecordFrame.checksum = checksum;
    memcpy(&cmdStruct.drfPtr[index], &cmdStruct.dataRecordFrame.checksum, sizeU32);
    index += sizeU32;

    return(0);
};

// Set Message Data Record Frame.
int EdgetechFSDWCommands::setMsgDataRecordFrame( U32 recordTypeIdentifier,
					      void* messageData,
					      U32 messageDataSize)
{
  Boolean debug = DEBUG_OFF;
    unsigned int index, size;

    cmdStruct.sizeDataRecordFrameAndData = messageDataSize +
                                                 cmdStruct.sizeDataRecordFrame;

    dprintf("Size of DRF and data = %d\n", cmdStruct.sizeDataRecordFrameAndData);
    cmdStruct.drfPtr = new unsigned char[cmdStruct.sizeDataRecordFrameAndData];
    if(cmdStruct.drfPtr == NULL)
    {
	Syslog::write("setMsgDataRecordFrame: Unable to allocate space for Data Record Frame And Data!");
	return(-1);
    }
    memset(cmdStruct.drfPtr, 0, cmdStruct.sizeDataRecordFrameAndData);

    index = 0;
    size = 0;
    // version (set in constructor) U16
    size += sizeU16;
    // offset (set in constructor) U16
    size += sizeU16;
    // syncPattern (set in constructor) U32
    size += sizeU32;
    // size U32
    cmdStruct.dataRecordFrame.size = cmdStruct.sizeDataRecordFrameAndData;
    size += sizeU32;
    // optionalDataOffset U32
    size += sizeU32;
    // optionalDataIdentifier U32
    size += sizeU32;
    // time7k T7K
    EdgetechFSDWCommands::set7kTime(&cmdStruct.dataRecordFrame.time7k, 0);
    size += sizeT7K;
    // reserved U16
    size += sizeU16;
    // recordTypeIdentifier U32
    cmdStruct.dataRecordFrame.recordTypeIdentifier = recordTypeIdentifier;
    size += sizeU32;
    // deviceIdentifier U32
    cmdStruct.dataRecordFrame.deviceIdentifier = 0;
    size += sizeU32;
    // subsystemIdentifier U16
    size += sizeU16;
    // systemEnumerator U16
    size += sizeU16;
    // dataSetNumber U32
    size += sizeU32;
    // sequentialRecordCounter U32
    size += sizeU32;
    // pointerRecordPrevious (set in constructor) I64
    size += sizeI64;
    // pointerRecordNext (set in constructor) I64
    size += sizeI64;
    // flags U16
    size += sizeU16;
    // reserved U16
    size += sizeU16;

    dprintf("Serializing dataRecordFrame, %d bytes...\n", size);
    index = 0;
    // Copy everything up to this point.
    memcpy(&cmdStruct.drfPtr[index], &cmdStruct.dataRecordFrame.version, size);
    index += size;

    // DATA SECTION
    dprintf("Serializing message data, %d bytes at %d...\n",
	   messageDataSize, index);
    memcpy(&cmdStruct.drfPtr[index], messageData, messageDataSize);
    index += messageDataSize;

    dprintf("Serializing checksum, %d bytes at %d...\n", sizeU32, index);
    memcpy(&cmdStruct.drfPtr[index], &cmdStruct.dataRecordFrame.checksum, sizeU32);
    index += sizeU32;

    return(0);
};

// Display Data Record Frame.
void EdgetechFSDWCommands::displayDataRecordFrame(U32 showFrame) const
{
    U32 size;
    // This output can be interupted by other processes also using Syslog::write().
    Syslog::write("_____Data Record Frame (DRF)_____");
    Syslog::write("                  version = %d",cmdStruct.dataRecordFrame.version);
    Syslog::write("                   offset = %d",cmdStruct.dataRecordFrame.offset);
    Syslog::write("             sync pattern = 0x%08X",cmdStruct.dataRecordFrame.syncPattern);    
    Syslog::write("                     size = %d",cmdStruct.dataRecordFrame.size);    
    Syslog::write("     optional data offset = %d",cmdStruct.dataRecordFrame.optionalDataOffset);
    Syslog::write(" optional data identifier = %d",cmdStruct.dataRecordFrame.optionalDataIdentifier);
    Syslog::write("                  7K time = %4d.%03d %02d:%02d:%9.6f",
		  cmdStruct.dataRecordFrame.time7k.year,
		  cmdStruct.dataRecordFrame.time7k.day,
		  cmdStruct.dataRecordFrame.time7k.hours,
		  cmdStruct.dataRecordFrame.time7k.minutes,
		  cmdStruct.dataRecordFrame.time7k.seconds);
    Syslog::write("           record version = %d",cmdStruct.dataRecordFrame.recordVersion);
    Syslog::write("   record type identifier = %d",cmdStruct.dataRecordFrame.recordTypeIdentifier);
    Syslog::write("        device identifier = %d",cmdStruct.dataRecordFrame.deviceIdentifier); 
    Syslog::write("                reserved1 = %d",cmdStruct.dataRecordFrame.reserved1);
    Syslog::write("        system enumerator = %d",cmdStruct.dataRecordFrame.systemEnumerator);
    Syslog::write("sequential record counter = %d",cmdStruct.dataRecordFrame.sequentialRecordCounter);
    Syslog::write("                    flags = %d",cmdStruct.dataRecordFrame.flags);
    Syslog::write("                reserved2 = %d",cmdStruct.dataRecordFrame.reserved2);
    Syslog::write("                reserved3 = %d",cmdStruct.dataRecordFrame.reserved3);
    Syslog::write("            total records = %d",cmdStruct.dataRecordFrame.totalRecords);
    Syslog::write("          fragment number = %d",cmdStruct.dataRecordFrame.fragmentNumber);
    Syslog::write("                 checksum = %d",cmdStruct.dataRecordFrame.checksum);

    if(cmdStruct.drfPtr != NULL)
    {
	switch(showFrame)
	{
	case ShowFrameOnly:
	    size = cmdStruct.sizeDataRecordFrame;
	    EdgetechFSDWCommands::showRawFrame(cmdStruct.drfPtr, size);
	    break;
	case ShowFrameAndData:
	    size = cmdStruct.sizeDataRecordFrameAndData;
	    EdgetechFSDWCommands::showRawFrame(cmdStruct.drfPtr, size);
	    break;
	case ShowDataOnly:
	    size = cmdStruct.sizeDataRecordFrameAndData - cmdStruct.sizeDataRecordFrame - sizeU32;
	    EdgetechFSDWCommands::showRawFrame(&cmdStruct.drfPtr[cmdStruct.sizeDataRecordFrame],
					    size);
	case None:
	default:
	    size = 0;
	}
    }
};


// Init Payload Controller Command Frame
void EdgetechFSDWCommands::initPlcCommandFrame()
{
  Boolean debug = DEBUG_OFF;
    cmdStruct.plcCommandFrame.sensorIndex = -1;
    cmdStruct.plcCommandFrame.commandID = 0;
    cmdStruct.plcCommandFrame.action = 0;
    cmdStruct.plcCommandFrame.commandBytesToFollow = 0;
    dprintf("Size of command frame structure is %d\n", sizeof(cmdStruct.plcCommandFrame));
}



// Set Payload Controller Command Frame
int EdgetechFSDWCommands::setPlcCommandFrame(U32 sensorIndex,
					  U32 commandID,
					  U32 action,
					  char *command)
{
  Boolean debug = DEBUG_OFF;
    unsigned int size = 0, index = 0;
    //char buffer[16];

    if(command != NULL)
    {
	//sprintf(&buffer[0],command, param1);
	cmdStruct.plcCommandFrame.commandBytesToFollow = strlen(command);
    }
    else
    {
	cmdStruct.plcCommandFrame.commandBytesToFollow = 0;
    }

    // Check to see if there is alread a command pointer.
    if(cmdStruct.plccfPtr != NULL)
    {
	// Make sure we don't leak memory!
	//clean(cmdStruct.plccfPtr);
	delete[] cmdStruct.plccfPtr;
	cmdStruct.plccfPtr = NULL;
    }
    cmdStruct.sizePlcCommandFrameAndData =
	cmdStruct.sizePlcCommandFrame + cmdStruct.plcCommandFrame.commandBytesToFollow;
    cmdStruct.plccfPtr = new unsigned char[cmdStruct.sizePlcCommandFrameAndData];
    if(cmdStruct.plccfPtr == NULL)
    {
	Syslog::write("Unable to allocate memory for Payload Computer Command Frame!");
	return(-1);
    }
    memset(cmdStruct.plccfPtr, 0, cmdStruct.sizePlcCommandFrameAndData);

    // U32 fillerField
    //cmdStruct.plcCommandFrame.fillerField = 0;
    //size = sizeU32;
    // U32 sensorIndex
    cmdStruct.plcCommandFrame.sensorIndex = sensorIndex;
    size += sizeU32;
    // U32 hostID
    //cmdStruct.plcCommandFrame.hostID = hostID;
    //size += sizeU32;
    // U32 commandID
    cmdStruct.plcCommandFrame.commandID = commandID;
    size += sizeU32;
    // U32 action
    cmdStruct.plcCommandFrame.action = action;
    size += sizeU32;  
    // sizeU8 to follow ICD V 0.27
    //cmdStruct.plcCommandFrame.commandBytesToFollow calculated above.
    size += sizeU32;

    index = 0;
    dprintf("Serializing plcCommandFrame, %d bytes...\n", size);
    memcpy(&cmdStruct.plccfPtr[index], &cmdStruct.plcCommandFrame.sensorIndex, size);
    index += size;

    // Handle dynamic data here.
    if(cmdStruct.plcCommandFrame.commandBytesToFollow > 0)
    {
        dprintf("Serializing commandBytes, %d bytes at %d...\n",
	       cmdStruct.plcCommandFrame.commandBytesToFollow, index);
	memcpy(&cmdStruct.plccfPtr[index],&command[0],cmdStruct.plcCommandFrame.commandBytesToFollow);
    }

    return(0);
}


// int EdgetechFSDWCommands::setPlcCommandFrame(U32 sensorIndex,
// 					  U32 commandID,
// 					  U32 action,
// 					  char *command,
// 					  U32 parameter)
// {
//     char buffer[32];

//     if(command != NULL)
//     {
// 	sprintf(&buffer[0],command,parameter);
// 	EdgetechFSDWCommands::setPlcCommandFrame(sensorIndex,
// 					      commandID,
// 					      action,
// 					      &buffer[0]);
//     }
//     return(0);
// }


// Display Payload Controller Command Frame
// RECORD TYPE # 1100 'Payload Controller Command' (page 34 of 44, Revision 0.27/PMO)
void EdgetechFSDWCommands::displayPlcCommandFrame(U32 showFrame)
{
    U32 size;
    Syslog::write("____Payload Computer Command Frame_____");
    Syslog::write("         sensorIndex = %d", cmdStruct.plcCommandFrame.sensorIndex);
    Syslog::write("           commandID = %d", cmdStruct.plcCommandFrame.commandID);
    Syslog::write("              action = %d", cmdStruct.plcCommandFrame.action);
    Syslog::write("commandBytesToFollow = %d", cmdStruct.plcCommandFrame.commandBytesToFollow);
    Syslog::write("...data follows...");
    if(cmdStruct.drfPtr != NULL)
    {
	switch(showFrame)
	{
	case ShowFrameOnly:
	    size = cmdStruct.sizePlcCommandFrame;
	    EdgetechFSDWCommands::showRawFrame(cmdStruct.plccfPtr, size);
	    break;
	case ShowFrameAndData:
	    size = cmdStruct.sizePlcCommandFrameAndData;
	    EdgetechFSDWCommands::showRawFrame(cmdStruct.plccfPtr, size);
	    break;
	case ShowDataOnly:
	    size = cmdStruct.sizePlcCommandFrameAndData - cmdStruct.sizePlcCommandFrame;
	    EdgetechFSDWCommands::showRawFrame(&cmdStruct.plccfPtr[cmdStruct.sizePlcCommandFrame],
					    size);
	case None:
	default:
	    size = 0;
	}
    }
}

// Set Reson 7k Time either (current time or the time in setTime).
void EdgetechFSDWCommands::set7kTime(T7K *time7k, TimeIF::TimeSpec *setTime)
{
  long sec = 0;
  if (setTime) {
    sec = setTime->seconds;
  }
  else {
    time(&sec);
  }

  // Get the system time and populate the T7K structure
  //
  struct tm *fullTime = gmtime(&sec);
  struct timeb tmb;
  ftime(&tmb);

  time7k->year    = fullTime->tm_year + 1900;
  time7k->day     = fullTime->tm_yday + 1;
  time7k->seconds = (float)fullTime->tm_sec + (float)tmb.millitm/1000.;
  time7k->minutes = fullTime->tm_min;
  time7k->hours   = fullTime->tm_hour;
}

void EdgetechFSDWCommands::showRawFrame(BYTE *framePtr, U32 size) const
{
    BYTE c;
    U32 i;

    if(framePtr != NULL)
    {
    	for(i = 0; i < size;)
	    {
	      c = framePtr[i++];
	      printf("%02X:",c);
	      if ((i % 8) == 0) printf("\n");
	    }
	    if(size > 0) printf("\nsize = %u\n", size);
    }
}
