/*---------------------------------------------------------------------------* Project: Horizon File: rdt_Sender.h Copyright (C) Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Rev: 54504 $ *---------------------------------------------------------------------------*/ ////#include #ifndef NN_RDT_SENDER_H_ #define NN_RDT_SENDER_H_ #include #include #include namespace nn { namespace rdt { /*! @addtogroup nn_rdt_api @{ */ class SenderImpl; /*! @brief Structure that contains all configuration information passed to @ref Sender::Initialize. */ struct SenderConfig{ void *pWorkBuf; //!< Pointer to the work memory region used by the Sender instance. It must be 8-byte aligned. Allocate a working-memory area of at least Sender::SENDER_WORKBUF_SIZE bytes. void *pSendBuf; //!< Takes the starting address of the send buffer. u16 sendBufSize; //!< Size (in bytes) of the send buffer (pSendBuf). u16 nodeId; //!< Node ID of the UDS communication partner. u8 port; //!< Port number used during UDS communication. u8 padding[3]; //!< Padding. #ifdef _WIN32 SOCKET sock; #endif }; /*! @brief Represents a device that sends data. The following description shows how to use the Sender class. Detailed instructions on calling @ref Process have been left out of the following description. In actual practice, @ref Process must be called periodically at a frequency of about once per game frame or less.
  1. Create an instance of the Sender class.
  2. Call @ref Initialize to initialize the instance. (The send buffer memory and the working memory for use by the Sender instance are allocated at this time.)
  3. Call @ref Open to attempt a connection to the Receiver instance that is running remotely.
  4. After the state changes to SENDER_STATE_OPENED, break down the data to be sent into smaller pieces, and call @ref Send repeatedly.
  5. When all the data has been sent, call @ref Close, and inform the remote station that there is no more data left to send.
  6. When the state changes to SENDER_STATE_CLOSED, call @ref Finalize to clean up the Sender class.
