/*
 * RTC_NFC.h
 *
Remote Train Control Program for Windows

© Copyright 2018 by Mark DiVecchio <markd@silogic.com>

    This file is part of Remote Train Control.

    Remote Train Control is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Remote Train Control is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Remote Train Control.  If not, see <http://www.gnu.org/licenses/>.
--------------------------------------------------------------------------------------------
// Master Copy at C:\Users\markd\Documents\Arduino\libraries\RTC_NFC\RTC_NFC.h
--------------------------------------------------------------------------------------------
 * Author: Mark DiVecchio
 * Creation date: 12 Feb 2020
*/
#ifndef _RTC_NFC_H
#define _RTC_NFC_H
//
#pragma pack(push, 1)
//
#define RTC_NFC_VERSION 4
//------------------------------------------------------------------------------------------
// Engine Data Structure
// NOTE: if you add or change any of these entries, make the corresponding change to defines.lua
// and to the String Lists on the debug version of the main RTC window
    struct ED {		// Engine Data in binary - 16 bytes
      byte TagID;      // 0 = tag not programmed, 0x88 = tag is programmed
	    #define TAG_NOT_PROGRAMMED 0x00
		#define TAG_PROGRAMMED 0x88
      byte EngineNo;   // 0 = not an Engine or LashUp (look at CarModel), otherwise Engine Number  1-99 (look at CarModel)
                          // 101-120 LashUp Number
		#define NOT_AN_ENGINE 0
      byte TagLocation;  // 0 = Tag not on a truck, 1 = Tag on Front truck, 2 = Tag on Rear truck (Engines and Cars)
		#define NOT_ON_A_TRUCK 0
		#define TAG_ON_FRONT_TRUCK 1
		#define TAG_ON_REAR_TRUCK 2
		#define TAG_UNKNOWN 3
		#define TAG_ON_TRUCK 4
		#define TAG_AT_MIDPOINT 5
      byte EngineType; // 0 = not an engine, 1 = Diesel,  2 = Steam (Engines Only), etc
		#define NOT_AN_ENGINE 0
		#define DIESEL_ENGINE_TYPE 1
		#define STEAM_ENGINE_TYPE 2
		#define GAS_MECHANICAL_ENGINE_TYPE 3
		#define GAS_ELECTRIC_ENGINE_TYPE 4
		#define STEAM_TURBINE_ENGINE_TYPE 5
		#define ELECTRIC_TYPE 6
		#define TURBINE_TYPE 7
		#define DIESEL_MECHANICAL_TYPE 8
      byte Coupler;	// Specifies the location and operation of the couplers
		#define NO_COUPLER 0
		#define REAR_REMOTE_COUPLER_ONLY 1
		#define FRONT_REMOTE_COUPLER_ONLY 2
		#define FRONT_AND_REAR_REMOTE_COUPLERS 3
		#define COUPLER_UNKNOWN 4
		#define REAR_MANUAL_COUPLER_ONLY 5
		#define FRONT_MANUAL_COUPLER_ONLY 6
		#define FRONT_AND_REAR_MANUAL_COUPLERS 7
		#define REAR_DUMMY_COUPLER_ONLY 8
		#define FRONT_DUMMY_COUPLER_ONLY 9
		#define FRONT_DUMMY_AND_REAR_MANUAL_COUPLERS 10
		#define NOT_APPLICABLE 0x80	// Coupler is only used for Engines but can be specified for cars
      byte SXS;        // 0 = no SXS Sound, 1 = has SXS sound at clip 42 (Engines only)
		#define NO_SXS_SOUND 0
		#define HAS_SXS_SOUND 1
      byte CarModel;    // see #defines below
		// if EngineNo == NOT_AN_ENGINE
		#define UNKNOWN_CARMODEL 0 // 0 = unknown
		#define BOXCAR 1 // 1 = Boxcar
		#define TANK_CAR 2 // 2 = Tank Car
		#define FLAT_CAR 3 // 3 = Flat Car
		#define CABOOSE 4 // 4 = Caboose
		#define TENDER 5 // 5 = Tender
		#define GONDOLA 6 // 6 = Gondola
		#define COAL_HOPPER 7 // 7 = Coal Car
		#define ORE_HOPPER 8 // 8 = Ore Car
		#define MOW_FLATCAR 9 // 9 = MOW Flatcar
		#define MOW_CRANE_CAR 10 // 10 = MOW Crane Car
		#define MOW 11 // 11 = MOW Misc
		#define COACH 12 // 12 = Passenger Coach
		#define OBSERVATION 13  // 13 = Passenger Observation
		#define BAGGAGE 14 // 14 = Baggage
		// xx-255 for future use
		// if EngineNo != NOT_AN_ENGINE (Lead Engine for LashUps)
		#define UNKNOWN_ENGINEMODEL 0// 0 = unknown
		#define GP38_2 1 // 1 = GP38-2
		#define GP7 2 // 2 = GP7
		#define GP9 3 // 3 = GP9
		#define U28B 4 // 4 = U28B
		#define BERKSHIRE 5 // 5 = Berkshire
		#define DOODLEBUG 6 // 6 = Doodlebug
		#define SW1200 7 // 7 = SW1200
		#define SW1500 8 // 8 = SW1500
		#define SWITCHER_0_6_0 9 // 9 = 0-6-0 Switcher
		#define SWITCHER_0_8_0 10// 10 = 0-8-0 Switcher
		#define H_9 11 // 11 = 2-8-0 H-9 Consolidation
		#define SW_9 12 // 12 = SW-9
        #define RS_3 13 // 13 = RS-3
		#define MP15DC 14 // 14 = EMD MP15DC
        #define PCC 15 // 15 = Presidents Conference Committee Trolley
		// xx-255 for future use
      byte Railroad;   // see #defines below
		#define UNKNOWN_OR_OTHER 0
		#define P_AND_LE 1
		#define A_AND_S 2
		#define NYC 3
		#define B_AND_O 4
		#define P_AND_E 5
		#define LE_AND_E 6
		#define P_RR 7
		#define NH 8
        #define RDG 9
        #define J_AND_L 10
        #define Isalys 11
        #define LV 12
        // Many more defined see "Tag Programmer"		
      byte CarLength;  // Length of engine/car in centimeters, coupler face to coupler face (include Tender)
      byte TagOffset;  // Distance from center of tag to coupler face in centimeters
                       // for engines/cars with two tags, the distance must be same for both tags
      union {
          struct {
            byte n1;		// --
            byte n2;		// --
            byte n3;		// -- Up to 6 digit engine/car number in ASCII (w/leading spaces) "  2808"
            byte n4;		// --
            byte n5;		// --
            byte n6;		// --
            };
          byte CarNumber[6];  // Up to 6 digit engine/car number in ASCII (w/leading spaces) "  2808" -- NOT NULL TERMINATED
        };
      };
