//------------------------------------------------------------------------------
// <copyright file="FCCMessage.h" company="LiquidRobotics">
//
// Copyright (c) 2014 Liquid Robotics, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// This software is associated with a release.  Liquid Robotics makes no
// representation that the design, interfaces or component distribution will
// remain unchanged in future releases.
//
// </copyright>
//
// <summary>
//   Declarations for Float C&C message set types
// </summary>
//
// <owner>Mike Cookson</owner>
//------------------------------------------------------------------------------

#ifndef FCCMESSAGE_H_
#define FCCMESSAGE_H_

#include <iostream>
#include <vector>
#include <memory.h>
#include <stdint.h>
#include "LqrSMACByteArray.h"
#include "LqrSMACSharedLib.h"

namespace LiquidRobotics {
namespace SMACFramework {
	class ByteStream;
}
namespace PayloadInterface {
namespace FCCMessage {

typedef SMACFramework::ByteArray::byte byte;
typedef uint8_t BOOL;
typedef SMACFramework::ByteArray ByteArray;

#pragma pack(push,1)

enum ECommMaxRxMSG
{
	COMM_MAX_RX_MSG = 1820
};

enum ECommMaxTxMsg
{
	COMM_MAX_TX_MSG = 300
};

enum EMaxFileTxMsg
{
	COMM_MAX_FILE_TX_MSG = 1820
};

enum EMaxNumBatteries
{
	MAX_NUM_BATTERIES = 7
};

//Structures Common to Inbound and Outboud traffic
typedef struct _COMM_HEADER_
{
	uint8_t		type;
	uint32_t	packetID;
	uint16_t	size;
}COMM_HEADER, *PCOMM_HEADER;

typedef struct _CMD_FMT_COMMON_
{
	uint8_t		fmtID;
	uint16_t	command;
}CMD_FMT_COMMON, *PCMD_FMT_COMMON;

typedef struct _SINGLE_PARAMETER_
{
	uint16_t	paramID;
	uint8_t		paramLen;
	uint8_t		paramVal;
}SIGLE_PARAMETER, *PSINGLE_PARAMETER;

//Structures used to describe inbound traffic (Shore to Ship)
typedef struct _CMD_FMT_10_
{
	uint8_t		field3;
	uint8_t		field4;
	uint8_t		field5;
	uint8_t		field6;
	uint8_t		field7;
	uint32_t	latitude;
	uint32_t	longitude;
	uint16_t	crc;
}CMD_FMT_10, *PCMD_FMT_10;

//System Status/Configuration Packet
typedef struct _COMM_CURRENT_STATUS_
{
	uint8_t		bf_followCourse:1;
	uint8_t		bf_manualNav:1;
	uint8_t		bf_followHeading:1;
	uint8_t		bf_holdStation:1;
	uint8_t		bf_reservedBits:1;
	uint8_t		bf_xbee:1;
	uint8_t		bf_lightLED:1;
	uint8_t		bf_lightIR:1;
	uint16_t	telemetryRate;		//minutes -- default = 2
	uint16_t	batteryCheckRate;	//seconds -- default = 20
	uint16_t	alarmCheckRate;		//seconds -- default = 20
	uint8_t		unused1;			// NOT USED SET TO 0 ----- seconds -- default = 120 -- ????
	uint8_t		subToFloatTO;		//ms -- default = 20;
	uint8_t		__subLowBattery;		// NOT USED SET TO 0 ----- Sub Battery readings -- not currently used
	uint8_t		__subCritBattery;		// NOT USED SET TO 0 ----- Sub Battery readings -- not currently used
	uint8_t		floatLowBattery;	//units/default TBD
	uint8_t		floatCritBattery;	//units/default TBD
	uint8_t		__subUpperPressure;	// NOT USED SET TO 0 ----- units/default TBD -- ???
	uint8_t		__subLowerPressure;	// NOT USED SET TO 0 ----- units/default TBD -- ???
	uint8_t		__subUpperTemp;		// NOT USED SET TO 0 ----- units/default TBD -- ???
	uint8_t		floatUpperPressure;	//units/default TBD
	uint8_t		floatLowerPressure;	//units/default TBD
	int8_t		floatUpperTemp;		//units/default TBD
	uint16_t	arrivalDistance;	//meters -- default = 20
	uint8_t		unused2;			// NOT USED SET TO 0 ----- ms -- Sub Steering default = 10? -- ???
	uint16_t	powerTelemRate;		//minutes -- default = 60
	uint16_t	unused3;			// NOT USED SET TO 0 ----- brads? -- default TBD	-- ???
	uint8_t		floatSubCommRate;	//seconds -- default = 10
	int32_t		holdPosLatitude;	//
	int32_t		holdPosLongitude;	//
}COMM_CURRENT_STATUS, *PCOMM_CURRENT_STATUS;


typedef struct _CMD_FMT_11_
{
	COMM_CURRENT_STATUS	config;
	uint16_t	crc;
}CMD_FMT_11, *PCMD_FMT_11;

typedef struct _CMD_FMT_15_
{
	uint8_t		numParameters;
	SIGLE_PARAMETER	parameter;
}CMD_FMT_15, *PCMD_FMT_15;

//Structure used for individual power settings for sub steering parameters
typedef struct _SUB_STEERING_SETTINGS_
{
	uint16_t	gain;
	uint8_t		timebase;
	uint8_t		deadband;
	uint8_t		goal;
	uint8_t		rudderMax;
	uint8_t		moveMin;
	uint8_t		trimMax;
}SUB_STEERING_SETTINGS, *PSUB_STEERING_SETTINGS;

//Structure used for setting, retrieving, and reporting the Sub Steering Parameters
typedef struct _SUB_STEERING_PARAMETERS_
{
	SUB_STEERING_SETTINGS 	powerSteeringSettings[3];
	uint32_t				unused;
	uint32_t				crc32;
}SUB_STEERING_PARAMETERS, *PSUB_STEERING_PARAMETERS;

typedef struct _CMD_FMT_16_
{
	SUB_STEERING_PARAMETERS		steeringParams;
	uint16_t	crc;
}CMD_FMT_16, *PCMD_FMT_16;
// structure that holds the date and time with short year
typedef struct _DATE_TIME_
{
	uint8_t		hour;
	uint8_t		minute;
	uint8_t		second;
	uint8_t		month;
	uint8_t		day;
	uint8_t		year;		// since 2000
} DATE_TIME, *PDATE_TIME;

// structure that holds a MD5 signature
typedef struct _MD5_
{
	uint8_t		data[16];
}MD5, *PMD5;

enum EFileIDSpecial
{
	INVALID_FILE_ID = 0xFFFFFFFFL
};

enum EFTAttributes
{
	FTATTR_READ_ONLY = 1,
	FTATTR_CHECKED = 0x80
};

typedef struct _CMD_FMT_18_
{
	uint16_t	storageControllerAddress;
	char		fileName[11];
	uint32_t	fileID;
	uint32_t	fileSize;
	DATE_TIME	creationDate;
	DATE_TIME	modifiedDate;
	uint8_t		fileAttributes;
	uint8_t		overwriteFile;
	uint16_t	contentCRC;
	MD5			contentMD5;
	uint16_t	numDataBytes;
	uint8_t		data[0];
}CMD_FMT_18, *PCMD_FMT_18;

typedef struct _CMD_FMT_19_
{
	uint16_t	storageControllerAddress;
	uint32_t	fileID;
	uint32_t	offset;
	uint16_t	numDataBytes;
	uint8_t		data[0];
}CMD_FMT_19, *PCMD_FMT_19;

typedef struct _CMD_FMT_1A_
{
	uint16_t	storageControllerAddress;
	char		fileName[11];
	uint32_t	fileID;
	uint8_t		overrideReadOnly;
}CMD_FMT_1A, *PCMD_FMT_1A;

typedef struct _CMD_FMT_1B_
{
	uint16_t	storageControllerAddress;
	char		fileName[11];
	uint32_t	originalTransactionID;
	uint32_t	offset;
	uint32_t	readLength;
	uint16_t	maxResponseSize;
}CMD_FMT_1B, *PCMD_FMT_1B;

enum ActionFlag
{
	AF_CHECK_FILE = 1,
	AF_DELETE_ON_FAILURE = 2
};

typedef struct _CMD_FMT_1C_
{
	uint16_t	storageControllerAddress;
	char		fileName[11];
	uint32_t	fileID;
	uint8_t		actionFlags;
	uint16_t	maxResponseSize;
}CMD_FMT_1C, *PCMD_FMT_1C;

typedef struct _CMD_FMT_1E_
{
	uint16_t dest;
	uint8_t function;
	uint16_t dataLength;
	char consoleData[0];
}CMD_FMT_1E, *PCMD_FMT_1E;

typedef CMD_FMT_1C CMD_FMT_31, *PCMD_FMT_31;

typedef struct _ACK_NAK_
{
	uint16_t	crc;
}ACK_NAK, *PACK_NAK;


typedef struct _ACK_NAK_STATUS_
{
	COMM_CURRENT_STATUS		systemConfig;
	uint16_t	crc;
}ACK_NAK_STATUS, *PACK_NAK_STATUS;

//Battery Charge Controller -- Battery Information Structure
typedef struct _BATTERY_INFORMATION_
{
	//Bitfield data for first status byte -- if a battery is missing or failed, all bits = 0
	uint8_t	bfPresent:1;		//1=battery is present
	uint8_t	bfDischarged:1;		//1=battery is fully discharged
	uint8_t	bfCharged:1;		//1=battery is fully charged
	uint8_t	bfDischarging:1;	//1=battery is discharging
	uint8_t	bfDischargeAlarm:1;	//1=battery terminate discharge alarm
	uint8_t	bfChargeAlarm:1;	//1=battery terminate charge alarm
	uint8_t	bfOverTempAlarm:1;	//1=battery over temperature alarm
	uint8_t	bfOnline:1;			//1=battery is on line
	//End of bitfield data

	int8_t 		temperature;	//Batery temperature from -10 to 100 -- units are 1C/count
	uint16_t	power;			//Power remaining in the battery -- units are 10mWh/count
	int16_t		current;		//Battery current.  Units in 10mA/count.  Negative = discharge
	uint16_t	voltage;		//Battery voltage.  Units in 1mV/count
}BATTERY_INFORMATION, *PBATTERY_INFORMATION;

//Structure defining the overall system charge status
typedef struct _SYSTEM_CHARGE_STATUS_
{
	uint8_t		statusPayload1;		//0x00 - 0x7F 10mA/count: 0x80 Payload1 commanded Off, 0x81 Payload1 over current off
	uint8_t		statusPayload2;		//Same as above
	uint8_t		statusUmbilical;	//Same as above
	uint8_t		statusUntwist;		//Same as above

	uint16_t	totalPower;			//Total power remaing in batteries 10mWh/count -- capped at 655.35 Wh
	int16_t		batteryCurrent;		//Total current flowing to/from batteries in mA -- negative=discharge
	uint16_t	systemCurrent;		//Total current being delivered to the system in mA
	uint16_t	systemVoltage;		//System voltage in mV

	uint8_t		powerSolarPanel0;	//Power indicator for solar panel 0
	uint8_t		powerSolarPanel1;	//Power indicator for solar panel 1
	uint8_t		powerSolarPanel2;	//Power indicator for solar panel 2
	uint8_t		powerSolarPanel3;	//Power indicator for solar panel 3
}SYSTEM_CHARGE_STATUS, *PSYSTEM_CHARGE_STATUS;

//System Detailed Power Packet
typedef struct _COMM_DETAILED_POWER_
{
	uint8_t hour;
	uint8_t minute;
	uint8_t second;
	uint8_t month;
	uint8_t day;
	uint8_t year;	//Value + 2000 = Year
	SYSTEM_CHARGE_STATUS systemCharge;
	BATTERY_INFORMATION batteryInfo[MAX_NUM_BATTERIES];
}COMM_DETAILED_POWER, *PCOMM_DETAILED_POWER;

typedef struct _ACK_POWER_
{
	COMM_DETAILED_POWER	systemPower;
	uint16_t	crc;
}ACK_POWER, *PACK_POWER;

//Structure Used to report the ID information for various Components of the system
typedef struct _COMPONENT_ID_
{
	uint8_t		component;			//0x10=Bubble, 0x20=Sensor, 0x30=Power, 0x40=Untwist, 0x50=Sub C&C
	uint8_t		swMajorRev;			//Major Version Number for the Software
	uint8_t		swMinorRev;			//Minor Version Number for the Software
	uint8_t		hwMajorRev;			//Major Version Number for the Hardware
	uint8_t		hwMinorRev;			//Minor Version Number for the Hardware
	uint16_t	serialNumber;		//HW Serial Number
	uint16_t	calibrationID;		//ID value for Calibration Data
	uint32_t	eepromCRC;			//CRC of the EEPROM data
	uint32_t	flashCRC;			//CRC of the Program Flash
}COMPONENT_ID, *PCOMPONENT_ID;

typedef struct _COMPONENT_ID_SUBSET_
{
	uint8_t		swMajorRev;			//Major Version Number for the Software
	uint8_t		swMinorRev;			//Minor Version Number for the Software
	uint8_t		hwMajorRev;			//Major Version Number for the Hardware
	uint8_t		hwMinorRev;			//Minor Version Number for the Hardware
	uint32_t	flashCRC;			//CRC of the Program Flash
	uint32_t	eepromCRC;			//CRC of the EEPROM data
}COMPONENT_ID_SUBSET, *PCOMPONENT_ID_SUBSET;

//System Identification Packet
typedef struct _COMM_SYSTEM_ID_
{
	uint8_t hour;
	uint8_t minute;
	uint8_t second;
	uint8_t month;
	uint8_t day;
	uint8_t year;	//Value + 2000 = Year
	uint8_t floatFirmwareMajor;
	uint8_t floatFirmwareMinor;
	uint16_t floatFirmwareBuild;
	char iridiumIMEI[15];
	COMPONENT_ID_SUBSET subID;
	COMPONENT_ID_SUBSET sensorBoardID;
	COMPONENT_ID_SUBSET bubbleID;
	COMPONENT_ID_SUBSET batteryID;
	COMPONENT_ID_SUBSET untwistID;
	uint8_t		commSpecMajor;
	uint8_t		commSpecMinor;
	uint8_t		commSpecRev;
	uint16_t	modemVersion;
	uint8_t		unused1;
	uint8_t		unused2;
	uint8_t		xbeeChannel;
	uint16_t	xbeePANID;
	uint16_t	xbeeAddress;
}COMM_SYSTEM_ID, *PCOMM_SYSTEM_ID;

typedef struct _ACK_ID_
{
	COMM_SYSTEM_ID	systemID;
	uint16_t		crc;
}ACK_ID, *PACK_ID;

typedef struct _ACK_RUDDER_
{
	SUB_STEERING_PARAMETERS		steeringParams;
	uint16_t	crc;
}ACK_RUDDER, *PACK_RUDDER;

enum ETotalErrorCountParams
{
	TOTAL_ERROR_COUNT_PARAMS = 69
};

typedef struct _ACK_DEBUG_
{
	uint16_t	version;
	uint16_t	params[TOTAL_ERROR_COUNT_PARAMS];
	uint16_t	crc;
}ACK_DEBUG, *PACK_DEBUG;

typedef struct _ACK_SUB_HEADING_
{
	uint8_t		heading[192];
	uint16_t	crc;
}ACK_SUB_HEADING, *PACK_SUB_HEADING;

typedef struct _ACK_INTEGRAL_
{
	int16_t		integral[96];
	uint16_t	crc;
}ACK_INTEGRAL, *PACK_INTEGRAL;

//Coordinate Structure (Latitude/Longitude in 10000th of a minute)
typedef struct _COORD_
{
	int32_t	latitude;
	int32_t	longitude;
}COORD, *PCOORD;

typedef struct _PID_NAVIGATION_
{
	BOOL 	enablePIDNavigation;
	BOOL	calculateError;
	int16_t	baseHeading;
	float 	baseDistance;
	COORD 	start;
	COORD 	dest;
	int16_t	gainP;
	int16_t	gainI;
	int16_t	gainThreshold;
	int32_t	integral;
	int32_t	integralSaturation;
	int32_t	lastError;
	float	errorParamC;
	float	errorParamD;
	int8_t	correction;
}PID_NAVIGATION, *PPID_NAVIGATION;

enum EPidNumBins
{
	PID_NUM_BINS = 8
};

typedef struct _ACK_PID_PARAMS_
{
	PID_NAVIGATION navPIDParameters;
	int32_t pidIntegralCache[PID_NUM_BINS];
	uint16_t	crc;
}ACK_PID_PARAMS, *PACK_PID_PARAMS;

typedef struct _ACK_ALL_PARAMS_
{
	uint16_t	version;

	uint16_t	typeRudderTrim;		//Currently undefined so use 0
	uint8_t		valRudderTrim;		//
	uint16_t	typeDeclination;	//Currently undefined so use 0;
	int16_t		valDeclination;		//
	uint16_t 	typeGPSCount;		//#define PARAM_NO_GPS_ALARM				0x000F
	uint8_t		valGPSCount;			//
	uint16_t	typeModemState;		//#define PARAM_MODEM_ALWAYS_ON				0x0014
	uint8_t		valModemState;		//
	uint16_t	typeModemDefault;	//#define PARAM_MODEM_DEFAULT_ALWAYS_ON		0x0015
	uint8_t		valModemDefault;	//
	uint16_t	typePANID;			//#define PARAM_XBEE_PAN_ID					0x0016
	uint16_t	valPANID;			//
	uint16_t	typeChannel;		//#define PARAM_XBEE_CHANNEL_ID				0x0017
	uint8_t		valChannel;			//
	uint16_t	typePwrBubble;		//#define PARAM_POWER_BUBBLE				0x0020
	uint8_t		valPwrBubble;		//
	uint16_t	typePwrSub;			//#define PARAM_POWER_SUB					0x0021
	uint8_t		valPwrSub;			//

	uint16_t	typeEnablePID;		//#define PARAM_NAV_ENABLE_PID				0x0030
	uint8_t		valEnablePID;		//
	uint16_t	typePGain;			//#define PARAM_NAV_PID_P					0x0031
	int16_t		valPGain;			//
	uint16_t	typeIGain;			//#define PARAM_NAV_PID_I					0x0032
	int16_t		valIGain;			//
	uint16_t	typePIDSatLimit;	//#define PARAM_NAV_PID_LIMIT				0x0033
	int16_t		valPIDSatLimit;		//

	uint16_t	typePwrPyld1;		//#define PARAM_POWER_PAYLOAD1				0x0100
	uint8_t		valPwrPyld1;		//
	uint16_t	typePwrPyld2;		//#define PARAM_POWER_PAYLOAD2				0x0200
	uint8_t		valPwrPyld2;		//
	uint16_t	typePwrPyldSub;		//#define PARAM_POWER_PAYLOAD_SUB			0x0300
	uint8_t		valPwrPyldSub;		//
	uint16_t	typePwriPib;		//#define PARAM_POWER_PAYLOAD_IPIB			0x0400
	uint8_t		valPwriPib;			//
	uint16_t	typePyldEnumDelay;
	uint16_t	valPyldEnumDelay;

	uint16_t	crc;
}ACK_ALL_PARAMS, *PACK_ALL_PARAMS;

typedef struct _ACK_UNIQUE_ID_
{
	uint32_t	uniqueID;			// unique ID assigned to vehicle (vehicleID)
	uint16_t	crc;				// crc for the message
}ACK_UNIQUE_ID, *PACK_UNIQUE_ID;

typedef struct _ACK_WRITE_CONSOLE_OUTPUT_
{
	uint16_t	source;				// source address (board ID and task ID)
	uint8_t		function;			// function (0)
	uint16_t	dataLength;			// data length
	uint8_t		data[0];			// console data
}ACK_WRITE_CONSOLE_OUTPUT, *PACK_WRITE_CONSOLE_OUTPUT;

typedef struct _ACK_READ_FILE_
{
	uint16_t	storageControllerAddress;	// storage controller address from request
	uint32_t	seekOffset;			// offset from start of file
	uint8_t		eofFlag;			// EOF flag (0 = not EOF, 0xFF = EOF)
	uint16_t	numDataBytes;		// number of data bytes to follow
	uint8_t		data[64];			// data bytes (content of file; may be larger, but at least 64)
	uint16_t	crc;				// placeholder for CRC
}ACK_READ_FILE, *PACK_READ_FILE;

typedef struct _ACK_FILE_LIST_COMMON_HEADER_
{
	uint16_t	storageControllerAddress;	// storage controller address from request
	uint16_t	offset;				// number of files reported before this
	uint8_t		lastReport;			// 0 = not last report, 0xFF = last report
	uint16_t	numFiles;			// number of files in this message
}ACK_FILE_LIST_COMMON_HEADER, *PACK_FILE_LIST_COMMON_HEADER;

typedef struct _ACK_FILE_LIST_RECORD_
{
	char		fileName[11];		// padded file name
	uint32_t	fileID;				// ID of file
	uint32_t	fileSize;			// size of file
	uint8_t		fileAttributes;		// attributes of file
}ACK_FILE_LIST_RECORD, *PACK_FILE_LIST_RECORD;

typedef struct _ACK_FILE_LIST_
{
	ACK_FILE_LIST_COMMON_HEADER common;
	ACK_FILE_LIST_RECORD records[1];
	uint16_t	crc;
}ACK_FILE_LIST, *PACK_FILE_LIST;

typedef struct _ACK_FILE_LIST_DETAILED_RECORD_
{
	char		fileName[11];		// padded file name
	uint32_t	fileID;				// ID of file
	uint32_t	fileSize;			// size of file
	DATE_TIME	creationDate;		// creation date from file
	DATE_TIME	modifiedDate;		// modified date from file
	uint8_t		fileAttributes;		// attributes of file
	uint16_t	providedCRC;		// CRC provided at initialization
	MD5			providedMD5;		// MD5 provided at initialization
	uint16_t	calculatedCRC;		// CRC calculated at last check
	MD5			calculatedMD5;		// MD5 calculated at last check
}ACK_FILE_LIST_DETAILED_RECORD, *PACK_FILE_LIST_DETAILED_RECORD;

typedef struct _ACK_FILE_LIST_DETAILED_
{
	ACK_FILE_LIST_COMMON_HEADER common;
	ACK_FILE_LIST_DETAILED_RECORD records[1];
	uint16_t	crc;
}ACK_FILE_LIST_DETAILED, *PACK_FILE_LIST_DETAILED;

typedef struct _ACK_FILE_AT_DEST_
{
	uint16_t	storageControllerAddress;
	uint32_t	fileID;
	uint16_t	crc;
}ACK_FILE_AT_DEST, *PACK_FILE_AT_DEST;

typedef struct _ACK_NEW_FILE_AVAILABLE_
{
	uint16_t	storageControllerAddress;	// storage controller reporting new file
	char		fileName[11];		// padded file name
	uint32_t	fileSize;			// size of file
	DATE_TIME	creationDate;		// creation date from file
	DATE_TIME	modifiedDate;		// modified date from file
	uint8_t		fileAttributes;		// attributes of file
	uint16_t	providedCRC;		// CRC provided at initialization
	MD5			providedMD5;		// MD5 provided at initialization
	uint16_t	calculatedCRC;		// CRC calculated at last check
	MD5			calculatedMD5;		// MD5 calculated at last check
	uint16_t	crc;
}ACK_NEW_FILE_AVAILABLE, *PACK_NEW_FILE_AVAILABLE;

enum ConsoleResponses
{
	CONSOLE_RESPONSE_OK								= 1,
	CONSOLE_RESPONSE_OK_TRUNCATED					= 2,
	CONSOLE_RESPONSE_UNKNOWN_CMD					= 10,
	CONSOLE_RESPONSE_DEVICE_BUSY					= 11,
	CONSOLE_RESPONSE_UNSUPPORTED_CMD				= 12,
	CONSOLE_RESPONSE_EMPTY_CMD						= 13,
	CONSOLE_RESPONSE_WRONG_DEVICE					= 14,
	CONSOLE_RESPONSE_CMD_FAILED						= 15,
	CONSOLE_RESPONSE_DEVICE_NOT_RESPONDING			= 16,
	CONSOLE_RESPONSE_INVALID_CMD_LENGTH				= 30,
	CONSOLE_RESPONSE_UNKNOWN_DESTINATION			= 31
};

/*typedef struct _CONSOLE_RESPONSE_INFO_
{
	uint16_t	source;
	uint8_t		status;
	uint8_t		format;
	uint8_t		length;
	uint32_t	id;
}CONSOLE_RESPONSE_INFO, *PCONSOLE_RESPONSE_INFO;

enum ConsoleBufferSizes
{
	ConsoleBufferMaxIn = 256,
	ConsoleBufferMaxOut = 1024
};

typedef struct _CONSOLE_CMD_FORMAT_
{
	uint16_t	cmdSrcAddress;
	uint8_t		functionCode;
	uint16_t	cmdSize;
	uint32_t	id;
	char		cmd[ConsoleBufferMaxIn];
}CONSOLE_CMD_FORMAT, *PCONSOLE_CMD_FORMAT; */

enum EUnsolcitedMsgType
{
	UNSOLICITED_SHORE_TO_SHIP = 1,
	UNSOLICITED_SHIP_TO_SHORE = 2
};

typedef struct _LRI_FORWARD_INFO_
{
	uint8_t		msgFormat;
	uint16_t	destination;
	uint16_t	source;
}LRI_FORWARD_INFO, *PLRI_FORWARD_INFO;

typedef struct _CONSOLE_ACK_
{
	uint8_t		format;
	uint8_t		disposition;
	uint16_t	len;
	uint8_t		msgData[0];
}CONSOLE_ACK, *PCONSOLE_ACK;

typedef struct _CONSOLE_NACK_
{
	uint16_t	numDispositions;
	uint8_t		disposition[1];
}CONSOLE_NACK, *PCONSOLE_NACK;

typedef struct _NAK_WITH_DESCRIPTION
{
	uint16_t    descriptionLength;
	uint8_t     sequenceNumber;
	uint8_t     description[0];
}NAK_WITH_DESCRIPTION, *PNAK_WITH_DESCRIPTION;

/*typedef struct _CONSOLE_ACK_XMIT_
{
	PIB_IRIDIUM_DATA_XMIT_EXT	comm;
	union
	{
		CONSOLE_ACK		consoleAck;
		CONSOLE_NACK	consoleNack;
	};
}CONSOLE_ACK_XMIT, *PCONSOLE_ACK_XMIT;

typedef struct _CONSOLE_ACK_XMIT_2_
{
	PIB_DATA_FORWARD_MESSAGE	comm;
	union
	{
		CONSOLE_ACK		consoleAck;
		CONSOLE_NACK	consoleNack;
	};
}CONSOLE_ACK_XMIT_2, *PCONSOLE_ACK_XMIT_2;
*/

//Nak Dispositions
enum ENakDispositions
{
	NAKDISP_SUCCEEDED				= 3,		// this item succeeded, other items failed
	NAKDISP_DATA					= 5,		// something was wrong with the data
	NAKDISP_FILE_IN_USE				= 7,		// file exists and is in use
	NAKDISP_WOULD_OVERWRITE			= 8,		// file exists (new file would overwrite)
	NAKDISP_READ_ONLY				= 9,		// file is marked as read-only
	NAKDISP_MISSING_STORAGE			= 10,		// storage device is missing, cannot be mounted
	NAKDISP_CRC_FAILED				= 11,		// calculated CRC of file content does not match provided number
	NAKDISP_MD5_FAILED				= 12,		// calculated MD5 of file content does not match provided signature
	NAKDISP_STORAGE_FULL			= 13,		// storage device is full
	NAKDISP_STORAGE_IO_ERROR		= 14,		// there was a problem talking to the storage device
	NAKDISP_BAD_FILE_CONTROL_BLOCK 	= 15,		// there is a problem with the control blocks that describe the file
	NAKDISP_BAD_PROG_SELECT			= 16,		// there is a problem with the configuration of program selection
	NAKDISP_TOO_MANY_COMMANDS		= 17		// there are too many active commands
};

typedef struct _NAK_DISPOSITIONS_
{
	uint16_t	countDispositions;
	uint8_t		disposition[1];
	uint16_t	crc;
}NAK_DISPOSITIONS, *PNAK_DISPOSITIONS;

#pragma pack(push,1)
typedef struct _LRI_COMMAND_DATA_REQUEST_ACK_WRAPPER_
{
	uint16_t	commandFormat;
	//char		startOfCommand;
}LRI_COMMAND_REQUEST_ACK_WRAPPER, *PLRI_COMMAND_REQUEST_ACK_WRAPPER;
#pragma pack(pop)

/*#pragma pack(push,1)
typedef struct _NAK_FILE_
{
	uint16_t	count;		//always one for this application
	uint8_t		result;
	uint16_t	crc;
}NAK_FILE, *PNAK_FILE;
#pragma pack(pop)

#pragma pack(push,1)
typedef struct _FILE_ACKS_
{
	LRI_COMM_WRAPPER headers;
	LRI_GENERIC_ACK	 ackInfo;
	COMM_HEADER		toShoreheader;
	union
	{
		ACK_READ_FILE ackRead;
		ACK_FILE_LIST ackFileInfo;
		uint16_t crc;
	};

}FILE_ACKS, *PFILE_ACKS;
#pragma pack(pop)

#pragma pack(push,1)
typedef struct _FILE_NACKS_
{
	LRI_COMM_WRAPPER headers;
	LRI_GENERIC_NAK	 nakInfo;
	COMM_HEADER		toShoreheader;
	union
	{
		NAK_FILE	nakFile;
		uint16_t crc;
	};
}FILE_NAKS, *PFILE_NAKS;
#pragma pack(pop)
 *
 */

typedef struct _SYSTEM_ALARMS_
{
	//System Alarms -- 2 Bytes
	//Bit fields for Byte 0 Alarms
	uint8_t 	subLeak:1;			//Sub Leak Alarm 					Bit 0
	uint8_t 	floatLeak:1;		//Float Leak Alarm 					Bit 1
	uint8_t 	subFloatCommErr:1;	//Sub to Float Comm					Bit 2
	uint8_t 	subBattery:1;		//Overloaded with Payload Alarm (Sub Battery Not Used Otherwise)		Bit 3
	uint8_t 	floatBattery:1;		//Float Battery Low					Bit 4
	uint8_t 	floatShieldFault:1;	//Umbilical Fault					Bit 5
	uint8_t 	subPressure:1;		//Sub Pressure						Bit 6
	uint8_t 	invalidGPS:1;		//Invalid GPS Value					Bit 7

	//Bit Fields for Byte 1 Alarms
	uint8_t 	componentCommErr:1;	//Charge Controller or Bubble Communication Error			Bit 0
	uint8_t 	subReboot:1;		//Sub Reboot						Bit 1
	uint8_t 	floatSubComErr:1;	//Float To Sub Comm					Bit 2
	uint8_t 	overCurrent:1;		//Over Current						Bit 3
	uint8_t 	floatTemp:1;		//Float Temp						Bit 4
	uint8_t 	floatPressure:1;	//Float Pressure					Bit 5
	uint8_t 	subTemp:1;			//Sub Temp							Bit 6
	uint8_t 	floatReboot:1;		//Float Reboot						Bit 7

}SYSTEM_ALARMS, *PSYSTEM_ALARMS;

typedef struct _SYSTEM_ALARMS_2_
{
	//Bit Fields for previous "reservedByte" field in telemetry 6
	uint8_t		readTransTimeout:1;	//Read Transaction Timeout			Bit 0
	uint8_t     fallbackImageActivated : 1; //                          Bit 1
	uint8_t     programImageBurned : 1; //                              Bit 2
	uint8_t     fallbackImageBadOrNotFound : 1; //                      Bit 3
	uint8_t     selectedImageBadOrNotFound : 1; //                      Bit 4
	uint8_t     tentativeImageRetry : 1; //                             Bit 5
	uint8_t		bootConfigCorrupt : 1;	//                              Bit 6
}SYSTEM_ALARMS_2, *PSYSTEM_ALARMS_2;

//Extended Telemetry Packet
typedef struct _TELEMETRY_06_
{
	SYSTEM_ALARMS alarms;
	int16_t		floatTempBoard;
	int32_t		latitude;
	int32_t		longitude;
	uint8_t 	fixHour;
	uint8_t 	fixMin;
	uint8_t 	fixSec;
	uint8_t 	fixMonth;
	uint8_t 	fixDay;
	uint8_t 	fixYear;	//Year is actually Year - 2000 (2008==>08)
	//uint8_t reservedByte; === now used for flags
	SYSTEM_ALARMS_2 alarms2;
	int16_t		subTempBoard;
	uint16_t	cumulativeDistance;
	uint32_t	rudderCount;
	uint16_t 	headingSub;
	uint8_t 	iridiumSignal;
	uint8_t 	targetWaypt;
	uint16_t 	desiredBearing;
	uint16_t 	headingFloat;
	uint8_t 	floatPressure;
	uint8_t 	subPressure;
	uint8_t 	navigationMode;
	uint8_t		ledStatus:1;
	uint8_t		irStatus:1;
	uint8_t		rfStatus:1;
	uint8_t		payload1Status:1;
	uint8_t		payload2Status:1;
	uint8_t		payloadSubStatus:1;
	uint8_t		bubbleCommError:1;
	uint8_t		batteryCommError:1;
	uint8_t		resetFlags;
	uint16_t	totalPowerRemaining;
	uint8_t		iridiumReadErrorCount;
	uint8_t		iridiumWriteErrorCount;
	uint8_t		iridiumSessionErrorCount;
	uint8_t		reservedBytes[10];
	uint16_t	crc;
}TELEMETRY_06, *PTELEMETRY_06;

//Power Status Telemetry Packet
typedef struct _TELEMETRY_07_
{
	uint8_t hour;
	uint8_t minute;
	uint8_t second;
	uint8_t month;
	uint8_t day;
	uint8_t year;	//Value + 2000 = Year
	SYSTEM_CHARGE_STATUS systemCharge;
	BATTERY_INFORMATION batteryInfo[MAX_NUM_BATTERIES];
	uint16_t	crc;
}TELEMETRY_07, *PTELEMETRY_07;

//PID Navigation Status Telemetry Packet
typedef struct _TELEMETRY_08_
{
	uint8_t hour;
	uint8_t minute;
	uint8_t second;
	uint8_t month;
	uint8_t day;
	uint8_t year;	//Value + 2000 = Year
	PID_NAVIGATION navPIDParameters;
	int32_t pidIntegralCache[PID_NUM_BINS];
	uint16_t	crc;
}TELEMETRY_08, *PTELEMETRY_08;

typedef struct _TELEMETRY_91_SAMPLE0_
{
	int32_t latitude;
	int32_t longitude;
	uint32_t sampleTime_T;
}TELEMETRY_91_SAMPLE0, *PTELEMETRY_91_SAMPLE0;

template<typename T, int SZ = 1>
struct TELEMETRY_91_SAMPLE : public TELEMETRY_91_SAMPLE0
{
	T samples[SZ];
};

typedef struct _TELEMETRY_91_
{
	typedef boost::shared_ptr<_TELEMETRY_91_> Ptr;

	_TELEMETRY_91_(bool init = false)
	{
		if (init)
			memset(this, '\0', sizeof(*this));
	}

	void Set(uint32_t _payloadType, uint16_t _boardAddress, uint8_t _formatCode, uint8_t _repeatCount = 1, bool _ascii = false, uint8_t _priority = 0)
	{
		payloadType = _payloadType;
		payloadBoardID = _boardAddress >> 8;
		payloadTaskID = _boardAddress & 0xFF;
		formatInfo = (_formatCode & 7) | (_ascii ? 8 : 0) | ((_priority & 7) << 4);
		repeatCount = _repeatCount;
	}

	bool GetASCII() const
	{
		return !!(formatInfo & 8);
	}

	void SetASCII(bool ascii = true)
	{
		if (ascii)
			formatInfo |= 8;
		else
			formatInfo &= ~8;
	}

	uint8_t GetFormatCode() const
	{
		return formatInfo & 7;
	}

	void SetFormatCode(uint8_t newValue)
	{
		formatInfo &= ~7;
		formatInfo |= (newValue & 7);
	}

	uint8_t GetPriority() const
	{
		return (formatInfo >> 4) & 7;
	}

	void SetPriority(uint8_t newValue)
	{
		formatInfo &= 0xF;
		formatInfo |= (newValue & 7) << 4;
	}

	uint32_t payloadType;
	uint8_t payloadBoardID;
	uint8_t payloadTaskID;
	uint8_t formatInfo;
	uint8_t repeatCount;
	TELEMETRY_91_SAMPLE0 samples[0];

}TELEMETRY_91, *PTELEMETRY_91;

typedef struct _COMM_MGR_TX_BUFFER_
{
	COMM_HEADER		header;
	union
	{
//		TELEMETRY_05		telemetry;
		TELEMETRY_06		telemetryXtnd;
		TELEMETRY_07		telemetryPower;
		ACK_POWER			ackPowerStatus;
		ACK_ID				ackSystemID;
		ACK_RUDDER			ackRudderParams;
		ACK_NAK				ackBasic;
		ACK_NAK_STATUS		ackStatus;
		ACK_DEBUG			ackDebug;
		ACK_SUB_HEADING		ackSubHeading;
		ACK_INTEGRAL		ackIntegral;
		ACK_PID_PARAMS		ackPIDParams;
		ACK_ALL_PARAMS		ackAllParams;
		ACK_UNIQUE_ID		ackUniqueID;
		ACK_READ_FILE		ackReadFile;
		ACK_FILE_LIST		ackGetFileList;
		ACK_FILE_LIST_COMMON_HEADER ackFileListCommon;
		ACK_FILE_LIST_DETAILED ackGetDetailedFileList;
		ACK_FILE_AT_DEST	ackFileAtDest;
		ACK_NEW_FILE_AVAILABLE ackNewFileAvailable;
		NAK_DISPOSITIONS	nakDispositions;
		uint8_t				testBuffer[275];
		uint8_t				sizer[COMM_MAX_TX_MSG - sizeof(COMM_HEADER)];
	};
}COMM_MGR_TX_BUFFER, *PCOMM_MGR_TX_BUFFER;

typedef struct _COMM_MGR_FILE_TX_BUFFER_
{
	COMM_HEADER		header;
	union
	{
//		TELEMETRY_05		telemetry;
		TELEMETRY_06		telemetryXtnd;
		TELEMETRY_07		telemetryPower;
		ACK_POWER			ackPowerStatus;
		ACK_ID				ackSystemID;
		ACK_RUDDER			ackRudderParams;
		ACK_NAK				ackBasic;
		ACK_NAK_STATUS		ackStatus;
		ACK_DEBUG			ackDebug;
		ACK_SUB_HEADING		ackSubHeading;
		ACK_INTEGRAL		ackIntegral;
		ACK_PID_PARAMS		ackPIDParams;
		ACK_ALL_PARAMS		ackAllParams;
		ACK_UNIQUE_ID		ackUniqueID;
		ACK_READ_FILE		ackReadFile;
		ACK_FILE_LIST		ackGetFileList;
		ACK_FILE_LIST_COMMON_HEADER ackFileListCommon;
		ACK_FILE_LIST_DETAILED ackGetDetailedFileList;
		ACK_FILE_AT_DEST	ackFileAtDest;
		ACK_NEW_FILE_AVAILABLE ackNewFileAvailable;
		NAK_DISPOSITIONS	nakDispositions;
		uint8_t				sizer[COMM_MAX_FILE_TX_MSG - sizeof(COMM_HEADER)];
	};
}COMM_MGR_FILE_TX_BUFFER, *PCOMM_MGR_FILE_TX_BUFFER;


typedef struct _COMM_MGR_RX_BUFFER_
{
	COMM_HEADER		header;
	CMD_FMT_COMMON	type;
	union
	{
		CMD_FMT_10	command;
		CMD_FMT_11	status;
		CMD_FMT_15	params;
		CMD_FMT_16	rudder;
		CMD_FMT_18  initFileWrite;
		CMD_FMT_19  writeFile;
		CMD_FMT_1A  deleteFile;
		CMD_FMT_1B  readFile;
		CMD_FMT_1C  getFileListDetailed;
		CMD_FMT_1E  consoleInput;
		CMD_FMT_31  getFileList;
		uint8_t		sizer[COMM_MAX_RX_MSG - (sizeof(COMM_HEADER) + sizeof(CMD_FMT_COMMON))];

	};
}COMM_MGR_RX_BUFFER, *PCOMM_MGR_RX_BUFFER;

typedef struct _COMM_MGR_BUBBLE_STATE_
{
	uint8_t powerGPS;
	uint8_t powerRF;
	uint8_t powerLED;
	uint8_t powerIR;
}COMM_MGR_BUBBLE_STATE, *PCOMM_MGR_BUBBLE_STATE;

#pragma pack(pop)

// command types (CMD_FMT_COMMON.command)
enum ECommands
{
	CMD_COMMENT									= 0,				// not supported by SV2 Float C&C
	CMD_HOLD_CURRENT_POS						= 0x0001,
	CMD_HOLD_AT_WAYPT							= 0x0002,
	CMD_SEQUENTIAL_COURSE						= 0x0003,
	CMD_CUSTOM_COURSE							= 0x8101,
	CMD_CUSTOM_COURSE_PLUS						= 0x8102,
	CMD_RIGHT_RUDDER							= 0x0004,
	CMD_LEFT_RUDDER								= 0x0005,
	CMD_CENTER_RUDDER							= 0x0006,
	CMD_CUSTOM_RUDDER							= 0x1006,
	CMD_FOLLOW_HEADING							= 0x0008,
	CMD_SET_DEFAULT_COMM_CHANNEL 				= 0x000A,
	CMD_READ_UNIQUE_ID							= 0x000E,
	CMD_SET_UNIQUE_ID							= 0x000F,
	CMD_TOGGLE_MARKER_LIGHT						= 0x2000,
	CMD_LIGHT_OFF								= 0x2001,
	CMD_LIGHT_ON								= 0x2002,
	CMD_IR_LIGHT_OFF							= 0x2003,
	CMD_IR_LIGHT_ON								= 0x2004,
	CMD_RF_OFF									= 0x2005,
	CMD_RF_ON									= 0x2006,
	CMD_GET_STATUS								= 0x4001,
	CMD_SET_STATUS								= 0x4002,
	CMD_GET_IDENTIFICATION						= 0x4003,
	CMD_GET_POWER_STATUS						= 0x5001,
	CMD_GET_RUDDER_PARAMS						= 0x5002,
	CMD_SET_RUDDER_PARAMS						= 0x5003,
	CMD_SET_PARAMETERS							= 0x6000,
	CMD_GET_ERROR_COUNTS						= 0x7000,
	CMD_GET_SUB_HEADING							= 0x7001,
	CMD_GET_INTEGRAL							= 0x7002,
	CMD_GET_PID_PARAMS							= 0x7003,
	CMD_NEW_WAYPT								= 0x8000,
	CMD_NEW_WAYPTS								= 0x8001,
	CMD_CLR_WAYPTS								= 0x8002,
	CMD_READ_WAYPT								= 0x8003,
	CMD_ADD_MMSI_TO_WATCH_LIST					= 0x8200,
	CMD_INIT_FILE_WRITE							= 0x9000,
	CMD_WRITE_FILE_BLOCK						= 0x9001,
	CMD_DELETE_FILE								= 0x9002,
	CMD_READ_FILE_REQUEST						= 0x9003,
	CMD_GET_DETAILED_FILE_LIST 					= 0x9004,
	CMD_SELECT_PROGRAM							= 0x9005,
	CMD_WRITE_CONSOLE_INPUT 					= 0x9006,
	CMD_READ_FILE_TRANSACTION_CLOSED 			= 0x9007,
	CMD_GET_FILE_LIST							= 0x9008,
	CMD_WRITE_CNSL_CMD_ASCII					= 0x9100,
	CMD_WRITE_CNSL_CMD_BINARY					= 0x9101,
	CMD_FLOAT_REBOOT							= 0xA000,
	CMD_SECURE_ON								= 0xA500,
	CMD_SECURE_AUTHENTICATE						= 0xA501,
	CMD_SECURE_REGISTER_CLIENT					= 0xA502,
	CMD_SECURE_OFF								= 0xA504,
	CMD_SECURE_ENABLE_PARTITION					= 0xA505,
	CMD_SECURE_ON_2								= 0xA51E,
	CMD_RETRIEVE_LOG_FILE						= 0xB001,
	CMD_BINARY_BLOCK							= 0xE000,
	CMD_PAYLOAD_CMD								= 0xF000,
};

// packet types for messages received (COMM_HEADER.type)
enum EPacketTypeRecive
{
	RCV_CMD										= 0x0A,
	RCV_SETTINGS								= 0x0B,
	RCV_ENCRYPTED_COMMAND_PACKET				= 0xA7,
};

// packet types for messages sent, acks or unsolicited events (COMM_HEADER.type)
enum EPackTypeSend
{
	SND_TELEMETRY								= 0x06,			// unsolicited
	ACK_WITH_SETTINGS_WAYPT						= 0x10,
	ACK_WITH_SETTINGS							= 0x11,
	ACK_WITH_ID									= 0x12,
	ACK_BASIC									= 0x13,
	ACK_WITH_POWER								= 0x14,
	ACK_WITH_RUDDER								= 0x15,
	ACK_WITH_DEBUG								= 0x16,
	ACK_WITH_SUB_HEADING						= 0x17,
	ACK_WITH_INTEGRAL							= 0x18,
	ACK_WITH_PID_PARAMS							= 0x19,
	ACK_WITH_ALL_PARAMS							= 0x1A,
	ACK_WITH_READ_FILE							= 0x1B,
	ACK_WITH_LIST_DETAILED						= 0x1C,
	SND_CONSOLE_OUTPUT							= 0x1D,			// unsolicited (at least sometimes)
	ACK_WITH_UNIQUE_ID							= 0x1E,
	ACK_WITH_FILE_AT_DEST						= 0x1F,