*/ class Sender{ public: static const size_t SENDER_WORKBUF_SIZE = 32 * 1024; //!< Specifies the size of the working memory required by the Sender instance. /*! @brief Instantiates an object. You must call @ref Initialize after calling this function to enable use of the Sender instance. */ Sender(void); /*! @brief Destroys the object. If @ref Finalize has not been called yet, the destructor calls it. */ ~Sender(void); /*! @brief Initializes an instance. If initialization succeeds, this function implicitly consumes two nn::uds::EndpointDescriptor objects. If initialization fails, the function returns without consuming any nn::uds::EndpointDescriptor objects. Memory passed to the instance by this call must be allocated before calling @ref Finalize. The @ref nn::uds::Cafe::Attach "nn::uds::Attach" function is called implicitly with @ref nn::uds::Cafe::ATTACH_BUFFER_SIZE_DEFAULT "nn::uds::ATTACH_BUFFER_SIZE_DEFAULT" specified as the receive buffer size. If the application does not supply a large enough buffer to @ref nn::uds::Cafe::Initialize "nn::uds::Initialize", initialization fails, returning @ref nn::uds::Cafe::ResultOutOfResource "nn::uds::ResultOutOfResource", because the @ref nn::uds::Cafe::Attach "nn::uds::Attach" function uses the buffer passed to @ref nn::uds::Cafe::Initialize "nn::uds::Initialize". @param[in] config Data structure storing initialization parameters. For more information, see SenderConfig. @return Returns the initialization result. Specifically, this function may return the following: a value for which the @ref nn::Result::IsSuccess function returns true or a result code returned by the UDS library (such as @ref ResultNullPointer, @ref ResultInvalidSize, or @ref ResultAlreadyInitialized). */ nn::Result Initialize(const SenderConfig &config); /*! @brief Frees resources that were used by the Sender instance, including the send buffer and the endpoint descriptors. @return None. Calls to @ref Finalize always succeed. If @ref Finalize is called when the instance is not initialized, the function does nothing and returns. */ void Finalize(void); /*! @brief Issues a connection request. Issues a connection request to a remote Receiver instance. If the call to this function succeeds, the state transitions to SENDER_STATE_OPEN_REQUESTED. The connection is actually opened within the @ref Process function. @return Returns success if the request was accepted. The function returns failure if it is called when the state of the instance is anything other than SENDER_STATE_CLOSED. Specifically, this function may return the following: a value for which the @ref nn::Result::IsSuccess function returns true; or @ref ResultNotInitialized or @ref ResultUntimelyFunctionCall. */ nn::Result Open(void); /*! @brief Issues a request to close a connection. This function is provided to inform the receiver that there is no more data to send. If the call to this function succeeds, the state transitions to SENDER_STATE_CLOSE_REQUESTED. The connection is actually closed within the @ref Process function. @return Returns success if the request was accepted. The function returns failure if it is called when the state of the instance is anything other than SENDER_STATE_OPENED. Specifically, this function may return the following: a value for which the @ref nn::Result::IsSuccess function returns true; or @ref ResultNotInitialized or @ref ResultUntimelyFunctionCall. */ nn::Result Close(void); /*! @brief Writes data to the send buffer. After you confirm that this call has succeeded, you can free the memory pointed to by pBuf because the data it points to has already been copied to the send buffer. Calls to this function fail if it cannot write all of the requested data because the capacity of the send buffer is too small. No data is written to the send buffer at all in such cases. If @ref Send fails, wait a short time and then try again. The act of sending the data in the send buffer is actually executed by the @ref Process function. @param[in] pBuf Pointer to the start of the data to send. It must not be a null pointer. @param[in] bufSize The size of the data to send (in bytes). If this parameter is set to 0, the function does nothing and returns a non-error value. @return Returns a value indicating whether data was successfully written to the send buffer. Specifically, this function may return the following: a value for which the @ref nn::Result::IsSuccess function returns true, or the result code @ref ResultNotInitialized, @ref ResultDoNothing, @ref ResultSendBufferIsNotAvailable, or @ref ResultUntimelyFunctionCall. */ nn::Result Send(const void *pBuf, size_t bufSize); /*! @brief Proceeds with communication. The actual communication occurs within this function. Applications must always call this function at least every game frame (every 50 ms or less) until the @ref Finalize function is called, even when running in background mode. When sending and receiving real data, you can sometimes improve the transmission performance by calling this function several times in a row. This function results in transfer of up to 1400 bytes per call, but even more data can be received by calling this function multiple times after writing more data to the send buffer in the RDT library with the @ref Send function. For more information about specific settings, see the ServerClient sample demo. Do not call other member functions (such as @ref Send) while this function is running. This results in undefined operations. State transitions of Sender instances are also handled within this function. @return Returns the result of a series of communication operations. Specifically, this function may return the following: a value for which the @ref nn::Result::IsSuccess function returns true or a result code returned by the UDS library, such as @ref ResultNotInitialized or @ref ResultResetReceived. Depending on the state of communications, @ref nn::uds::Cafe::ResultBufferIsFull "nn::uds::ResultBufferIsFull" might also be returned. When this happens, the outgoing data is lost in the UDS layer, but the RDT checks to determine whether the appropriate data arrived and resends the data if it cannot verify arrival. Because data for which arrival has not been confirmed is automatically resent, you can safely ignore @ref nn::uds::Cafe::ResultBufferIsFull "nn::uds::ResultBufferIsFull" if it is returned by this function. */ nn::Result Process(void); /*! @brief Cancels the operation. Call this function when you want to forcibly stop communication based on a command by the player. Calling this function makes the Sender instance transition to the SENDER_STATE_CLOSED state. This function is an exception in that it runs its operation right away, without waiting for the @ref Process function to run it. @return None. Calls to the @ref Cancel function always succeed. */ void Cancel(void); /*! @brief Gets the status of a Sender instance. @return Returns the status of the Sender instance at the time this function was called. */ enum SenderState GetStatus(void) const; /*! @brief Sets up a simulated packet loss ratio (for debugging). This function may be removed in a future release without notice. If a value other than zero is set for the packet loss ratio, the rdt library calls std::rand to determine whether to simulate packet loss. Set an appropriate random seed by calling std::srand before using this function. @param[in] per Provide a value so that 0 <= per <= 100. @return None. */ void SetPacketLossRatio(int per); /*! @brief Prints detailed information about the internal state of a Sender instance (for debugging). This function may be removed in a future release without notice. @return None. */ void PrintDebugInfo(void) const; private: /*! @brief The copy constructor is private. */ Sender (const Sender&); /*! @brief The assignment operator is private. */ Sender& operator=(const Sender&); /*! @brief Private member variables. */ SenderImpl *m_pImpl; }; //! @} }} // namespace nn::rdt #endif // end of NN_RDT_SENDER_H_