1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     rdt_Receiver.h
4 
5   Copyright (C) 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_RECEIVER_H_
19 #define NN_RDT_RECEIVER_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 ReceiverImpl;
36 
37 /*!
38     @brief  Structure that contains all configuration information passed to <tt>@ref Receiver::Initialize</tt>.
39 */
40 struct ReceiverConfig{
41     void *pWorkBuf;     //!< Pointer to the work memory region used by the <tt>Receiver</tt> instance. It must be 8-byte aligned. Allocate a working memory buffer of at least <tt>Receiver::RECEIVER_WORKBUF_SIZE</tt> bytes.
42     void *pRecvBuf;     //!< Takes the starting address of the receive buffer.
43     u16   recvBufSize;  //!< Size (in bytes) of the receive buffer (<var>pRecvBuf</var>).
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  Class representing a device receiving data.
55 
56     The following description shows how to use the <tt>Receiver</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     <ol>
59       <li>Create an instance of the <tt>Receiver</tt> class.</li>
60 
61       <li>Call <tt>@ref Initialize</tt> to initialize the instance. (The receive buffer memory and the work memory for use by the <tt>Receiver</tt> instance are allocated at this time.)</li>
62 
63       <li>Call <tt>@ref Wait</tt> and wait for connection from a <tt>Sender</tt> instance.</li>
64 
65       <li>When the state changes to <tt>RECEIVER_STATE_OPENED</tt>, periodically call <tt>@ref Receive</tt> to write received data (to the memory buffer provided by the application).</li>
66 
67       <li>When the state changes to <tt>RECEIVER_STATE_FINISHED</tt> and you have confirmed that the size of data that can be read using <tt>@ref Receive</tt> has reached <tt>0</tt>, call <tt>@ref Close</tt>.</li>
68 
69       <li>When the state changes to <tt>RECEIVER_STATE_CLOSED</tt>, call <tt>@ref Finalize</tt> to clean up the <tt>Sender</tt> class.</li>
70     </ol>
71 
72 
73 
74 
75 
76 */
77 class Receiver{
78 public:
79     static const size_t RECEIVER_WORKBUF_SIZE = 128;  //!< Size of the working memory required by the <tt>Receiver</tt> instance.
80 
81     /*!
82     @brief  Instantiates an object.
83 
84     You must call <tt>@ref Initialize</tt> after calling this function to enable use of the <tt>Receiver</tt> instance.
85 
86 */
87     Receiver(void);
88 
89 
90     /*!
91     @brief  Destroys the object.
92 
93     If <tt>@ref Finalize</tt> has not been called yet, the destructor calls it.
94 
95 */
96     ~Receiver(void);
97 
98 
99     /*!
100     @brief  Initializes an instance.
101 
102     If initialization succeeds, this function implicitly consumes two <tt>nn::uds::EndpointDescriptor</tt> objects.
103     If initialization fails, the function returns without consuming any <tt>nn::uds::EndpointDescriptor</tt> objects.
104     Memory passed to the instance by this call must be allocated before calling <tt>@ref Finalize</tt>.
105 
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 
109     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>.
110 
111 
112     @param[in] config  Data structure storing initialization parameters. For more information, see <tt>ReceiverConfig</tt>.
113 
114     @return  Returns the result of initialization. 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 ResultAlreadyInitialized</tt>, <tt>@ref ResultNullPointer</tt>, or <tt>@ref ResultInvalidSize</tt>).
115 
116 
117 
118 
119 */
120     nn::Result Initialize(const ReceiverConfig &config);
121 
122 
123     /*!
124     @brief  Frees resources that were used by a <tt>Receiver</tt> instance, including the receive buffer and the endpoint descriptors.
125 
126     @return  None. Calls to <tt>@ref Finalize</tt> always succeed.
127     If <tt>@ref Finalize</tt> is called when the instance is not initialized, the function does nothing and returns.
128 
129 */
130     void Finalize(void);
131 
132 
133     /*!
134     @brief  Issues a request to wait for a connection.
135 
136     Issues a request to wait for a remote <tt>Sender</tt> instance to issue a connection request.
137     If the call to this function succeeds, the state changes to <tt>RECEIVER_STATE_WAITING</tt>.
138     The actual wait operation is performed by the <tt>@ref Process</tt> function.
139 
140     @return  Returns success if the request was accepted.
141     The function returns failure if it is called when the state of the instance is anything other than <tt>RECEIVER_STATE_CLOSED</tt>.
142     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>.
143 
144 
145 */
146     nn::Result Wait(void);
147 
148 
149     /*!
150     @brief  Issues a request to revert an instance to the <tt>CLOSED</tt> state.
151 
152     Call this function after you verify that all data has been received.
153     If the call to this function succeeds, the state transitions to <tt>RECEIVER_STATE_CLOSED</tt>.
154 
155     @return  Returns success if the request was accepted.
156     The function returns failure if it is called when the state of the instance is anything other than <tt>RECEIVER_STATE_FINISHED</tt>.
157     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>.
158 
159 
160 */
161     nn::Result Close(void);
162 
163 
164     /*!
165     @brief  Reads the data that has accumulated in the receive buffer.
166 
167     Reads the byte string that was sent from the <tt>Sender</tt> instance and has accumulated in the receive buffer.
168     This byte string is guaranteed to be obtainable in a form that maintains the byte sequence sent by <tt>nn::rdt::Sender::Send</tt>.
169 
170 
171     We recommend calling this function every game frame to improve throughput.
172 
173 
174     @param[out] pBuf  Specifies the starting address of the buffer where the received data is written.
175     @param[out] pRecvSize  Stores the number of bytes that were read from the receive buffer.
176     If no data was readable, this parameter is set to <tt>0</tt>.
177     @param[in] bufSize  Holds the size, in bytes, of the buffer where the received data is written.
178     If this parameter is set to <tt>0</tt>, the function does nothing and returns a non-error value.
179 
180     @return  Returns the result of the function.
181     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 <tt>@ref ResultDoNothing</tt>, <tt>@ref ResultNotInitialized</tt>, <tt>@ref ResultNullPointer</tt>, or <tt>@ref ResultUntimelyFunctionCall</tt> result code.
182 
183 
184 
185 */
186     nn::Result Receive(void *pBuf, size_t *pRecvSize, size_t bufSize);
187 
188 
189 /*!
190     @brief  Proceeds with communication. The actual communication occurs within this function.
191 
192     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.
193 
194     When sending and receiving real data, you can sometimes improve the transmission performance by calling this function several times in a row.
195 
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.
197 
198     For more information about specific settings, see the <tt>ServerClient</tt> sample demo.
199     Do not call other member functions (such as <tt>@ref Receive</tt>) while this function is running.
200     This results in undefined operations.
201     State transitions of <tt>Receiver</tt> instances are also handled within this function.
202 
203     @return  Returns the result of a series of communication operations.
204     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>.
205 
206 
207 */
208     nn::Result Process(void);
209 
210 
211     /*!
212     @brief  Cancels the operation.
213 
214     Call this function when you want to forcibly stop communication based on a command by the player.
215 
216     Calling this function makes the <tt>Receiver</tt> instance transition to the <tt>RECEIVER_STATE_CLOSED</tt> state.
217     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.
218 
219     @return  None. Calls to the <tt>@ref Cancel</tt> function always succeed.
220 */
221     void Cancel(void);
222 
223 
224     /*!
225     @brief  Gets the state of a <tt>Receiver</tt> instance.
226 
227     @return  Returns the state of the instance at the time this function was called.
228 */
229     enum ReceiverState GetStatus(void) const;
230 
231 
232     /*!
233     @brief  Sets up a simulated packet loss ratio (for debugging). This function may be removed in a future release without notice.
234 
235     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.
236     Set an appropriate random seed by calling <tt>std::srand</tt> before using this function.
237 
238 
239     @param[in] per  Provide a value so that <tt>0 <=</tt> <var>per</var> <tt><= 100</tt>.
240 
241     @return  None.
242 */
243     void SetPacketLossRatio(int per);
244 
245 
246     /*!
247     @brief  Prints detailed information about the internal state of a <tt>Receiver</tt> instance (for debugging). This function may be removed in a future release without notice.
248 
249     @return  None.
250 */
251     void PrintDebugInfo(void) const;
252 
253 
254 private:
255     /*!
256     @brief  The copy constructor is private.
257 */
258     Receiver           (const Receiver&);
259 
260 
261     /*!
262     @brief  The assignment operator is private.
263 */
264     Receiver& operator=(const Receiver&);
265 
266 
267     /*!
268     @brief  Private member variables.
269 */
270     ReceiverImpl *m_pImpl;
271 };
272 
273 //! @}
274 
275 }} // namespace nn::rdt
276 
277 #endif  // end of NN_RDT_RECEIVER_H_
278