//#pragma hh #include "CosNotification.h"
#include "CosNotification.idl"
#include "CosNotifyComm.idl"
#include "CosEventComm.idl"

module LiquidRobotics
{
	module SMAC
	{
		exception TestException { string testmessage; };
		exception AlreadyRegistered { string message; };
		exception BadParameter { string parameterName; string message; };
		exception BadFileControlBlock { string message; };
		exception BadProgramSelectionConfig { string message; };
		exception CommFailure { string message; };
		exception CRCCheckFailed { string message; };
		exception FileHasBeenDeleted { string message; };
		exception FileInUse { string message; };
		exception FileIsReadOnly { string message; };
		exception MD5CheckFailed { string message; };
		exception NotReady { string message; };
		exception NotRegistered { string message; };
		exception StorageIOError { string message; };
		exception StorageIsFull { string message; };
		exception StorageIsMissing { string message; };
		exception TooManyConcurrentCommands { string message; };
		exception TooManySubscribers { string message; };
		exception UnknownSubscriber { string message; };
		exception UnavailableInPowerOffState { string message; };
		exception WillCompleteAsynchronously { };
		exception WouldOverwriteFile { string message; };

		typedef octet BoardIDType;
		typedef sequence<octet> ByteArrayType;
		typedef unsigned short CRCType;
		typedef CosNotification::StructuredEvent EnumerationData;
		typedef unsigned long FilePosType;
		typedef ByteArrayType MD5Type;
		typedef sequence<string> ParentLocationType;
		typedef unsigned short PowerOffTimeType;
		typedef unsigned short PowerOnTimeType;
		typedef unsigned long RemoteFileIDType;
		typedef CosNotification::StructuredEvent SensorSample;
		typedef unsigned short SensorSampleIntervalType;
		typedef octet TaskIDType;
		typedef unsigned long long TimeStampType;

		const BoardIDType BROADCAST_BOARD_ID = 0xFF;
		const TaskIDType BROADCAST_TASK_ID = 0xFF;
		const BoardIDType NO_BOARD_ID = 0xFF;
		const TaskIDType NO_TASK_ID = 0xFF;

		struct PayloadDescription
		{
			BoardIDType boardID;			// board ID or FF if none
			TaskIDType taskID;			// task ID or FF if none
			string description;			// text description of item
			string ior;				// interoperable object reference to instance
			string readableName;			// this is optional (blank if none)
			string descriptiveJSON;			// JSON code to send to SV3 to describe the component
		};

		typedef sequence<PayloadDescription> PayloadDescriptionList;

		struct ComponentVersion
		{
			string versionString;			// string form of version number
			unsigned short majorVersion;		// major revision or 0
			unsigned short minorVersion;		// minor revision or 0
			unsigned short subminorVersion;		// subminor revision or 0
		};

		// Various states of communication
		enum ECommunicationState
		{
			ECS_START,						// device has not started up yet
			ECS_DISABLED,					// device is in disabled state, not attempting comm
			ECS_ESTABLISH_COMM,				// device is establishing communication, outcome is not known
			ECS_COMMUNICATING,				// device is communication has been established and thought to be operational
			ECS_COMM_FAIL					// device communication was lost, manual or auto transition to "establish comm" pending
		};

		// Various states of being enabled for use
		enum EPayloadEnableState
		{
			EPES_DISABLED,					// device is deactivated/powered off or ready for power off
			EPES_ENABLE_PENDING,			// device is enabled and initializing, not ready for access yet
			EPES_ENABLED,					// device is enabled and ready for use
			EPES_DISABLE_PENDING			// device is shutting down in preparation for power off
		};
		
		// Objects that can be pinged to determine if they are alive
		interface IPingable
		{
			// Call this interface to determine if the object is alive
			// (returns seconds and fractional seconds at server or
			// or may return 0 if not implemented)
			double Ping();
		};

		// Objects that receive events
		interface IEventReceiver : CosNotifyComm::StructuredPushConsumer
		{
		};
		
		const long LogError = 1;			// log entry for an error condition
		const long LogWarning = 2;			// log entry for a warning condition
		const long LogEvent = 4;			// log entry for an event
		const long LogMethod = 8;			// log entry for a method invocation
		const long LogProperty = 16;		// log entry for property set/get
		const long LogComment = 32;			// log entry for a comment
		
		typedef sequence<string> EMCF_Strings;
		
		// Parameter to IEventManager.SetCustomFilter
		struct EventManagerCustomFilter
		{
			boolean enabled;
			EMCF_Strings aliasToEventName;
			EMCF_Strings nameList;
			EMCF_Strings typeAndDomainList;
		};

		// Methods of my stand-in for CosNotification
		interface IEventManager
		{
			// Adds a subscriber object, which implements StructuredPushConsumer
			void AddSubscriber(in string ior)
				raises(BadParameter,TooManySubscribers);

			// Adds a subscriber object, which implements StructuredPushConsumer
			void AddSubscriber2(in string ior, in string nickName)
				raises(BadParameter,TooManySubscribers);
				
