//
//  Copyright © 2004, RESON Inc. All Rights Reserved.
//
//  No part of this file may be reproduced or transmitted in any form or by
//  any means, electronic or mechanical, including photocopy, recording, or
//  information storage or retrieval system, without permission in writing
//  from RESON Inc.
//
//  Filename:   C7kProtocolVersion.h
//
//  Project:    6046.
//
//  Author(s):  W. Arcus
//
//  Purpose:    Defines the 7k format header versions and defintions thereof.
//
//  Notes:      DRF and NF are defined seperately so that should the policy of
//              mandating them be the same version be relaxed, the code will
//              be largely unaffected.
//

#if !defined(AFX_7KPROTOCOL_H__5E04A08D_5750_47e5_81A7_65D031AC543B__INCLUDED_)
#define AFX_7KPROTOCOL_H__5E04A08D_5750_47e5_81A7_65D031AC543B__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

///////////////////////////////////////////////////////////////////////////////
// Constants etc.

#if defined ( PROTOCOL_VERSION_7K )
#error  7k DATA PROTOCOL VERSION IS SPECIFIED ELSEWHERE !!!
#endif

#if defined ( DRF_VERSION_7K )
#error  7k DATA RECORD FRAME VERSION NUMBER IS SPECIFIED ELSEWHERE !!!
#endif

#if defined ( NF_VERSION_7K )
#error  7k NETWORK FRAME VERSION NUMBER IS SPECIFIED ELSEWHERE !!!
#endif

// Define the protocol version here and enforce the policy that the two headers need 
// to be the same version.

#define PROTOCOL_VERSION_7K                     5                       // As of DFD 0.54.
#define RECORDS_VERSION                         1                       // New field as of DFD 0.54 (protocol version 5).
#define DRF_VERSION_7K                          PROTOCOL_VERSION_7K
#define NF_VERSION_7K                           PROTOCOL_VERSION_7K

#if ( DRF_VERSION_7K != NF_VERSION_7K )
#error  7k HEADER MISMATCH !!!
#endif

typedef unsigned long                           Checksum7k_t;
#define Checksum7kSize_m()                      sizeof( Checksum7k_t )

const unsigned short                            un7kDataProtocolVersion_c   =   DRF_VERSION_7K;
const unsigned short                            un7kSocketProtocolVersion_c =   NF_VERSION_7K;
const unsigned short                            un7kRecordsVersion_c        =   RECORDS_VERSION;

#pragma pack( push, PROTOCOLVERSION7K_H_PACK, 1 )               // Set single byte alignment.

///////////////////////////////////////////////////////////////////////////////
// 7k time definition.

typedef struct tagTIME7K
{
    unsigned short  m_unYear;                                   // Year                 u16 0 - 65535
    unsigned short  m_unDay;                                    // Day                  u16 1 - 366

    float           m_fSeconds;                                 // Seconds              f32 0.000000 - 59.000000

    unsigned char   m_ucHours;                                  // Hours                u8  0 - 23
    unsigned char   m_ucMinutes;                                // Minutes              u8  0 - 59

    bool IsValid( void ) const                                  // Header validity check.
    {
        return ( ( m_unDay     >= 1    ) &&
                 ( m_unDay     <= 366  ) &&
                 ( m_fSeconds  >= 0.0f ) &&
                 ( m_fSeconds  < 60.0f ) &&
                 ( m_ucHours   <= 23   ) &&
                 ( m_ucMinutes <= 59   )  );
    }

    unsigned long DynamicBytes( void ) const                    // Dynamic bytes to follow this record
    {
        return 0UL;                                             // ... not relevant to this header.
    }
}
TIME7K, *PTIME7K;

///////////////////////////////////////////////////////////////////////////////
// Data Record Frame header definitions.

struct tagRECORDHEADER7KVERSION1
{
    unsigned short  m_unVersion;                                // Version              u16 Version of this frame (e.g.: 1, 2, …)
    unsigned short  m_unOffset;                                 // Offset               u16 Offset in bytes from the start of the sync pattern to the start of the DATA SECTION. This allows for expansion of the header whilst maintaining backward compatibility.