	NAK_CMD_BASIC								= 0x22,
	NAK_DATA_BASIC								= 0x23,
	NAK_DATA_ENUMERATED							= 0x24,
	NAK_SECURITY								= 0x25,
	NACK_CONSOLE_DATA							= 0x26,
	NACK_WITH_DESCRIPTION						= 0x27,

	ACK_WITH_FILE_LIST							= 0x31,
	ACK_CONSOLE_DATA							= 0x3D,

	SND_IRIDIUM_MT_RESERVED						= 0x44,

	SND_NEW_FILE_AVAILABLE						= 0x60,			// unsolicited

	SND_RELAY_STATUS							= 0x70,
	SND_SYSTEM_INFO								= 0x71,			// same format as 0x91

	SND_SINGLE_PAYLOAD_PACKET					= 0x80,
	SND_MULTI_PAYLOAD_PACKET					= 0x81,
	SND_SINGLE_PAYLOAD_PACKET_RECORD			= 0x82,

	SND_PAYLOAD_PACKET							= 0x90,
	SND_PAYLOAD_PACKET_91						= 0x91,
	SND_PAYLOAD_PACKET_RECORD					= 0x92,

	ACK_SECURE_ON_2								= 0xA1,
	ACK_SECURE_ON								= 0xA5,


	SND_ENCRYPTED_PACKET						= 0xA6,
};

enum ESystemInfoTypes
{
	SYSINFO_SMC_PARTITION_STATE					= 1,
	SYSINFO_EVENT_RECORD						= 2,
	SYSINFO_AMPS_POWER_STATUS_RECORD			= 4,
	SYSINFO_EVENT_RECORD_V2						= 5,
	SYSINFO_SMC_MOBILE_WGMS_HEARTBEAT				= 10,
	SYSINFO_SMC_MOBILE_WGMS_SYNCH					= 11
};

enum ESystemInfoSMCPartitionStateSubType
{
	SYSINFOSMCPARTITIONSTATE_SUBTYPE_0			= 0
};

enum ESystemInfoSMCPartitionStateValues
{
	SYSINFOSMCPARTITIONSTATEVALUE_DISABLED		= 0,
	SYSINFOSMCPARTITIONSTATEVALUE_ENABLED		= 1
};

// structure ID's used (CMD_FMT_COMMON.fmtID)
enum ECmdStructureID
{
	FMT_RCV_CMD									= 0x10,
	FMT_RCV_SETTINGS							= 0x11,
	FMT_RCV_CRS_LST								= 0x12,
	FMT_RCV_SET_PARAMS							= 0x15,
	FMT_RCV_STEER								= 0x16,
	FMT_RCV_INIT_FILE_WRITE						= 0x18,
	FMT_RCV_WRITE_FILE_BLK						= 0x19,
	FMT_RCV_DELETE_FILE							= 0x1A,
	FMT_RCV_READ_FILE_REQ						= 0x1B,
	FMT_RCV_GET_FILE_LIST_D 					= 0x1C,
	FMT_RCV_CONSOLE_INPUT						= 0x1E,
	FMT_RCV_GET_FILE_LIST						= 0x31,
	FMT_RCV_SECURE_ON							= 0x64,
	FMT_RCV_SECURE_AUTHENTICATE					= 0x65,
	FMT_RCV_SECURE_REGISTER_CLIENT				= 0x66,
};

SHARED_LIB_PUBLIC std::ostream& Cmd_ToStream(std::ostream& out, uint16_t cmdNum);
SHARED_LIB_PUBLIC std::ostream& CmdStructID_ToStream(std::ostream& out, uint8_t structID);
SHARED_LIB_PUBLIC std::ostream& PacketType_ToStream(std::ostream& out, uint8_t packetType);
SHARED_LIB_PUBLIC std::ostream& RxPacketType_ToStream(std::ostream& out, uint8_t packetType);
SHARED_LIB_PUBLIC std::ostream& TxPacketType_ToStream(std::ostream& out, uint8_t packetType);

SHARED_LIB_PUBLIC std::ostream& operator<<(std::ostream& out, const COMM_HEADER& header);

enum EFloatMessageFormat
{
	FLOAT_MESSAGE_FORMAT_ICD_1					= 1,
};

enum EFloatServerTargetIDS
{
	FLOAT_TARGET_COMMAND_INTERFACE 				= 0x0001,		// command execution on float
	FLOAT_TARGET_IRIDIUM_INTERFACE 				= 0x0002,		// sending telemetry
	FLOAT_TARGET_DEBUG_INTERFACE 				= 0x0003,		// debug message output
	FLOAT_TARGET_XBEE 							= 0x0004,		// not currently used
	FLOAT_TARGET_FILE_TRANSFER_TO_SHORE 		= 0x0005,		// new file available messages to shore
	FLOAT_TARGET_SHORE_VIA_IRIDIUM				= 0x000A,
	FLOAT_TARGET_SHORE_VIA_XBEE					= 0x000B,
	FLOAT_TARGET_DATA_INTERFACE					= 0x0010,
	FLOAT_TARGET_FORWARD_MESSAGE				= 0x0020
};

// pack this after an Ack header with variable-length debug data to follow
#pragma pack(push,1)
typedef struct _LRI_XBEE_DATA_REQUEST_ACK_WRAPPER_
{
    enum EOutputFormat
    {
        DEBUG_ASCII = 0,
        DEBUG_HEX = 1
    };

	uint8_t		outputFormat;   // set to 0 for ASCII output or 1 for hex dump
	uint8_t		debugLevel;   // debug level threshold, 5?
	uint16_t	size;  // length of debug data to follow
}LRI_XBEE_DATA_REQUEST_ACK_WRAPPER, *PLRI_XBEE_DATA_REQUEST_ACK_WRAPPER;
#pragma pack(pop)

struct XBeeDataRequestWrapper : public LRI_XBEE_DATA_REQUEST_ACK_WRAPPER
{
	XBeeDataRequestWrapper(uint16_t _size = 0, uint8_t _debugLevel = 5, EOutputFormat _outputFormat = DEBUG_ASCII);
	XBeeDataRequestWrapper(const std::string& data, uint8_t _debugLevel = 5, EOutputFormat _outputFormat = DEBUG_ASCII);

