/*
 *                         Vortex OpenSplice
 *
 *   This software and documentation are Copyright 2006 to TO_YEAR ADLINK
 *   Technology Limited, its affiliated companies and licensors. All rights
 *   reserved.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
#ifndef VORTEX_FACE_ISOCPP2_Data_HPP_
#define VORTEX_FACE_ISOCPP2_Data_HPP_

#include "Vortex_FACE.hpp"
#include "Vortex/FACE/Macros.hpp"

namespace FACE {
namespace TS {

/**
 * The Initialize function call allows for the Portable Components Segment (PCS)  and Platform-Specific Services Segment (PSSS)
 * component to trigger the initialization of the Transport Services Segment (TSS) component.
 *
 * Possible return codes:
 * <ul>
 * <li>INVALID_PARAM - The provided configuration is not valid
 * <li>INVALID_CONFIG - The provided configuration contains invalid settings
 * <li>NO_ACTION - There is already an initialized configuration.
 * </ul>
 * @param configuration
 *        The configuration defined as an xml file which hold the connection configuration.
 *        This is an input parameter
 * @param return_code
 *        The return_code
 */
void Initialize(
        /* in    */ const FACE::CONFIGURATION_RESOURCE   &configuration,
        /* out   */       FACE::RETURN_CODE_TYPE         &return_code);

/**
 * The Transport Services Segment (TSS) provides an interface to create a connection.
 * The parameters for the individual connections are determined through the TSS configuration
 * capability which is set by the Initialize function call.
 *
 * Possible return codes:
 * <ul>
 * <li>NO_ERROR - Successful completion.</li>
 * <li>NO_ACTION - Returned if the participant has already been created and
 * registered. - Type has already been registered.</li>
 * <li>INVALID_CONFIG - Could not allocate enough memory. - Policies are not
 * consistent with each other (e.g., configuration data is invalid, QoS
 * attributes not supported).
 * <ul>
 * <li>Generic, unspecified error.</li>
 * <li>Attempted to modify an immutable QoSPolicy.</li>
 * </ul></li>
 * <li>INVALID_PARAM - Returned under the following conditions: - Could not
 * find topic name associated with the connection.</li>
 * <li>NOT_AVAILABLE - Unsupported operation.</li>
 * <li>INVALID_MODE - Connection could not be created in the current mode or
 * operation performed at an inappropriate type.</li>
 * </ul>
 *
 * @param connection_name
 *        The connection_name which needs to match one of the configured connection names in the configuration
 *        This is an input parameter.
 * @param pattern
 *        The pattern set in the connection configuration which for DDS only can be PUB_SUB.
 *        This is an input parameter.
 * @param connection_id
 *        The connection_id which is generated by DDS and set on successful creation.
 *        This is an output parameter.
 * @param connection_direction
 *        The connection_direction of the connection that is created. This can be SOURCE or DESTINATION.
 *        This is an output parameter.
 * @param max_message_size
 *        The max_message_size for DDS this parameter is not relevant.
 *        This is an output parameter.
 * @param timeout
 *        The timeout for DDS this parameter is not relevant.
 *        This is an input parameter.
 * @param return_code
 *        The return_code
 *        This is an output parameter.
 */
void Create_Connection(
        /* in    */ const FACE::CONNECTION_NAME_TYPE      &connection_name,
        /* in    */ const FACE::MESSAGING_PATTERN_TYPE    &pattern,
        /* out   */       FACE::CONNECTION_ID_TYPE        &connection_id,
        /* out   */       FACE::CONNECTION_DIRECTION_TYPE &connection_direction,
        /* out   */       FACE::MESSAGE_SIZE_TYPE         &max_message_size,
        /* in    */ const FACE::TIMEOUT_TYPE              &timeout,
        /* out   */       FACE::RETURN_CODE_TYPE          &return_code);

/**
 * The Destroy_Connection function frees up any resources allocated to the connection.
 *
 * Possible return codes:
 * <ul>
 * <li>NO_ERROR - Successful completion.</li>
 * <li>NO_ACTION - Object target of this operation has already been deleted.</li>
 * <li>INVALID_MODE - An operation was invoked on an inappropriate object or
 * at an inappropriate time.</li>
 * <li>INVALID_PARAM - Connection identification (ID) invalid.</li>
 * <li>NOT_AVAILABLE - Unsupported operation.</li>
 * <li>INVALID_CONFIG - Generic, unspecified error.</li>
 * <li>INVALID_MODE - A pre-condition for the operation was not met. Note:
 * In a FACE implementation, this error may imply an implementation problem
 * since the connection is deleted and should clean up all entities/children
 * associated with the connection.</li>
 * </ul>
 *
 * @param connection_id
 *        The connection_id of the connection that needs to be destroyed.
 *        This is an input parameter.
 * @param return_code
 *        The return_code.
 *        This is an output parameter.
 */
