#ifndef SDV_PS_SUPPORT_H #define SDV_PS_SUPPORT_H #include "../interfaces/core_ps.h" #include "../interfaces/serdes/core_ps_serdes.h" #include "../interfaces/serdes/core_types_serdes.h" /** * @brief Compare two marshall IDs. * @param[in] rtID1 Reference to the first ID. * @param[in] rtID2 Reference to the second ID. * @return Returns whether the first ID is identical to the second ID. */ bool operator==(const sdv::ps::TMarshallID& rtID1, const sdv::ps::TMarshallID& rtID2); /** * @brief Compare the marshall ID with zero. * @param[in] rtID1 Reference to the first ID. * @param[in] nVal The value to use for comparison (only 0 is allowed). * @return Returns whether the ID is zero. */ bool operator==(const sdv::ps::TMarshallID& rtID1, size_t nVal); /** * @brief Compare the marshall ID with zero. * @param[in] nVal The value to use for comparison (only 0 is allowed). * @param[in] rtID2 Reference to the second ID. * @return Returns whether the ID is zero. */ bool operator==(size_t nVal, const sdv::ps::TMarshallID& rtID2); /** * @brief Compare two marshall IDs. * @param[in] rtID1 Reference to the first ID. * @param[in] rtID2 Reference to the second ID. * @return Returns whether the first ID is different from the second ID. */ bool operator!=(const sdv::ps::TMarshallID& rtID1, const sdv::ps::TMarshallID& rtID2); /** * @brief Compare the marshall ID with zero. * @param[in] rtID1 Reference to the first ID. * @param[in] nVal The value to use for comparison (only 0 is allowed). * @return Returns whether the ID is not zero. */ bool operator!=(const sdv::ps::TMarshallID& rtID1, size_t nVal); /** * @brief Compare the marshall ID with zero. * @param[in] nVal The value to use for comparison (only 0 is allowed). * @param[in] rtID2 Reference to the second ID. * @return Returns whether the ID is not zero. */ bool operator!=(size_t nVal, const sdv::ps::TMarshallID& rtID2); /** * @brief Compare two marshall IDs. * @param[in] rtID1 Reference to the first ID. * @param[in] rtID2 Reference to the second ID. * @return Returns whether the first ID is smaller than the second ID. */ bool operator<(const sdv::ps::TMarshallID& rtID1, const sdv::ps::TMarshallID& rtID2); /** * @brief Compare two marshall IDs. * @param[in] rtID1 Reference to the first ID. * @param[in] rtID2 Reference to the second ID. * @return Returns whether the first ID is smaller or equal the than second ID. */ bool operator<=(const sdv::ps::TMarshallID& rtID1, const sdv::ps::TMarshallID& rtID2); /** * @brief Compare two marshall IDs. * @param[in] rtID1 Reference to the first ID. * @param[in] rtID2 Reference to the second ID. * @return Returns whether the first ID is larger than the second ID. */ bool operator>(const sdv::ps::TMarshallID& rtID1, const sdv::ps::TMarshallID& rtID2); /** * @brief Compare two marshall IDs. * @param[in] rtID1 Reference to the first ID. * @param[in] rtID2 Reference to the second ID. * @return Returns whether the first ID is larger or equal than the second ID. */ bool operator>=(const sdv::ps::TMarshallID& rtID1, const sdv::ps::TMarshallID& rtID2); /** * @brief Check for validity of the marshall ID. * @param[in] rtID Reference to the ID. * @return Returns whether the ID is valid. */ bool operator!(const sdv::ps::TMarshallID& rtID); #ifndef DOXYGEN_IGNORE /** * @brief Specialization of std::less for sdv::ps::TMarshallID. */ template <> struct std::less { /// The result type using result_type = bool; /// The first argument type. using first_argument_type = sdv::ps::TMarshallID; /// The second argument type. using second_argument_type = sdv::ps::TMarshallID; /** * @brief Compare ID1 < ID2. * @param[in] rtID1 Reference to the first ID. * @param[in] rtID2 Reference to the second ID. * @return Result of the comparison. */ bool operator()(const sdv::ps::TMarshallID& rtID1, const sdv::ps::TMarshallID& rtID2) const { return ::operator<(rtID1, rtID2); } }; #endif // !defined DOXYGEN_IGNORE /** * @brief Compare two connection IDs. * @param[in] rtID1 Reference to the first ID. * @param[in] rtID2 Reference to the second ID. * @return Returns whether the first ID is identical to the second ID. */ bool operator==(const sdv::com::TConnectionID& rtID1, const sdv::com::TConnectionID& rtID2); /** * @brief Compare the connection ID with zero. * @param[in] rtID1 Reference to the first ID. * @param[in] nVal The value to use for comparison (only 0 is allowed). * @return Returns whether the ID is zero. */ bool operator==(const sdv::com::TConnectionID& rtID1, size_t nVal); /** * @brief Compare the connection ID with zero. * @param[in] nVal The value to use for comparison (only 0 is allowed). * @param[in] rtID2 Reference to the second ID. * @return Returns whether the ID is zero. */ bool operator==(size_t nVal, const sdv::com::TConnectionID& rtID2); /** * @brief Compare two connection IDs. * @param[in] rtID1 Reference to the first ID. * @param[in] rtID2 Reference to the second ID. * @return Returns whether the first ID is different from the second ID. */ bool operator!=(const sdv::com::TConnectionID& rtID1, const sdv::com::TConnectionID& rtID2); /** * @brief Compare the connection ID with zero. * @param[in] rtID1 Reference to the first ID. * @param[in] nVal The value to use for comparison (only 0 is allowed). * @return Returns whether the ID is not zero. */ bool operator!=(const sdv::com::TConnectionID& rtID1, size_t nVal); /** * @brief Compare the connection ID with zero. * @param[in] nVal The value to use for comparison (only 0 is allowed). * @param[in] rtID2 Reference to the second ID. * @return Returns whether the ID is not zero. */ bool operator!=(size_t nVal, const sdv::com::TConnectionID& rtID2); /** * @brief Compare two connection IDs. * @param[in] rtID1 Reference to the first ID. * @param[in] rtID2 Reference to the second ID. * @return Returns whether the first ID is smaller than the second ID. */ bool operator<(const sdv::com::TConnectionID& rtID1, const sdv::com::TConnectionID& rtID2); /** * @brief Compare two connection IDs. * @param[in] rtID1 Reference to the first ID. * @param[in] rtID2 Reference to the second ID. * @return Returns whether the first ID is smaller or equal the than second ID. */ bool operator<=(const sdv::com::TConnectionID& rtID1, const sdv::com::TConnectionID& rtID2); /** * @brief Compare two connection IDs. * @param[in] rtID1 Reference to the first ID. * @param[in] rtID2 Reference to the second ID. * @return Returns whether the first ID is larger than the second ID. */ bool operator>(const sdv::com::TConnectionID& rtID1, const sdv::com::TConnectionID& rtID2); /** * @brief Compare two connection IDs. * @param[in] rtID1 Reference to the first ID. * @param[in] rtID2 Reference to the second ID. * @return Returns whether the first ID is larger or equal than the second ID. */ bool operator>=(const sdv::com::TConnectionID& rtID1, const sdv::com::TConnectionID& rtID2); /** * @brief Check for validity of the connection ID. * @param[in] rtID Reference to the ID. * @return Returns whether the ID is valid. */ bool operator!(const sdv::com::TConnectionID& rtID); #ifndef DOXYGEN_IGNORE /** * @brief Specialization of std::less for sdv::com::TConnectionID. */ template <> struct std::less { /// The result type using result_type = bool; /// The first argument type. using first_argument_type = sdv::com::TConnectionID; /// The second argument type. using second_argument_type = sdv::com::TConnectionID; /** * @brief Compare ID1 < ID2. * @param[in] rtID1 Reference to the first ID. * @param[in] rtID2 Reference to the second ID. * @return Result of the comparison. */ bool operator()(const sdv::com::TConnectionID& rtID1, const sdv::com::TConnectionID& rtID2) const { return ::operator<(rtID1, rtID2); } }; #endif // !defined DOXYGEN_IGNORE #include "sequence.h" #include "pointer.h" #include "crc.h" #include "component_impl.h" #include #include #include #include #include #include #include namespace sdv { namespace ps { /** * Local SMarshall structure to handle specific CRC calculations */ struct SMarshallLocal : SMarshall {}; /** * @brief Bypass class available during a function call. This class uses thread local storage to allow the storage of * raw data bypassing the serialization. */ class CRawDataBypass { public: /** * @brief Constructor */ CRawDataBypass(); /** * @brief Add raw data to the raw data queue. * @param[in] rptrData Reference to the smart pointer holding the data. */ void push(const pointer& rptrData); /** * @brief Prop the data from the raw data queue. * @return The data to pop. */ pointer pop(); /** * @brief Is the raw data queue empty? * @return Returns whether the queue is empty. */ bool empty() const; /** * @brief Clear the raw data queue. */ void clear(); private: std::queue> m_queueBypassData; ///< Additional buffers not being serialized. }; /** * @brief Global access function for the raw data bypass. * @return Reference to the bypass. */ CRawDataBypass& GetRawDataBypass(); /** * @brief Result enumeration of the call function. */ enum class ECallResult : uint32_t { result_ok = 0, ///< Normal processing. The return buffer contains the return values. result_exception = 1, ///< Exception occurred. The return buffer contains the serialized exception. }; /** * @brief Proxy class managing the function calls and incoming calls containing the response. * @tparam TInterface The interface the deriving class is deriving from as well. */ template class CProxyHandler : public sdv::CSdvObject, public IMarshallObjectIdent, public IMarshallLink { public: // Ensure that the EEndian structure is 8 bits (to prevent byte swapping during detection). static_assert(sizeof(EEndian) == 1); /** * @brief Constructor */ CProxyHandler(); /** * @brief Constructor */ virtual ~CProxyHandler() override; // Interface map BEGIN_SDV_INTERFACE_MAP() SDV_INTERFACE_CHAIN_BASE(sdv::CSdvObject) SDV_INTERFACE_ENTRY(IMarshallObjectIdent) SDV_INTERFACE_ENTRY(IMarshallLink) END_SDV_INTERFACE_MAP() // Object class type DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Proxy) /** * @brief Set the identification. Overload of IMarshallObjectIdent::SetIdentification. * @param[in] tMarshallID Reference to the marshall object ID. For a proxy object, this is the proxy ID. For a stub object * this is a stub ID. */ virtual void SetIdentification(/*in*/ const TMarshallID& tMarshallID) override; /** * @brief Link the communication interface to the object. Overload of IMarshallLink::Link. * @remarks Only one link can exists at the time. * @param[in] pMarshall Interface to be linked. */ virtual void Link(/*in*/ IMarshall* pMarshall) override; /** * @brief Unlink the linked interface. Overload of IMarshallLink::Unlink. */ virtual void Unlink() override; /** * @brief Schedule a call. * @param[in] uiFuncIndex Operation/attribute index. * @param[in] rserInput Serializer containing the input parameters. * @param[in] rdesOutput Deserializer containing the return value and output parameters or the exception. * @return The call result value. */ ECallResult DoCall(uint32_t uiFuncIndex, const serializer& rserInput, deserializer& rdesOutput); private: IMarshall* m_pRequest = nullptr; ///< Marshall interface for call requests. TMarshallID m_tProxyID = {}; ///< Proxy handler ID. TMarshallID m_tStubID = {}; ///< Stub handler ID. }; /** * @brief Stub class managing incoming calls containing the request and dispatching them to the functions. * @tparam TInterface The interface this stub is dispatching to. */ template class CStubHandler : public sdv::CSdvObject, public IMarshallObjectIdent, public IMarshall { // Ensure that the EEndian structure is 8 bits (to prevent byte swapping during detection). static_assert(sizeof(EEndian) == 1); public: /** * @brief Constructor */ CStubHandler(); /** * @brief Destructor */ virtual ~CStubHandler() override; // Interface map BEGIN_SDV_INTERFACE_MAP() SDV_INTERFACE_CHAIN_BASE(sdv::CSdvObject) SDV_INTERFACE_ENTRY(IMarshallObjectIdent) SDV_INTERFACE_ENTRY(IMarshall) END_SDV_INTERFACE_MAP() // Object class type DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Stub) protected: /** * @brief Dispatch function type. Function arguments are endianness, input parameters and output * parameters/return value/exception information. Function returns the dispact result. */ typedef std::function&, pointer&)> FNDispatch; /** * @brief Register dispatch function. * @remarks This dispatch functions must be registered in the correct order. * @attention Registering dispatch functions should happen during construction. No protection of the vector is * available during data dispatching. * @param[in] fnDispatch Dispatch function to call for this interface. */ void RegisterDispatchFunc(FNDispatch fnDispatch); /** * @brief Serialize exception helper function. * @tparam TExcept The exception type to serialize. * @param[in] eEndian The endianness of the serialization. * @param[in] rexcept Reference to the exception. * @return The serialized exception. */ template pointer SerializeException(EEndian eEndian, const TExcept& rexcept); /** * @brief Set the identification. Overload of IMarshallObjectIdent::SetIdentification. * @param[in] tMarshallID Reference to The marshall object ID. For a proxy object, this is the proxy ID. For a stub object * this is a stub ID. */ virtual void SetIdentification(/*in*/ const TMarshallID& tMarshallID) override; /** * @brief Marshall a function call. Overload of IMarshall::Call. * @remarks This function call is synchronous and does not return until the call has been finalized or a timeout * exception has occurred. * @remarks The sequence contains all data to make the call. It is important that the data in the sequence is * complete and in the correct order. * @param[inout] seqInputData Reference to sequence of input data pointers. The first data pointer contains the * marshalling header. The second contains the parameters (if available) and the others contain raw data pointers * (if available). The call is allowed to change the sequence to be able to add additional information during the * communication without having to copy the existing data. * @return Sequence of output data pointers. The first data pointer contains the marshalling header. The second * contains the return value and parameters (if available) and the others contain raw data pointers (if available). */ virtual sequence> Call(/*inout*/ sequence>& seqInputData) override; private: std::vector m_vecDispatch; ///< Vector containing the dispatch functions. TMarshallID m_tStubID{}; ///< Stub handler ID. }; } // namespace ps } // namespace sdv #include "pssup.inl" #endif // !defined(SDV_PS_SUPPORT_H)