//
// Packet Format
//
// offsets of header & trailer fields in the ASCII data packet
//
#define SOPIDX 0
#define DETECTORIDX 2
#define READERIDX 4
#define TAGCOUNTIDX 6
#define PACKETTYPEIDX 8
#define BYTECOUNTIDX 10
#define UIDIDX 12		// UID for the next 8 characters, packets without UID has data starting here
#define DATAIDX 20
#define CRCIDX 52
#define EOTIDX 54
// then starting at DATAIDX the 32 characters (16 bytes) from the tag:
#define TAGIDIDX 0
#define ENGINENOIDX 2
#define TAGLOCATIONIDX 4
#define ENGINETYPEIDX 6
#define COUPLERIDX 8
#define SXSIDX 10
#define CARMODELIDX 12
#define RAILROADIDX 14
#define CARLENGTHIDX 16
#define TAGOFFSETIDX 18
#define CARNUMBERIDX 20   // for the next 12 characters
//---------------------------------------------------------------------------
struct CMD {		  // Packet in ASCII - total 56 chars + NULL
  union {
	struct {
		byte StartOfPacket[2];    	// SOP
		byte Detector[2];    	// Sending detector number, starting at 0x01, 0x00 == Master Computer
		union {
			byte Reader[2];      	//
			byte Target[2];      	// used for target detector # for type 0x5X commands
		};
		byte TagCount[2];    	// used for operand #1 for type 0x5X commands
		byte PacketType[2];  	// used for command for type 0x5X commands
		byte ByteCount[2];
		byte Data[8 + 32 + 2 + 2];   // max : UID (8 chars) + data (32 chars) + checksum + EOP
		byte Filler;			// NULL
		};

	unsigned char Packet[57];	// max : packet 56 chars + NULL
	};
  };
//---------------------------------------------------------------------------
struct Packet_Header {			// Packet header in binary
  byte SOP;    		// SOP
  byte Detector;  		// Sending detector number, starting at 0x01, 0x00 == Master Computer
 union {
	byte Reader;       // Reader number for detected tags
	byte Target;       // used for target detector # for type 0x5X commands
	};
  byte TagCount;		// tag detection number
  byte PacketType;		// Packet Type
  byte ByteCount;		// Number of bytes in data
  };
