1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     rdt_Sender.h
4 
5   Copyright (C) 2009-2011 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 54504 $
14  *---------------------------------------------------------------------------*/
15 
16 ////#include <stdafx.h>
17 
18 #ifndef NN_RDT_SENDER_H_
19 #define NN_RDT_SENDER_H_
20 
21 
22 #include <nn/rdt/rdt_define.h>
23 
24 #include <nn/types.h>
25 #include <nn/Result.h>
26 
27 
28 namespace nn { namespace rdt {
29 
30 /*!
31     @addtogroup  nn_rdt_api
32     @{
33 */
34 
35 class SenderImpl;
36 
37 /*!
38     @brief Structure that contains all configuration information passed to <tt>@ref Sender::Initialize</tt>.
39  */
40 struct SenderConfig{
41     void *pWorkBuf;    //!< Pointer to the work memory region used by the <tt>Sender</tt> instance. It must be 8-byte aligned. Allocate a working-memory area of at least <tt>Sender::SENDER_WORKBUF_SIZE</tt> bytes.
42     void *pSendBuf;    //!< Takes the starting address of the send buffer.
43     u16   sendBufSize; //!< Size (in bytes) of the send buffer (<span class="argument">pSendBuf</span>).
44     u16   nodeId;      //!< Node ID of the UDS communication partner.
45     u8    port;        //!< Port number used during UDS communication.
46     u8    padding[3];  //!< Padding.
47 #ifdef _WIN32
48     SOCKET sock;
49 #endif
50 };
51 
52 
53 /*!
54     @brief Represents a device that sends data.
55 
56 The following description shows how to use the <tt>Sender</tt> class. Detailed instructions on calling <tt>@ref Process</tt> have been left out of the following description. In actual practice, <tt>@ref Process</tt> must be called periodically at a frequency of about once per game frame or less.
57 
58 1. Create an instance of the <tt>Sender</tt> class.
59 
60 2. Call <tt>@ref Initialize</tt> to initialize the instance.
61 (The send buffer memory and the working memory for use by the <tt>Sender</tt> instance are allocated at this time.)
62 
63 3. Call <tt>@ref Open</tt> to attempt a connection to the <tt>Receiver</tt> instance that is running remotely.
64 
65 4. After the state changes to <tt>SENDER_STATE_OPENED</tt>, break down the data to be sent into smaller pieces, and call <tt>@ref Send</tt> repeatedly.
66 
67 5. When all the data has been sent, call <tt>@ref Close</tt>, and inform the remote station that there is no more data left to send.
68 
69 6. When the state changes to <tt>SENDER_STATE_CLOSED</tt>, call <tt>@ref Finalize</tt> to clean up the <tt>Sender</tt> class.
70 
71 
72 
73 
74 
75 
76 
77 */
78 class Sender{
79 public:
80     static const size_t SENDER_WORKBUF_SIZE = 32 * 1024;  //!< Specifies the size of the working memory required by the <tt>Sender</tt> instance.
81 
82     /*!
83     @brief Instantiates the object.
84 
85     You must call <tt>@ref Initialize</tt> after calling this function to enable use of the <tt>Sender</tt> instance.
86 
87     */
88     Sender(void);
89 
90 
91     /*!
92     @brief Destroys the object.
93 
94     If <tt>@ref Finalize</tt> has not been called yet, the destructor calls it.
95 
96     */
97    ~Sender(void);
98 
99 
100     /*!
101     @brief  Initializes the instance.
102 
103     If initialization succeeds, this function implicitly consumes two <tt>nn::uds::EndpointDescriptor</tt> objects.
104     If initialization fails, the function returns without consuming any <tt>nn::uds::EndpointDescriptor</tt> objects.
105     Memory passed to the instance by this call must be allocated before calling <tt>@ref Finalize</tt>.
106 
107     The <tt>@ref nn::uds::Cafe::Attach "nn::uds::Attach"</tt> function is called implicitly with <tt>@ref nn::uds::Cafe::ATTACH_BUFFER_SIZE_DEFAULT "nn::uds::ATTACH_BUFFER_SIZE_DEFAULT"</tt> specified as the receive buffer size.
108     If the application does not supply a large enough buffer to <tt>@ref nn::uds::Cafe::Initialize "nn::uds::Initialize"</tt>, initialization fails, returning <tt>@ref nn::uds::Cafe::ResultOutOfResource "nn::uds::ResultOutOfResource"</tt>, because the <tt>@ref nn::uds::Cafe::Attach "nn::uds::Attach"</tt> function uses the buffer passed to <tt>@ref nn::uds::Cafe::Initialize "nn::uds::Initialize"</tt>.
109 
110     @param[in] config   Data structure storing initialization parameters. For more information, see <tt>SenderConfig</tt>.
111 
112     @return Returns the initialization result. Specifically, this function may return the following: a value for which the <tt>@ref nn::Result::IsSuccess</tt> function returns <tt>true</tt> or a result code returned by the UDS library (such as <tt>@ref ResultNullPointer</tt>, <tt>@ref ResultInvalidSize</tt>, or <tt>@ref ResultAlreadyInitialized</tt>).
113 
114 
115 
116 
117 
118 
119 
120 */
121     nn::Result Initialize(const SenderConfig &config);
122 
123 
124     /*!
125     @brief Frees resources that were used by the <tt>Sender</tt> instance, including the send buffer and the endpoint descriptors.
126 
127     @return  None. Calls to <tt>@ref Finalize</tt> always succeed.
128     If <tt>@ref Finalize</tt> is called when the instance is not initialized, the function does nothing and returns.
129 
130 */
131     void Finalize(void);
132 
133 
134     /*!
135     @brief Issues a connection request.
136 
137     Issues a connection request to a remote <tt>Receiver</tt> instance.
138     If the call to this function succeeds, the state transitions to <tt>SENDER_STATE_OPEN_REQUESTED</tt>.
139     The connection is actually opened within the <tt>@ref Process</tt> function.
140 
141     @return Returns success if the request was accepted.
142     The function returns failure if it is called when the state of the instance is anything other than <tt>SENDER_STATE_CLOSED</tt>.
143     Specifically, this function may return the following: a value for which the <tt>@ref nn::Result::IsSuccess</tt> function returns <tt>true</tt>; or <tt>@ref ResultNotInitialized</tt> or <tt>@ref ResultUntimelyFunctionCall</tt>.
144 
145 
146 */
147     nn::Result Open(void);
148 
149 
150     /*!
151     @brief Issues a request to close a connection.
152 
153     This function is provided to inform the receiver that there is no more data to send.
154     If the call to this function succeeds, the state transitions to <tt>SENDER_STATE_CLOSE_REQUESTED</tt>.
155     The connection is actually closed within the <tt>@ref Process</tt> function.
156 
157 @return Returns success if the request was accepted.
158 The function returns failure if it is called when the state of the instance is anything other than <tt>SENDER_STATE_OPENED</tt>.
159 Specifically, this function may return the following: a value for which the <tt>@ref nn::Result::IsSuccess</tt> function returns <tt>true</tt>; or <tt>@ref ResultNotInitialized</tt> or <tt>@ref ResultUntimelyFunctionCall</tt>.
160 
161 
162 
163 */
164     nn::Result Close(void);
165 
166 
167     /*!
168     @brief Writes data to the send buffer.
169 
170     After you confirm that this call has succeeded, you can free the memory pointed to by <span class="argument">pBuf</span> because the data it points to has already been copied to the send buffer.
171     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.
172     If <tt>@ref Send</tt> fails, wait a short time and then try again.
173     The act of sending the data in the send buffer is actually executed by the <tt>@ref Process</tt> function.
174 
175     @param[in] pBuf     Pointer to the start of the data to send. It must not be a null pointer.
176     @param[in] bufSize  The size of the data to send (in bytes).
177     If this parameter is set to <tt>0</tt>, the function does nothing and returns a non-error value.
178 
179     @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 <tt>@ref nn::Result::IsSuccess</tt> function returns <tt>true</tt>, or the result code <tt>@ref ResultNotInitialized</tt>, <tt>@ref ResultDoNothing</tt>, <tt>@ref ResultSendBufferIsNotAvailable</tt>, or <tt>@ref ResultUntimelyFunctionCall</tt>.
180 
181 
182 
183 
184 
185 
186 
187 */
188     nn::Result Send(const void *pBuf, size_t bufSize);
189 
190 
191     /*!
192     @brief Proceeds with communication. The actual communication occurs within this function.
193 
194     Applications must always call this function at least every game frame (every 50 ms or less) until the <tt>@ref Finalize</tt> function is called, even when running in background mode.
195     When sending and receiving real data, you can sometimes improve the transmission performance by calling this function several times in a row.
196     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 <tt>@ref Send</tt> function.
197     For more information about specific settings, see the <tt>ServerClient</tt> sample demo.
198     Do not call other member functions (such as <tt>@ref Send</tt>) while this function is running.
199     This results in undefined operations.
200     State transitions of <tt>Sender</tt> instances are also handled within this function.
201 
202     @return Returns the result of a series of communication operations. Specifically, this function may return the following: a value for which the <tt>@ref nn::Result::IsSuccess</tt> function returns <tt>true</tt> or a result code returned by the UDS library, such as <tt>@ref ResultNotInitialized</tt> or <tt>@ref ResultResetReceived</tt>.
203 
204     Depending on the state of communications, <tt>@ref nn::uds::Cafe::ResultBufferIsFull "nn::uds::ResultBufferIsFull"</tt> might also be returned.
205     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 <tt>@ref nn::uds::Cafe::ResultBufferIsFull "nn::uds::ResultBufferIsFull"</tt> if it is returned by this function.
206 
207 
208 
209 
210 
211 
212 
213 
214 */
215     nn::Result Process(void);
216 
217 
218     /*!
219     @brief  Cancels the operation.
220 
221     Call this function when you want to forcibly stop communication based on a command by the player.
222     Calling this function makes the <tt>Sender</tt> instance transition to the <tt>SENDER_STATE_CLOSED</tt> state.
223     This function is an exception in that it runs its operation right away, without waiting for the <tt>@ref Process</tt> function to run it.
224 
225     @return  None. Calls to the <tt>@ref Cancel</tt> function always succeed.
226 
227     */
228     void Cancel(void);
229 
230 
231     /*!
232     @brief Gets the status of a <tt>Sender</tt> instance.
233 
234     @return Returns the status of the <tt>Sender</tt> instance at the time this function was called.
235      */
236     enum SenderState GetStatus(void) const;
237 
238 
239     /*!
240     @brief Sets up a simulated packet loss ratio (for debugging). This function may be removed in a future release without notice.
241 
242     If a value other than zero is set for the packet loss ratio, the <tt>rdt</tt> library calls <tt>std::rand</tt> to determine whether to simulate packet loss. Set an appropriate random seed by calling <tt>std::srand</tt> before using this function.
243 
244     @param[in] per  Provide a value so that <tt>0 <= </tt><span class="argument">per</span> <tt><= 100</tt>.
245 
246     @return  None.
247 
248 
249     */
250     void SetPacketLossRatio(int per);
251 
252 
253     /*!
254     @brief Prints detailed information about the internal state of a <tt>Sender</tt> instance (for debugging). This function may be removed in a future release without notice.
255 
256     @return  None.
257      */
258     void PrintDebugInfo(void) const;
259 
260 
261 private:
262     /*!
263     @brief The copy constructor is private.
264      */
265     Sender           (const Sender&);
266 
267 
268     /*!
269     @brief The assignment operator is private.
270      */
271     Sender& operator=(const Sender&);
272 
273 
274     /*!
275     @brief Private member variables.
276      */
277     SenderImpl *m_pImpl;
278 };
279 
280 //! @}
281 
282 }} // namespace nn::rdt
283 
284 #endif  // end of NN_RDT_SENDER_H_
285