    unsigned long   m_ulSyncPattern;                            // Sync pattern         u32 0x0000FFFF
    unsigned long   m_ulSize;                                   // Size                 u32 Size in bytes of this record from the start of the version field to the end of the Checksum. It includes the embedded data size.
    unsigned long   m_ulOffsetToOptionalData;                   // Data offset          u32 Offset in bytes to optional data field from start of record. Zero implies no optional data.
    unsigned long   m_ulOptionalDataIdentifier;                 // Data idenfitifer     u32 Identifier for optional data field. Zero for no optional field. This identifier is described with each record type.

    TIME7K          m_sTime7k;                                  // 7KTIME               u8*10   UTC.

    unsigned long   m_ulRecordType;                             // Record type          u32 Unique identifier of indicating the type of data embedded in this record.
    unsigned long   m_ulDeviceId;                               // Device identifier    u32 Identifier of the device that this data pertains.
    unsigned long   m_ulSubsystemId;                            // Subsystem identifier u32 Identifier for the device subsystem
    unsigned long   m_ulDataSetNumber;                          // Data set             u32 Data set number.
    unsigned long   m_ulRecordNumber;                           // Record count         u32 Sequential record counter.

    __int64         m_i64PreviousRecord;                        // Previous record      i64 Pointer to the previous record of the same type (in bytes from start of file). This is an optional field for files and shall be -1 if not used.
    __int64         m_i64NextRecord;                            // Next record          i64 Pointer to the next record of the same type in bytes from start of file. This is an optional field for files and shall be -1 if not used.

    unsigned short  m_unFlags;                                  // Flags                u16 BIT FIELD: Bit 1 - Valid Checksum
                                                                
    // Following this header is:                                     
    // DATA SECTION                                                                     xx  Dynamic Record type specific data.
    // Checksum                                                                         u32 Sum of bytes in data section (optional, depends on bit 1 of Flags field).

    static unsigned long Size( void )
    {
        return sizeof( struct tagRECORDHEADER7KVERSION1 );
    }

    bool IsValid( void ) const
    {
        return ( ( m_unVersion          >   0          ) &&
                 ( m_ulSyncPattern      ==  0x0000ffff ) &&
                 ( m_ulSize             >   Size()     ) &&
                 ( m_sTime7k.IsValid()                 )  );
    }

    unsigned long DynamicBytes( void ) const
    {
        return ( m_ulSize - ( Size() + Checksum7kSize_m() ) );
    }
};

struct tagRECORDHEADER7KVERSION2
{
    unsigned short  m_unVersion;                                // Version              u16 Version of this frame (e.g.: 1, 2, …)
    unsigned short  m_unOffset;                                 // Offset               u16 Offset in bytes from the start of the sync pattern to the start of the DATA SECTION. This allows for expansion of the header whilst maintaining backward compatibility.

    unsigned long   m_ulSyncPattern;                            // Sync pattern         u32 0x0000FFFF
    unsigned long   m_ulSize;                                   // Size                 u32 Size in bytes of this record from the start of the version field to the end of the Checksum. It includes the embedded data size.
    unsigned long   m_ulOffsetToOptionalData;                   // Data offset          u32 Offset in bytes to optional data field from start of record. Zero implies no optional data.
    unsigned long   m_ulOptionalDataIdentifier;                 // Data idenfitifer     u32 Identifier for optional data field. Zero for no optional field. This identifier is described with each record type.

    TIME7K          m_sTime7k;                                  // 7KTIME               u8*10   UTC.

    unsigned char   m_ucReserved1[ 2 ];                         // Reserved             u16 Reserved space for byte boundary alignment and future use.

    unsigned long   m_ulRecordType;                             // Record type          u32 Unique identifier of indicating the type of data embedded in this record.
    unsigned long   m_ulDeviceId;                               // Device identifier    u32 Identifier of the device that this data pertains.

    unsigned short  m_unSubsystemId;                            // Subsystem identifier u16 Identifier for the device subsystem

    unsigned short  m_unSystemEnumerator;                       // System Enumerator    u16 Enumerator to differentiate between identical systems for a given installation.

    unsigned long   m_ulDataSetNumber;                          // Data set             u32 Data set number.
    unsigned long   m_ulRecordNumber;                           // Record count         u32 Sequential record counter.