			// Adds a filter for an ior
			//long AddFilter(in string ior, in CosNotification::FixedEventHeader header, in CosNotification::FilterableEventBody filter)
			//	raises(BadParameter,UnknownSubscriber);

			// Removes a previously-subscribed item
			void DeleteSubscriber(in string ior)
				raises(BadParameter,UnknownSubscriber);

			// Removes an existing filter
			//void RemoveFilter(in string ior, in long filterKey)
			//	raises(BadParameter,UnknownSubscriber);
			
			// Sets the filter to be applied to the given IOR
			void SetCustomFilter(in string ior, in EventManagerCustomFilter filter)
				raises(BadParameter,UnknownSubscriber);
			
		};

		// Methods of a logging object
		interface ILogger
		{
			readonly attribute long logEnableMask;

			boolean Log(in TimeStampType timeStamp, in long logMask, in string componentName, in string message, in any data);
		};
		
		// This interface is implemented by all payload addressable devices (i.e.
		// every device)
		interface IPayloadDevice : IPingable
		{
			readonly attribute BoardIDType boardID;
			readonly attribute PayloadDescription description;
			readonly attribute EPayloadEnableState enableState;
			readonly attribute PowerOffTimeType requestOffTime;
			readonly attribute PowerOnTimeType requestOnTime;
			readonly attribute ComponentVersion softwareVersion;
			readonly attribute TaskIDType taskID;

			EnumerationData GetEnumerationData()
				raises(CommFailure,NotReady,UnavailableInPowerOffState);
			void PowerOff(in PowerOffTimeType offDelay)
				raises(NotReady);
			void PowerOn()
				raises(NotReady);
		};
		
		// Paylaod devices that receive events
		interface IPayloadDeviceWithEvents : IPayloadDevice, IEventReceiver
		{
		};

		// This structure represents the content of a storage controller directory entry
		struct SCDirectoryEntry
		{
			ParentLocationType parentLocation;
			string fileName;
			RemoteFileIDType remoteFileID;
			boolean remoteFile;
			FilePosType fileSize;
			TimeStampType creationDate;
			TimeStampType modifiedDate;
			boolean isComplete;
			boolean isReadOnly;
			boolean md5Verified;
			CRCType crcProvided;
			MD5Type md5Provided;
			CRCType crcCalculated;
			MD5Type md5Calculated;
		};

		// A sequence of directory entries is a directory list (or a directory)
		typedef sequence<SCDirectoryEntry> SCDirectoryList;

		// This interface represents a file (or file handle)
		interface ISCFile
		{
			readonly attribute SCDirectoryEntry directoryEntry;

			void CheckIntegrity()
				raises(BadFileControlBlock,BadParameter,CommFailure,CRCCheckFailed,FileHasBeenDeleted,MD5CheckFailed,NotReady,StorageIOError,StorageIsFull,StorageIsMissing,TooManyConcurrentCommands,UnavailableInPowerOffState);
			void Delete(in boolean overrideReadOnly)
				raises(BadFileControlBlock,BadParameter,CommFailure,FileInUse,FileIsReadOnly,FileHasBeenDeleted,NotReady,StorageIOError,StorageIsMissing,TooManyConcurrentCommands,UnavailableInPowerOffState);
			void Flush()
				raises(BadFileControlBlock,BadParameter,CommFailure,FileHasBeenDeleted,NotReady,StorageIOError,StorageIsFull,StorageIsMissing,TooManyConcurrentCommands,UnavailableInPowerOffState);
			ByteArrayType ReadBlock(in FilePosType offset, in FilePosType count)
				raises(BadFileControlBlock,BadParameter,CommFailure,FileHasBeenDeleted,NotReady,StorageIOError,StorageIsMissing,TooManyConcurrentCommands,UnavailableInPowerOffState);
			void WriteBlock(in FilePosType offset, in ByteArrayType content)
				raises(BadFileControlBlock,BadParameter,CommFailure,FileHasBeenDeleted,NotReady,StorageIOError,StorageIsFull,StorageIsMissing,TooManyConcurrentCommands,UnavailableInPowerOffState);
		};

		// This interface represents an array of files or hierarchy of files
		interface IStorageController
		{
			readonly attribute SCDirectoryList directory;