	typedef boost::shared_ptr<std::string> StringPtr;
	StringPtr savedData;
};

struct SHARED_LIB_PUBLIC Level2Wrapper
{
	typedef LiquidRobotics::SMACFramework::ByteArray ByteArray;

	enum CRCInclusion
	{
		WITHOUT_CRC,
		WITH_CRC
	};

	Level2Wrapper(CRCInclusion _crcInclusion = WITH_CRC);
	Level2Wrapper(uint8_t _type, const ByteArray& _level1Data, CRCInclusion _crcInclusion = WITH_CRC, bool _fsReportIncludeLength = false); // FSReport
	Level2Wrapper(uint8_t _type, uint32_t _packetID, const ByteArray& _level1Data, CRCInclusion _crcInclusion = WITH_CRC);

	uint16_t CalculateCRC() const;

	COMM_HEADER commHeader;
	ByteArray level1Data;
	uint16_t crc;
	const bool fsReport;
	const bool fsReportIncludeLength;
	CRCInclusion crcInclusion;
};

struct SHARED_LIB_PUBLIC ConsoleAck : public CONSOLE_ACK
{
	typedef LiquidRobotics::SMACFramework::ByteArray ByteArray;

	ConsoleAck(uint8_t _format, uint8_t _disposition, const ByteArray& _additionalData);