    __int64         m_i64PreviousRecord;                        // Previous record      i64 Pointer to the previous record of the same type (in bytes from start of file). This is an optional field for files and shall be -1 if not used.
    __int64         m_i64NextRecord;                            // Next record          i64 Pointer to the next record of the same type in bytes from start of file. This is an optional field for files and shall be -1 if not used.

    unsigned short  m_unFlags;                                  // Flags                u16 BIT FIELD: Bit 1 - Valid Checksum

    unsigned char   m_ucReserved2[ 2 ];                         // Reserved             u16 Reserved space for byte boundary alignment and future use.
                                                                
    // Following this header is:                                     
    // DATA SECTION                                                                     xx  Dynamic Record type specific data.
    // Checksum                                                                         u32 Sum of bytes in data section (optional, depends on bit 1 of Flags field).

    static unsigned long Size( void )
    {
        return sizeof( struct tagRECORDHEADER7KVERSION2 );
    }

    bool IsValid( void ) const
    {
        return ( ( m_unVersion          >   0          ) &&
                 ( m_ulSyncPattern      ==  0x0000ffff ) &&
                 ( m_ulSize             >   Size()     ) &&
                 ( m_sTime7k.IsValid()                 )  );
    }

    unsigned long DynamicBytes( void ) const
    {
        return ( m_ulSize - ( Size() + Checksum7kSize_m() ) );
    }
};

struct tagRECORDHEADER7KVERSION3
{
    unsigned short  m_unVersion;                                // Version              u16 Version of this frame (e.g.: 1, 2, …)
    unsigned short  m_unOffset;                                 // Offset               u16 Offset in bytes from the start of the sync pattern to the start of the DATA SECTION. This allows for expansion of the header whilst maintaining backward compatibility.

    unsigned long   m_ulSyncPattern;                            // Sync pattern         u32 0x0000FFFF
    unsigned long   m_ulSize;                                   // Size                 u32 Size in bytes of this record from the start of the version field to the end of the Checksum. It includes the embedded data size.
    unsigned long   m_ulOffsetToOptionalData;                   // Data offset          u32 Offset in bytes to optional data field from start of record. Zero implies no optional data.
    unsigned long   m_ulOptionalDataIdentifier;                 // Data idenfitifer     u32 Identifier for optional data field. Zero for no optional field. This identifier is described with each record type.

    TIME7K          m_sTime7k;                                  // 7KTIME               u8*10   UTC.

    unsigned char   m_ucReserved1[ 2 ];                         // Reserved             u16 Reserved space for byte boundary alignment and future use.

    unsigned long   m_ulRecordType;                             // Record type          u32 Unique identifier of indicating the type of data embedded in this record.
    unsigned long   m_ulDeviceId;                               // Device identifier    u32 Identifier of the device that this data pertains.

    unsigned char   m_ucReserved2[ 2 ];                         // Reserved             u8*2 NB: Formally the subsystem identifier (u16 Identifier for the device subsystem).

    unsigned short  m_unSystemEnumerator;                       // System Enumerator    u16 Enumerator to differentiate between identical systems for a given installation.
    unsigned long   m_ulRecordNumber;                           // Record count         u32 Sequential record counter.
    unsigned short  m_unFlags;                                  // Flags                u16 BIT FIELD: Bit 1 - Valid Checksum

    unsigned char   m_ucReserved3[ 2 ];                         // Reserved             u16 Reserved space for byte boundary alignment and future use.
                                                                
    // Following this header is:                                     
    // DATA SECTION                                                                     xx  Dynamic Record type specific data.
    // Checksum                                                                         u32 Sum of bytes in data section (optional, depends on bit 1 of Flags field).

    static unsigned long Size( void )
    {
        return sizeof( struct tagRECORDHEADER7KVERSION3 );
    }

    bool IsValid( void ) const
    {
        return ( ( m_unVersion          >   0          ) &&
                 ( m_ulSyncPattern      ==  0x0000ffff ) &&
                 ( m_ulSize             >   Size()     ) &&
                 ( m_sTime7k.IsValid()                 )  );
    }

    unsigned long DynamicBytes( void ) const
    {
        return ( m_ulSize - ( Size() + Checksum7kSize_m() ) );
    }
};

