

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//_/_/
//_/_/  This file is part of CMSDK version 2.1.1.260726 (26 July 2026)
//_/_/  
//_/_/  developed by
//_/_/  
//_/_/  Communicative Machines Ltd. 
//_/_/    http://cmlabs.com/
//_/_/  Copyright (c) 2026
//_/_/  
//_/_/  in collaboration with 
//_/_/  
//_/_/  Icelandic Institute for Intelligent Machines ses
//_/_/    Menntavegur 1
//_/_/    101 Reykjavik
//_/_/    ICELAND
//_/_/    http://www.iiim.is/
//_/_/
//_/_/  and is released under the following
//_/_/  
//_/_/  EXTENDED BSD License
//_/_/
//_/_/  Redistribution and use in source and binary forms, with or without
//_/_/  modification, is permitted provided that the following conditions 
//_/_/  are met:
//_/_/
//_/_/  - Redistributions of source code must retain the above copyright 
//_/_/    and collaboration notice, this list of conditions and the following 
//_/_/    disclaimer.
//_/_/
//_/_/  - Redistributions in binary form must reproduce the above copyright 
//_/_/    notice, this list of conditions and the following disclaimer in the 
//_/_/    documentation and/or other materials provided with the distribution.
//_/_/
//_/_/  - Neither the name of its copyright holders nor the names of its 
//_/_/    contributors may be used to endorse or promote products derived from 
//_/_/    this software without specific prior written permission.
//_/_/
//_/_/  - CADIA Clause: The license granted in and to the software under this 
//_/_/    agreement is a limited-use license. The software may not be used in 
//_/_/    furtherance of: (i) intentionally causing bodily injury or severe 
//_/_/    emotional harm to any person; (ii) invading the personal privacy or 
//_/_/    violating the human rights of any person; or (iii) committing or 
//_/_/    preparing for any act of war. 
//_/_/
//_/_/  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
//_/_/  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
//_/_/  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
//_/_/  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
//_/_/  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
//_/_/  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
//_/_/  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
//_/_/  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
//_/_/  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
//_/_/  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
//_/_/  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//_/_/
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
/*! @file ControlMessage.h
	@brief Lightweight internal control/command message used by the Psyclone runtime.

	ControlMessages carry runtime commands (start, stop, ping, status, ...)
	between nodes and internal components. Like DataMessage they are a single
	flat memory block — a ControlMessageHeader optionally followed by an opaque
	payload — so they can be moved through shared memory and sockets verbatim.
	Unlike DataMessage they have no named user entries; they are deliberately
	minimal for low-overhead control-plane traffic.
	@ingroup Messaging
*/

#if !defined(_CONTROLMESSAGE_H_)
#define _CONTROLMESSAGE_H_

#include "PsyTime.h"
#include "ObjectIDs.h"

namespace cmlabs {


/*! @brief Wire/shared-memory header of a ControlMessage; any payload follows immediately after.
	@warning Binary contract — do not change field order or sizes.
	@ingroup Messaging
*/
struct ControlMessageHeader {
	uint32	size;	//!< Total block size in bytes (header + payload). auto
	uint32	cid;	//!< Object id, always CONTROLMESSAGEID for a valid message. auto
	uint64	time;	//!< Creation time in microseconds since epoch. auto/api
	uint64	from;	//!< Sender id (wider than DataMessage's: can encode node+component).
	uint64	to;		//!< Addressee id.

	uint16	command;//!< Command code — what the receiver should do. user
	uint16	status;	//!< Status/result code, typically filled in by the receiver. user
};

/*! @brief Wrapper class managing a single flat ControlMessage memory block.

	Provides typed access to the header fields of the underlying block pointed
	to by #data. Ownership: the (command, from, to, ...) constructor allocates
	a new block (payload bytes are copied); the char* constructor merely wraps
	the supplied block without copying.
	@warning The destructor does NOT free #data — it only clears the pointer.
	Whoever allocated the block (this class's first constructor, or the caller
	for the wrapping constructor) is responsible for releasing it, typically
	via the surrounding memory-management layer.
	@ingroup Messaging
*/
class ControlMessage {
public:
	/*! Create a new control message.
	@param command command code for the receiver
	@param from sender id
	@param to addressee id
	@param data optional payload bytes (copied), NULL for none
	@param dataSize payload size in bytes */
	ControlMessage(uint16 command, uint64 from, uint64 to, char* data = NULL, uint32 dataSize = 0);
	/*! Wrap an existing binary control message block without copying.
	@param data the binary block to wrap; caller retains ownership */
	ControlMessage(char* data);
	//! Destructor. @warning Does not free #data (see class notes on ownership).
	~ControlMessage();

	uint32 getSize();		//!< @return total block size in bytes, 0 if invalid.
	uint16 getCommand();	//!< @return the command code, 0 if invalid.
	uint64 getTime();		//!< @return creation time in microseconds, 0 if invalid.
	uint64 getFrom();		//!< @return sender id, 0 if invalid.
	uint64 getTo();			//!< @return addressee id, 0 if invalid.

	uint16 getStatus();				//!< @return the status/result code, 0 if invalid.
	/*! Set the status/result code.
	@param status new status value
	@return true if successful, false if the message is invalid */
	bool setStatus(uint16 status);

	//! Run the built-in self test. @return true if all tests pass.
	static bool UnitTest();

	//! The flat message block (ControlMessageHeader + payload); see class notes on ownership.
	char* data;
};

} // namespace cmlabs

#endif //_CONTROLMESSAGE_H_