void Destroy_Connection(
        /* in    */ const FACE::CONNECTION_ID_TYPE   &connection_id,
        /* out   */       FACE::RETURN_CODE_TYPE     &return_code);

/**
 * The purpose of Get_Connection_Parameters is to get the information regarding the requested connection.
 *
 * @param connection_name
 *        The connection_name which belongs to the given connection_id.
 *        This is an output parameter.
 * @param connection_id
 *        The connection_id for which this status needs to return information
 *        This is an input parameter.
 * @param connection_status
 *        The connection_status which consists of the following settings:
 *        <ul>
 *        <li>MESSAGE - Always 0
 *        <li>MAX_MESSAGE - Always 0.
 *        <li>MAX_MESSAGE_SIZE - Always 0.
 *        <li>CONNECTION_DIRECTION - SOURCE or DESTINATION
 *        <li>WAITING_PROCESSES_OR_MESSAGES -  Not implemented
 *        <li>REFRESH_PERIOD - The configured refresh period.
 *        <li>LAST_MSG_VALIDITY - Whether or not the refresh period of last taken message has expired or not (DESTINATION)
 *        </ul>
 *        This is an output parameter.
 * @param return_code
 *        The return_code
 *        This is an output parameter.
 */
void Get_Connection_Parameters(
        /* inout */       FACE::CONNECTION_NAME_TYPE             &connection_name,
        /* inout */       FACE::CONNECTION_ID_TYPE               &connection_id,
        /* out   */       FACE::TRANSPORT_CONNECTION_STATUS_TYPE &connection_status,
        /* out   */       FACE::RETURN_CODE_TYPE                 &return_code);

/**
 * The purpose of Unregister_Callback is to provide a mechanism to unregister the callback
 * associated with a connection_id.
 *
 * @param connection_id
 *        The connection_id of the connection where the callback was registered.
 *        This is an input parameter.
 * @param return_code
 *        The return_code
 *        This is an output parameter.
 */
void Unregister_Callback(
        /* in    */ const FACE::CONNECTION_ID_TYPE &connection_id,
        /* out   */       FACE::RETURN_CODE_TYPE   &return_code);

/**
 * The Receive_Message Function is used to receive data from another source.
 *
 * Possible return codes:
 * <ul>
 * <li>NO_ERROR - Successful completion.
 * <li>NO_ACTION - Object target of this operation has already been deleted.
 * <li>INVALID_MODE - An operation was invoked on an inappropriate object or
 * <li>INVALID_PARAM - Illegal parameter value (e.g., connection ID).
 * <li>INVALID_CONFIG - Generic, unspecified error.
 * <li>NOT_AVAILABLE - Unsupported operation.
 * <li>INVALID_MODE
 * <ul>
 * <li>A pre-condition for the operation was not met.
 * <li>Operation invoked on an entity that is not yet enabled.
 * </ul>
 * <li>NO_ACTION - Indicates a transient situation where the operation did
 * </ul>
 * @param connection_id
 *        The connection_id which is used to get the connection where to receive messages on.
 *        This is an input parameter.
 * @param timeout
 *        The timeout in nanoseconds, this is used to determine how long DDS should wait for new messages
 *        to arrive before returning the result.
 *        This is an input parameter.
 * @param transaction_id
 *        The transaction_id, each time a message is read an unique transaction_id is generated for it.
 *        This is an output parameter.
 * @param message
 *        The message that is read by DDS
 *        This is an output parameter.
 * @param message_type_id
 *        The message_type_id for DDS this parameter is not relevant.
 *        This is an output parameter.
 * @param message_size
 *        The message_type_id for DDS this parameter is not relevant.
 *        This is an output parameter.
 * @param return_code
 *        The return_code
 *        This is an output parameter.
 */
void  Receive_Message(
        /* in    */ const FACE::CONNECTION_ID_TYPE &connection_id,
        /* in    */ const FACE::TIMEOUT_TYPE &timeout,
        /* inout */       FACE::TRANSACTION_ID_TYPE &transaction_id,
        /* inout */       Data::Type &message,
        /* inout */       FACE::MESSAGE_TYPE_GUID &message_type_id,
        /* inout */       FACE::MESSAGE_SIZE_TYPE &message_size,
        /* out   */       FACE::RETURN_CODE_TYPE &return_code);