struct tagRECORDHEADER7KVERSION4
{
    unsigned short  m_unVersion;                                // Version              u16 Version of this frame (e.g.: 1, 2, …)
    unsigned short  m_unOffset;                                 // Offset               u16 Offset in bytes from the start of the sync pattern to the start of the DATA SECTION. This allows for expansion of the header whilst maintaining backward compatibility.

    unsigned long   m_ulSyncPattern;                            // Sync pattern         u32 0x0000FFFF
    unsigned long   m_ulSize;                                   // Size                 u32 Size in bytes of this record from the start of the version field to the end of the Checksum. It includes the embedded data size.
    unsigned long   m_ulOffsetToOptionalData;                   // Data offset          u32 Offset in bytes to optional data field from start of record. Zero implies no optional data.
    unsigned long   m_ulOptionalDataIdentifier;                 // Data idenfitifer     u32 Identifier for optional data field. Zero for no optional field. This identifier is described with each record type.

    TIME7K          m_sTime7k;                                  // 7KTIME               u8*10   UTC.

    unsigned char   m_ucReserved1[ 2 ];                         // Reserved             u16 Reserved space for byte boundary alignment and future use.

    unsigned long   m_ulRecordType;                             // Record type          u32 Unique identifier of indicating the type of data embedded in this record.
    unsigned long   m_ulDeviceId;                               // Device identifier    u32 Identifier of the device that this data pertains.

    unsigned char   m_ucReserved2[ 2 ];                         // Reserved             u8*2 NB: Formally the subsystem identifier (u16 Identifier for the device subsystem).

    unsigned short  m_unSystemEnumerator;                       // System Enumerator    u16 Enumerator to differentiate between identical systems for a given installation.
    unsigned long   m_ulRecordNumber;                           // Record count         u32 Sequential record counter.
    unsigned short  m_unFlags;                                  // Flags                u16 BIT FIELD: Bit 1 - Valid Checksum

    unsigned char   m_ucReserved3[ 2 ];                         // Reserved             u16 Reserved space for byte boundary alignment and future use.

    unsigned long   m_ulReserved4;                              // Reserved             u32 Reserved for possible use of millisecond timestamp.
    unsigned long   m_ulTotalRecordsInFragmentSet;              // Total records in set u32 Total records in fragmented data set if flag is set.
    unsigned long   m_ulFragmentNumber;                         // Fragment number      u32 Fragment number if the appropriate flag is set.
                                                                    
    // Following this header is:                                     
    // DATA SECTION                                                                     xx  Dynamic Record type specific data.
    // Checksum                                                                         u32 Sum of bytes in data section (optional, depends on bit 1 of Flags field).

    static unsigned long Size( void )
    {
        return sizeof( struct tagRECORDHEADER7KVERSION4 );
    }

    bool IsValid( void ) const
    {
        return ( ( m_unVersion          >   0          ) &&
                 ( m_ulSyncPattern      ==  0x0000ffff ) &&
                 ( m_ulSize             >   Size()     ) &&
                 ( m_sTime7k.IsValid()                 )  );
    }

    unsigned long DynamicBytes( void ) const
    {
        return ( m_ulSize - ( Size() + Checksum7kSize_m() ) );
    }
};

struct tagRECORDHEADER7KVERSION5
{
    unsigned short  m_unVersion;                                // Version              u16 Version of this frame (e.g.: 1, 2, …)
    unsigned short  m_unOffset;                                 // Offset               u16 Offset in bytes from the start of the sync pattern to the start of the DATA SECTION. This allows for expansion of the header whilst maintaining backward compatibility.

    unsigned long   m_ulSyncPattern;                            // Sync pattern         u32 0x0000FFFF
    unsigned long   m_ulSize;                                   // Size                 u32 Size in bytes of this record from the start of the version field to the end of the Checksum. It includes the embedded data size.
    unsigned long   m_ulOffsetToOptionalData;                   // Data offset          u32 Offset in bytes to optional data field from start of record. Zero implies no optional data.
    unsigned long   m_ulOptionalDataIdentifier;                 // Data idenfitifer     u32 Identifier for optional data field. Zero for no optional field. This identifier is described with each record type.

    TIME7K          m_sTime7k;                                  // 7KTIME               u8*10   UTC.

    unsigned short  m_unRecordsVersion;                         // Version of records.  u16 Version number of records pertaining to a given protocol version number.