			ISCFile CreateFile(in SCDirectoryEntry directoryEntry, in boolean overwriteFile, in boolean permuteFileName, in boolean fat16Names)
				raises(BadFileControlBlock,BadParameter,CommFailure,FileInUse,FileIsReadOnly,FileHasBeenDeleted,NotReady,StorageIOError,StorageIsFull,StorageIsMissing,TooManyConcurrentCommands,UnavailableInPowerOffState,WouldOverwriteFile);
			SCDirectoryList GetDirectory(in ParentLocationType parentLocation, in boolean recursive)
				raises(BadFileControlBlock,BadParameter,CommFailure,NotReady,StorageIOError,StorageIsFull,StorageIsMissing,TooManyConcurrentCommands,UnavailableInPowerOffState);
			ISCFile GetFileByName(in string fileName, in boolean fat16Names)
				raises(BadFileControlBlock,BadParameter,CommFailure,NotReady,StorageIOError,StorageIsFull,StorageIsMissing,TooManyConcurrentCommands,UnavailableInPowerOffState);
			ISCFile GetFileByRemoteFileID(in RemoteFileIDType fileID)
				raises(BadFileControlBlock,BadParameter,CommFailure,NotReady,StorageIOError,StorageIsFull,StorageIsMissing,TooManyConcurrentCommands,UnavailableInPowerOffState);
		};

		// This interface is implemented by devices that communicate
		interface ICommDevice
		{
			readonly attribute ECommunicationState commState;
			attribute unsigned short autoRecoverInterval;		// 0=do not auto recover (must call StartEstablishComm())

			void DisableComm();
			void StartEstablishComm()
				raises(BadParameter,NotReady,UnavailableInPowerOffState);
		};

		// This interface is implemented by a process that caches payload object
		// references and makes the locators available in an array.
		interface IPayloadManager
		{
			readonly attribute BoardIDType defaultBoardID;
			readonly attribute PayloadDescriptionList payloadDescriptions;

			void Register(in PayloadDescription payload, in boolean overwrite)
				raises(AlreadyRegistered);
			void Unregister(in string ior)
				raises(NotRegistered);
		};
		
		// data for use with SendCommandWorkaround method of ICommandable
		struct SendCommandWorkaroundData
		{
			boolean exceptionThrown;			// true if exception was thrown, false if not thrown
			string exceptionName;				// name of exception that was thrown
			string param1;						// first parameter to exception (if applicable)
			string param2;						// second parameter to exception (if applicable)
		};
		
		// Objects that accept commands
		interface ICommandable
		{
			// Device accepts a command; if requester parameter is not empty and transaction ID is not empty,
			// it is permissible to throw WillCompleteAsynchronously and send an event upon completion later.
			// Otherwise, the result parameter contains the result. 
			void SendCommand(in any command, in string requester, in string transactionID, out any result)
				raises(BadParameter,CommFailure,NotReady,TooManyConcurrentCommands,UnavailableInPowerOffState,WillCompleteAsynchronously);

			// Workaround method that passes any exceptions back as data; no exceptions are thrown from this
			// method, except the native CORBA exceptions like TRANSIENT, which can't be helped				
			void SendCommandWorkaround(in any command, in string requester, in string transactionID, out any result, out SendCommandWorkaroundData waData);
		};
		
		// Objects that accept commands and also handle events
		interface ICommandableWithEvents : ICommandable, IEventReceiver
		{
		};
		
		// Objects that are both pingable and commandable
		interface IPingableCommandable : IPingable, ICommandable
		{
		};
		
		// Objects that are both pingable and commandable and receive evnets
		interface IPingableCommandableWithEvents : IPingableCommandable, IEventReceiver
		{
		};
		
		// Addressable payload devices that are commandable
		interface ICommandablePayloadDevice : IPayloadDevice, ICommandable
		{
		};
		
		// Addressable payload devices that are commandable that also receive events
		interface ICommandablePayloadDeviceWithEvents : ICommandablePayloadDevice, IEventReceiver
		{
		};

		// Sensors implement this interface
		interface ISensor : ICommandablePayloadDevice
		{
			readonly attribute ComponentVersion hardwareVersion;
			attribute SensorSampleIntervalType sensorSampleInterval;
			readonly attribute boolean samplePending;

			SensorSample SampleNow(in any sampleParameter)
				raises(CommFailure,NotReady,UnavailableInPowerOffState);
			void SetSamplePending(in any sampleParameter)
				raises(CommFailure,NotReady,UnavailableInPowerOffState);
		};
		
		// Sensors that want to receive events implement this interface
		interface ISensorWithEvents : ISensor, IEventReceiver
		{
		};
		
		// Sensors with storage controller exposed
		interface ISensorSC : ICommandablePayloadDevice, IStorageController
		{
		};
		
		// Sensors with storage controller exposed and event receiver
		interface ISensorSCWithEvents : ISensorSC, IEventReceiver
		{
		};
				
		// Demo interface also includes GPS to a particular sensor
		interface IDemoSensor : ISensor
		{
			void NoteGPSSample(in long dateTimeUTC, in boolean validFix, in double latitude, in double longitude);
		};
		
		// Demo interface with events (testing legacy Demo sensor with push consumer events)
		interface IDemoSensorWithEvents : IDemoSensor, IEventReceiver
		{
		};
		
		// Combination of interfaces for PayloadManger process
		interface IPayloadManagerProcess : IPingable, IPayloadManager, ICommandable
		{
		};

		// Combination of interfaces for the EventManager process
		interface IEventManagerProcess : IPingable, IEventManager, IEventReceiver
		{
		};
	};
};