	ByteArray additionalData;
};

struct SHARED_LIB_PUBLIC NakWithDescription : public NAK_WITH_DESCRIPTION
{
	typedef LiquidRobotics::SMACFramework::ByteArray ByteArray;

	NakWithDescription(uint8_t _sequenceNumber, const ByteArray& _additionalData);

	ByteArray additionalData;
};

struct SHARED_LIB_PUBLIC ForwardInfo : public LRI_FORWARD_INFO
{
	ForwardInfo(uint8_t _msgFormat, uint16_t _destination, uint16_t _source);
};

struct SHARED_LIB_PUBLIC NewFileAvailable : public ACK_NEW_FILE_AVAILABLE
{
	NewFileAvailable();
};

SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, COMM_HEADER& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const COMM_HEADER& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, Level2Wrapper& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const Level2Wrapper& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, ConsoleAck& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const ConsoleAck& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, NakWithDescription& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const NakWithDescription& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, LRI_FORWARD_INFO& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const LRI_FORWARD_INFO& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, NewFileAvailable& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const NewFileAvailable& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, DATE_TIME& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const DATE_TIME& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, LRI_COMMAND_REQUEST_ACK_WRAPPER& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const LRI_COMMAND_REQUEST_ACK_WRAPPER& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, TELEMETRY_91& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const TELEMETRY_91& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, TELEMETRY_91_SAMPLE0& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const TELEMETRY_91_SAMPLE0& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, CMD_FMT_COMMON& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const CMD_FMT_COMMON& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, CMD_FMT_10& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const CMD_FMT_10& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, CMD_FMT_18& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const CMD_FMT_18& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, CMD_FMT_19& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const CMD_FMT_19& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, CMD_FMT_1A& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const CMD_FMT_1A& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, CMD_FMT_1B& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const CMD_FMT_1B& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, CMD_FMT_1C& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const CMD_FMT_1C& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, CMD_FMT_1E& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const CMD_FMT_1E& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, ACK_READ_FILE& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const ACK_READ_FILE& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, ACK_FILE_LIST_COMMON_HEADER& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const ACK_FILE_LIST_COMMON_HEADER& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, ACK_FILE_LIST_RECORD& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const ACK_FILE_LIST_RECORD& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, ACK_FILE_LIST_DETAILED_RECORD& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const ACK_FILE_LIST_DETAILED_RECORD& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator>>(LiquidRobotics::SMACFramework::ByteStream& bs, XBeeDataRequestWrapper& data);
SHARED_LIB_PUBLIC LiquidRobotics::SMACFramework::ByteStream& operator<<(LiquidRobotics::SMACFramework::ByteStream& bs, const XBeeDataRequestWrapper& data);

}
}
}

#endif /* FCCMESSAGE_H_ */