    unsigned long   m_ulRecordType;                             // Record type          u32 Unique identifier of indicating the type of data embedded in this record.
    unsigned long   m_ulDeviceId;                               // Device identifier    u32 Identifier of the device that this data pertains.

    unsigned char   m_ucReserved2[ 2 ];                         // Reserved             u8*2 NB: Formally the subsystem identifier (u16 Identifier for the device subsystem).

    unsigned short  m_unSystemEnumerator;                       // System Enumerator    u16 Enumerator to differentiate between identical systems for a given installation.
    unsigned long   m_ulRecordNumber;                           // Record count         u32 Sequential record counter.
    unsigned short  m_unFlags;                                  // Flags                u16 BIT FIELD: Bit 1 - Valid Checksum

    unsigned char   m_ucReserved3[ 2 ];                         // Reserved             u16 Reserved space for byte boundary alignment and future use.

    unsigned long   m_ulReserved4;                              // Reserved             u32 Reserved for possible use of millisecond timestamp.
    unsigned long   m_ulTotalRecordsInFragmentSet;              // Total records in set u32 Total records in fragmented data set if flag is set.
    unsigned long   m_ulFragmentNumber;                         // Fragment number      u32 Fragment number if the appropriate flag is set.
                                                                    
    // Following this header is:                                     
    // DATA SECTION                                                                     xx  Dynamic Record type specific data.
    // Checksum                                                                         u32 Sum of bytes in data section (optional, depends on bit 1 of Flags field).

    static unsigned long Size( void )
    {
        return sizeof( struct tagRECORDHEADER7KVERSION5 );
    }

    bool IsValid( void ) const
    {
        return ( ( m_unVersion          >   0          ) &&
                 ( m_ulSyncPattern      ==  0x0000ffff ) &&
                 ( m_ulSize             >   Size()     ) &&
                 ( m_sTime7k.IsValid()                 )  );
    }

    unsigned long DynamicBytes( void ) const
    {
        return ( m_ulSize - ( Size() + Checksum7kSize_m() ) );
    }
};

///////////////////////////////////////////////////////////////////////////////
// Network Frame header flavors.

struct tagNETWORKFRAMEHEADERVERSION1
{
    unsigned short  m_unVersion;            // Version of this frame (e.g.: 1, 2, …)
    unsigned short  m_unOffset;             // Offset, in bytes, to the start of data from the start of this packet.
    unsigned long   m_ulTotalPackets;       // Number of network packets for set of records transmitted
    unsigned long   m_ulPacketSize;         // Size in bytes of this packet including the header and appended data.
    unsigned long   m_ulSequenceNumber;     // Sequential packet number; allows correct ordering during reconstruction. Range: 0 (zero) to N - 1 packets.

    tagNETWORKFRAMEHEADERVERSION1(  unsigned long   ulTotalPackets      = 1UL,
                                    unsigned long   ulPacketSize        = 0UL,
                                    unsigned long   ulSequenceNumber    = 0UL,
                                    unsigned short  unVersion           = un7kSocketProtocolVersion_c )
    {
        Reset();

        m_ulTotalPackets   = ulTotalPackets;
        m_ulPacketSize     = ulPacketSize;
        m_ulSequenceNumber = ulSequenceNumber;
        m_unVersion        = unVersion;
    }

    static unsigned short Size( void )
    {
        return sizeof( struct tagNETWORKFRAMEHEADERVERSION1 );
    }

    void Reset( void )
    {
        memset( this, 0x00, Size() );

        m_unVersion        = un7kSocketProtocolVersion_c;
        m_unOffset         = Size();
    }

    bool IsValid( void ) const
    {
        const unsigned long ulSize = Size();

        return ( ( m_ulPacketSize >= ulSize ) &&
                 ( m_unOffset     >= ulSize ) &&
                 ( m_unVersion    >= 1 ) );
    }
};

struct tagNETWORKFRAMEHEADERVERSION2
{

    unsigned short  m_unVersion;                // Version of this frame (e.g.: 1, 2, …)
    unsigned short  m_unOffset;                 // Offset, in bytes, to the start of data from the start of this packet.

    unsigned long   m_ulTotalPackets;           // Number of network packets for set of records transmitted