/**
 * The Send_Message Function is used to send data to another source.
 *
 * Possible return codes:
 * <ul>
 * <li>NO_ERROR - Successful completion.
 * <li>NO_ACTION - Object target of this operation has already been deleted.
 * <li>INVALID_MODE - An operation was invoked on an inappropriate object or
 * at an inappropriate time.
 * <li>INVALID_PARAM - Illegal parameter value (e.g., connection ID).
 * <li>INVALID_CONFIG - Generic, unspecified error.
 * <li>NOT_AVAILABLE - Unsupported operation.
 * <li>INVALID_MODE
 * <ul>
 * <li>A pre-condition for the operation was not met.
 * <li>Operation invoked on an entity that is not yet enabled.
 * </ul>
 * <li>INVALID_CONFIG - Service ran out of resources needed to complete the
 * operation.
 * <li>TIMED_OUT - DDS will not return TIMEOUT, but this could be returned
 * by the TSS implementation.
 * </ul>
 *
 * @param connection_id
 *        The connection_id which is used to get the connection where to send messages to.
 *        This is an input parameter.
 * @param timeout
 *        The timeout in nanoseconds, this is used to determine how long DDS at maximum can wait to send the message.
 *        This timeout cannot be greater than max_blocking_time of the supplied DataWriter QoS.
 *        This is an input parameter.
 * @param transaction_id
 *        The transaction_id, each time a message is send an unique transaction_id is generated for it.
 *        This is an output parameter.
 * @param message
 *        The message that is read by DDS
 *        This is an output parameter.
 * @param message_type_id
 *        The message_type_id for DDS this parameter is not relevant.
 *        This is an output parameter.
 * @param message_size
 *        The message_type_id for DDS this parameter is not relevant.
 *        This is an output parameter.
 * @param return_code
 *        The return_code
 *        This is an output parameter.
 */
void  Send_Message(
        /* in    */ const FACE::CONNECTION_ID_TYPE &connection_id,
        /* in    */ const FACE::TIMEOUT_TYPE &timeout,
        /* inout */       FACE::TRANSACTION_ID_TYPE &transaction_id,
        /* inout */       Data::Type &message,
        /* in    */ const FACE::MESSAGE_TYPE_GUID &message_type_id,
        /* in    */ const FACE::MESSAGE_SIZE_TYPE &message_size,
        /* out   */       FACE::RETURN_CODE_TYPE &return_code);

/**
 * The purpose of Register_Callback is to provide a mechanism to read data without polling.
 * This needs to be called on the generated type interface without using the TS Interface.
 * There can only be one callback registration per connection_id.
 *
 * Possible return codes:
 * <ul>
 * <li>NO_ERROR - Successful completion.
 * <li>NO_ACTION - Callback already registered for specified type.
 * <li>INVALID_PARAM - One or more of the parameters are incorrect (e.g.,
 * invalid connection identification (ID), invalid callback, invalid message
 * size).
 * <li>NOT_AVAILABLE - Callback/routing function not available (e.g.,
 * callback service is not provided in this implementation).
 * <li>INVALID_CONFIG - One or more fields in the configuration data for the
 * connection is invalid (e.g., invalid TSS thread parameters).
 * </ul>
 *
 * <p>
 * <b><i>Register_Callback Example</i></b>
 * <pre>
 * <code>
 *
 * static void data_callback (const FACE::TRANSACTION_ID_TYPE &transaction_id,
 *                            Data::Type                      &message,
 *                            const FACE::MESSAGE_TYPE_GUID   &message_type_id,
 *                            const FACE::MESSAGE_SIZE_TYPE   &message_size,
 *                            const FACE::WAITSET_TYPE        &waitset,
 *                            FACE::RETURN_CODE_TYPE          &return_code)
 * {
 *    do your action here
 * }
 *
 * then the callback can be registered by calling:
 * FACE::TS::Register_Callback(connection_id, waitset, data_callback, maxMessageSize, status);
 * </code>
 * </pre>
 *
 * @param connection_id
 *        The connection_id of the connection that needs to be used for the callback.
 *        This is an input parameter.
 * @param waitset
 *        The waitset for DDS this parameter is not relevant.
 *        This is an input parameter.
 * @param data_callback
 *        The data_callback class in which an action can be set on how to react when receiving data.
 *        This data_callback is the external operation (interface, which must be implemented by the application see example)
 *        that is called by the FACE API when new data is available for this connection.
 *        This is an input parameter.
 * @param max_message_size
 *        The max_message_size for DDS this parameter is not relevant however the max_message_size supplied
 *        needs to be less then the max_message_size of the configured connection.
 *        This is an input parameter.
 * @param return_code the return_code
 *        This is an output parameter.
 */
void  Register_Callback(
        /* in    */ const    FACE::CONNECTION_ID_TYPE &connection_id,
        /* in    */ const    FACE::WAITSET_TYPE &waitset,
        /* inout */          FACE::Read_Callback<Data::Type>::send_event  data_callback,
        /* in    */ const    FACE::MESSAGE_SIZE_TYPE &max_message_size,
        /* out   */          FACE::RETURN_CODE_TYPE &return_code);

} /* namespace TS */
} /* namespace FACE */

#endif /* VORTEX_FACE_ISOCPP2_Data_HPP_ */