//---------------------------------------------------------------------------
//
// Packet defintion using Union and different ways to access the information
//
union UP {
	struct {  			// binary packet with 4 byte UID and 16 byte engine data/name
      Packet_Header Header; // 6 bytes
      byte UID_UP[4];		// 4 bytes
	  ED EngineData;    	// 16 bytes
      byte Checksum;    	// 1 byte
      byte EOP;         	// 1 byte
      } Data_Packet;
	struct {  			// binary packet with 4 byte UID and 16 byte engine name
      Packet_Header Header; // 6 bytes
      byte UID_UP[4];		// 4 bytes
	  byte CarName[16];    	// 16 bytes - padded with blanks
      byte Checksum;    	// 1 byte
      byte EOP;         	// 1 byte
	  } Name_Packet;
	struct {  			// binary packet with 16 byte Detector Name
	  Packet_Header Header; // 6 bytes
	  byte Detector_Name[16];// 16 bytes - padded with blanks
      byte Checksum;    	// 1 byte
      byte EOP;         	// 1 byte
	  } Detector_Name_Packet;
    byte Byte_Array[56]; // Generic packet all byte array
    struct TP {  // packet with 4 byte tag ID
      Packet_Header PHTagID;  // 6 bytes
      byte UID[4];   // UID  4 Bytes
      byte Checksum;      // 1 byte
      byte EOP;           // 1 byte
      } UID_Only_Packet;
    };
//---------------------------------------------------------------------------	
/*
 * Message packet format
 *
 * character based packet. digits '0' to 'F'
 * Start of Packet and End of Packet are special hex codes to help identify the 
 * packet boundaries.
-------------------------------
Start of packet character - 2 hex digits START_OF_PACKET
Sending Detector # - 2 hex digits - number starting at 0x01, 0x00 == Master Computer
Reader # - 2 hex digits - number starting at 0
Tag Counter by detector - 2 hex digits - modulo "FF" - 0-255
Packet type  2 hex digits : Error - Tag - Information/Status - Command
Byte Count - 2 hex digits - count all digits in the Data packet
<----> Data Packet
Checksum - 2 hex digits - 8 bit binary sum of all characters between Start of Packet and End of Packet
End of Packet character - 2 hex digits END_OF_PACKET
-----------------------------------
*/
// Start of Packet Character
#define START_OF_PACKET 0xFF
// End of Packet Character
#define END_OF_PACKET 0xF0

// NOP - ACK - NAK - WACK
#define NOP 0x00
#define ACK 0x61
#define NAK 0x62
#define WACK 0x63

//Error:
//0x10 Didn't find PN53x detector on port X
#define PN53xNOTFOUND 0x10
//0x11 Unable to read Block X
#define CANTREADBLOCK 0x11
//0x12 Tag not Programmed
#define TAGNOTPROG 0x12
//0x13 Unable to authenticate
#define AUTHERROR 0x13
//0x14 SOP character missing
#define SOPMISSING 0x14
//0x15 Write block error
#define WRITEERROR 0x15
//0x16 No Tag Detected When Expected
#define NOTAGDETECTED 0x16

//Tag Data (TAGDATABLOCK4 also returns the Tag UID):
//0x20 not used
//0x21 Block 4
#define TAGDATABLOCK4 0x21
//0x22 Block 5
#define TAGDATABLOCK5 0x22
//0x23 Block 6
#define TAGDATABLOCK6 0x23
//0x24 Block 7
#define TAGDATABLOCK7 0x24

//Information:
//0x01 Hello X RFID Readers Attached (RTCNFCIRQ version in Reader byte and TagCount byte) 
#define HELLOPACKET 0x01
//0x03 Detector Y Reader X Detected
#define TAGDETECTED 0x03
//0x04 Found chip PN5xx
#define PN53xFOUND 0x04
//0x05 Waiting for an ISO14443A tag detection
#define WAITING 0x05
//0x06 Detector Y Sensor X Detected, Sensor pin state in 1 byte data packet
#define SENSORDETECTED 0x06
//0x07 Send Detector Name in the data field - exactly 16 characters, pad with blanks
#define DETECTORNAME 0x07
//0x08 Send IP in the data field, exactly 16 characters, pad with blanks (Protocol in Reader byte: 0 = UDP, 1 = TCP)
#define DETECTORIP 0x08

// Command Packet Transmitted to a Detector ("Reader" contains the target detector number and
// "TagCount" contains the operand);
// Commands are limited to 0x50 to 0x5F
//0x50 set flag to return Block 4 data to Master on tag detection
#define FLAG_READ_BLOCK4 0x50
//0x51 set flag to return Block 5 data to Master on tag detection
#define FLAG_READ_BLOCK5 0x51
//0x52 set flag to return only TagID to Master on tag detection
#define FLAG_READ_TAGID 0x52
//0x53 return TagID on Auth or Read error
#define FLAG_FALLBACKMODE 0x53
//0x54 write packet to block 4 - Engine Data
#define WRITE_PACKET4 0x54
//0x55 write packet to block 5 - Engine Name
#define WRITE_PACKET5 0x55
//0x56 write packet to block 6 - Lashup Data
#define WRITE_PACKET6 0x56
//
// debugging
//0x5D  Reset and reboot
#define RESET_REBOOT 0x5D
// debugging
//0x5E  Send Initial Packets
#define SEND_INITIAL_PACKETS 0x5E
// debugging
//0x5F LED Off, tag count = 1 -> LED on & tag count = 0 ->LED off
#define LED_CONTROL 0x5F
//
#pragma pack(pop)
#endif
//---------------------------------------------------------------------------