    unsigned short  m_unTotalRecords;           // Total number of records in network packets transmitted (helper field for parsing data). Max 128 records per transmission.
    unsigned short  m_unTransmissionIdentifier; // Helper field for packet assembly. Must be the same number for each network packet in transmission. Adjacent transmissions in time from one source may not use the same id.

    unsigned long   m_ulPacketSize;             // Size in bytes of this packet including the header and appended data.
    unsigned long   m_ulTotalSize;              // Total size in bytes of all packets in transmission excluding network frame(s).
    unsigned long   m_ulSequenceNumber;         // Sequential packet number; allows correct ordering during reconstruction. Range: 0 (zero) to N - 1 packets.

    tagNETWORKFRAMEHEADERVERSION2(  unsigned long   ulTotalPackets      = 1UL,
                                    unsigned long   ulPacketSize        = 0UL,
                                    unsigned long   ulSequenceNumber    = 0UL,
                                    unsigned short  unVersion           = un7kSocketProtocolVersion_c )
    {
        Reset();

        m_ulTotalPackets   = ulTotalPackets;
        m_ulPacketSize     = ulPacketSize;
        m_ulSequenceNumber = ulSequenceNumber;
        m_unVersion        = unVersion;
    }

    static unsigned short Size( void )
    {
        return sizeof( struct tagNETWORKFRAMEHEADERVERSION2 );

    }

    void Reset( void )
    {
        memset( this, 0x00, Size() );

        m_unVersion        = un7kSocketProtocolVersion_c;
        m_unOffset         = Size();
    }

    bool IsValid( void ) const
    {
        const unsigned long ulSize = Size();

        return ( ( m_ulPacketSize >= ulSize ) &&
                 ( m_unOffset     >= ulSize ) &&
                 ( m_unVersion    >= 1 ) );
    }
};

struct tagNETWORKFRAMEHEADERVERSION3
{

    unsigned short  m_unVersion;                        // Version of this frame (e.g.: 1, 2, …)
    unsigned short  m_unOffset;                         // Offset, in bytes, to the start of data from the start of this packet.

    unsigned long   m_ulTotalPackets;                   // Number of network packets for set of records transmitted

    unsigned short  m_unTotalRecords;                   // Total number of records in network packets transmitted (helper field for parsing data). Max 128 records per transmission.
    unsigned short  m_unTransmissionIdentifier;         // Helper field for packet assembly. Must be the same number for each network packet in transmission. Adjacent transmissions in time from one source may not use the same id.

    unsigned long   m_ulPacketSize;                     // Size in bytes of this packet including the header and appended data.
    unsigned long   m_ulTotalSize;                      // Total size in bytes of all packets in transmission excluding network frame(s).
    unsigned long   m_ulSequenceNumber;                 // Sequential packet number; allows correct ordering during reconstruction. Range: 0 (zero) to N - 1 packets.

    unsigned long   m_ulDestinationDeviceIdentifier;    // u32 0 – Unspecified, 0xFFFFFFFF – Not used, Any other number is a valid address.
    unsigned short  m_unDestinationEnumerator;          // u16 Destination enumerator unless destination, device identifier is unspecified or not used.
    unsigned short  m_unSourceEnumerator;               // u16 Destination enumerator unless source device, identifier is unspecified or not used.
    unsigned long   m_ulSourceDeviceIdentifier;         // u32 0 – Unspecified, 0xFFFFFFFF – Not used, Any other number is a valid address.

    tagNETWORKFRAMEHEADERVERSION3(  unsigned long   ulTotalPackets      = 1UL,
                                    unsigned long   ulPacketSize        = 0UL,
                                    unsigned long   ulSequenceNumber    = 0UL,
                                    unsigned short  unVersion           = un7kSocketProtocolVersion_c )
    {
        Reset();

        m_ulTotalPackets   = ulTotalPackets;
        m_ulPacketSize     = ulPacketSize;
        m_ulSequenceNumber = ulSequenceNumber;
        m_unVersion        = unVersion;
    }

    static unsigned short Size( void )
    {
        return sizeof( struct tagNETWORKFRAMEHEADERVERSION3 );

    }

    void Reset( void )
    {
        memset( this, 0x00, Size() );

        m_unVersion        = un7kSocketProtocolVersion_c;
        m_unOffset         = Size();
    }

    bool IsValid( void ) const
    {
        const unsigned long ulSize = Size();

        return ( ( m_ulPacketSize >= ulSize ) &&
                 ( m_unOffset     >= ulSize ) &&
                 ( m_unVersion    >= 1 ) );
    }
};

// Note: Version 4 NETWORK FRAME is identical to v3 NF.

struct tagNETWORKFRAMEHEADERVERSION4
{
    unsigned short  m_unVersion;                        // Version of this frame (e.g.: 1, 2, …)
    unsigned short  m_unOffset;                         // Offset, in bytes, to the start of data from the start of this packet.

    unsigned long   m_ulTotalPackets;                   // Number of network packets for set of records transmitted

    unsigned short  m_unTotalRecords;                   // Total number of records in network packets transmitted (helper field for parsing data). Max 128 records per transmission.
    unsigned short  m_unTransmissionIdentifier;         // Helper field for packet assembly. Must be the same number for each network packet in transmission. Adjacent transmissions in time from one source may not use the same id.

    unsigned long   m_ulPacketSize;                     // Size in bytes of this packet including the header and appended data.
    unsigned long   m_ulTotalSize;                      // Total size in bytes of all packets in transmission excluding network frame(s).
    unsigned long   m_ulSequenceNumber;                 // Sequential packet number; allows correct ordering during reconstruction. Range: 0 (zero) to N - 1 packets.

    unsigned long   m_ulDestinationDeviceIdentifier;    // u32 0 – Unspecified, 0xFFFFFFFF – Not used, Any other number is a valid address.
    unsigned short  m_unDestinationEnumerator;          // u16 Destination enumerator unless destination, device identifier is unspecified or not used.
    unsigned short  m_unSourceEnumerator;               // u16 Destination enumerator unless source device, identifier is unspecified or not used.
    unsigned long   m_ulSourceDeviceIdentifier;         // u32 0 – Unspecified, 0xFFFFFFFF – Not used, Any other number is a valid address.


    tagNETWORKFRAMEHEADERVERSION4(  unsigned long   ulTotalPackets      = 1UL,
                                    unsigned long   ulPacketSize        = 0UL,
                                    unsigned long   ulSequenceNumber    = 0UL,
                                    unsigned short  unVersion           = un7kSocketProtocolVersion_c )
    {
        Reset();

        m_ulTotalPackets   = ulTotalPackets;
        m_ulPacketSize     = ulPacketSize;
        m_ulSequenceNumber = ulSequenceNumber;
        m_unVersion        = unVersion;
    }

    static unsigned short Size( void )
    {
        return sizeof( struct tagNETWORKFRAMEHEADERVERSION3 );

    }

    void Reset( void )
    {
        memset( this, 0x00, Size() );

        m_unVersion        = un7kSocketProtocolVersion_c;
        m_unOffset         = Size();
    }

    bool IsValid( void ) const
    {
        const unsigned long ulSize = Size();

        return ( ( m_ulPacketSize >= ulSize ) &&
                 ( m_unOffset     >= ulSize ) &&
                 ( m_unVersion    >= 1 ) );
    }
};

// Note: Version 5 NETWORK FRAME is identical to v4 NF.

struct tagNETWORKFRAMEHEADERVERSION5
{
    unsigned short  m_unVersion;                        // Version of this frame (e.g.: 1, 2, …)
    unsigned short  m_unOffset;                         // Offset, in bytes, to the start of data from the start of this packet.

    unsigned long   m_ulTotalPackets;                   // Number of network packets for set of records transmitted

    unsigned short  m_unTotalRecords;                   // Total number of records in network packets transmitted (helper field for parsing data). Max 128 records per transmission.
    unsigned short  m_unTransmissionIdentifier;         // Helper field for packet assembly. Must be the same number for each network packet in transmission. Adjacent transmissions in time from one source may not use the same id.

    unsigned long   m_ulPacketSize;                     // Size in bytes of this packet including the header and appended data.
    unsigned long   m_ulTotalSize;                      // Total size in bytes of all packets in transmission excluding network frame(s).
    unsigned long   m_ulSequenceNumber;                 // Sequential packet number; allows correct ordering during reconstruction. Range: 0 (zero) to N - 1 packets.

    unsigned long   m_ulDestinationDeviceIdentifier;    // u32 0 – Unspecified, 0xFFFFFFFF – Not used, Any other number is a valid address.
    unsigned short  m_unDestinationEnumerator;          // u16 Destination enumerator unless destination, device identifier is unspecified or not used.
    unsigned short  m_unSourceEnumerator;               // u16 Destination enumerator unless source device, identifier is unspecified or not used.
    unsigned long   m_ulSourceDeviceIdentifier;         // u32 0 – Unspecified, 0xFFFFFFFF – Not used, Any other number is a valid address.


    tagNETWORKFRAMEHEADERVERSION5(  unsigned long   ulTotalPackets      = 1UL,
                                    unsigned long   ulPacketSize        = 0UL,
                                    unsigned long   ulSequenceNumber    = 0UL,
                                    unsigned short  unVersion           = un7kSocketProtocolVersion_c )
    {
        Reset();

        m_ulTotalPackets   = ulTotalPackets;
        m_ulPacketSize     = ulPacketSize;
        m_ulSequenceNumber = ulSequenceNumber;
        m_unVersion        = unVersion;
    }

    static unsigned short Size( void )
    {
        return sizeof( struct tagNETWORKFRAMEHEADERVERSION5 );

    }

    void Reset( void )
    {
        memset( this, 0x00, Size() );

        m_unVersion        = un7kSocketProtocolVersion_c;
        m_unOffset         = Size();
    }

    bool IsValid( void ) const
    {
        const unsigned long ulSize = Size();

        return ( ( m_ulPacketSize >= ulSize ) &&
                 ( m_unOffset     >= ulSize ) &&
                 ( m_unVersion    >= 1 ) );
    }
};

#pragma pack( pop, PROTOCOLVERSION7K_H_PACK )                   // Restore the previous byte alignment.

// Set the active protocol. Note that we leave the definitions of older versions defined
// should they be needed for backwards compatibility purposes.

#if     ( DRF_VERSION_7K == 1 )
    typedef struct tagRECORDHEADER7KVERSION1    tagRECORDHEADER7K;
#elif   ( DRF_VERSION_7K == 2 )
    typedef struct tagRECORDHEADER7KVERSION2    tagRECORDHEADER7K;
#elif   ( DRF_VERSION_7K == 3 )
    typedef struct tagRECORDHEADER7KVERSION3    tagRECORDHEADER7K;
#elif   ( DRF_VERSION_7K == 4 )
    typedef struct tagRECORDHEADER7KVERSION4    tagRECORDHEADER7K;
#elif   ( DRF_VERSION_7K == 5 )
    typedef struct tagRECORDHEADER7KVERSION5    tagRECORDHEADER7K;
#else
    #error UNKNOWN 7k DATA RECORD FRAME VERSION NUMBER
#endif

#if     ( NF_VERSION_7K == 1 )
typedef struct tagNETWORKFRAMEHEADERVERSION1    tagNETWORKFRAMEHEADER;
#elif   ( NF_VERSION_7K == 2 )
typedef struct tagNETWORKFRAMEHEADERVERSION2    tagNETWORKFRAMEHEADER;
#elif   ( NF_VERSION_7K == 3 )
typedef struct tagNETWORKFRAMEHEADERVERSION3    tagNETWORKFRAMEHEADER;
#elif   ( NF_VERSION_7K == 4 )
typedef struct tagNETWORKFRAMEHEADERVERSION4    tagNETWORKFRAMEHEADER;
#elif   ( NF_VERSION_7K == 5 )
typedef struct tagNETWORKFRAMEHEADERVERSION5    tagNETWORKFRAMEHEADER;
#else
#error  UNKNOWN 7k NETWORK FRAME VERSION NUMBER
#endif

// Set up the standard psuedonyms.

typedef tagRECORDHEADER7K                       RECORDHEADER7K,  *PRECORDHEADER7K,
                                                DATARECORDFRAME, *PDATARECORDFRAME;

typedef tagNETWORKFRAMEHEADER                   NETWORKFRAMEHEADER, *PNETWORKFRAMEHEADER;

#endif // !defined(AFX_7KPROTOCOL_H__5E04A08D_5750_47e5_81A7_65D031AC543B__INCLUDED_)
