1 /*--------------------------------------------------------------------------
2   Project:  Horizon
3   File:     rdt_Receiver.h
4 
5   Copyright (C)2010 Nintendo Co., Ltd.  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: 28630 $
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/CTR/rdt_define.h>
23 
24 #include <nn/types.h>
25 #include <nn/Result.h>
26 
27 
28 namespace nn { namespace rdt { namespace CTR {
29 
30 
31 class ReceiverImpl;
32 
33 /*!
34     @brief @ref Initialize に渡す初期化情報がまとめられた構造体です。
35  */
36 struct ReceiverConfig{
37     void *pWorkBuf;     //!< Receiverインスタンスがワークメモリとして使用する領域を指すポインタ。
38                         //!< 8byteアライメントが必要です。ワークメモリは、
39                         //!< Receiver::RECEIVER_WORKBUF_SIZE以上のサイズを確保してください。
40     void *pRecvBuf;     //!< 受信バッファの先頭アドレスを与えます。
41     u16   recvBufSize;  //!< pRecvBufで指定した受信バッファのサイズ(単位はByte)です。
42     u16   nodeId;       //!< UDS通信における相手のノードID
43     u8    port;         //!< UDS通信において使用するポート番号
44     u8    padding[3];   //!< パディング
45 #ifdef _WIN32
46     SOCKET sock;
47 #endif
48 };
49 
50 
51 /*!
52     @brief データの受信側を表現するクラスです。
53 
54 Receiverクラスの使い方を示します。以下の説明では、@ref Process の呼び出しに
55 ついての言及を省いていますが、実際にはゲームフレーム程度の周期、あるいはそれ以上の
56 周期で@ref Process を定期的に呼び出すことが必要となります。
57 
58 1. Receiverクラスのインスタンスを作成します。
59 
60 2. @ref Initialize を呼び出し、インスタンスを初期化します。
61 (このとき、Receiverインスタンスが内部で利用するワークメモリと、受信バッファ用の
62 メモリを割り当てます)
63 
64 3. @ref Wait を呼び出し、Senderインスタンスからの接続を待ちます。
65 
66 4. 状態がRECEIVER_STATE_OPENEDに遷移したら、定期的に @ref Receive を呼び出し、
67 到着したデータを(アプリケーション側が用意した領域に)書き込んでいきます。
68 
69 5. 状態がRECEIVER_STATE_FINISHEDに遷移し、@ref Receive で読み取ることの
70 できるデータサイズが0になったことを確認したら、@ref Close を呼び出します。
71 
72 6. 状態がRECEIVER_STATE_CLOSEDに遷移したら、@ref Finalize を呼び出し、Receiver
73 クラスの後始末をします。
74  */
75 class Receiver{
76 public:
77     static const size_t RECEIVER_WORKBUF_SIZE = 128;  //!< Receiverインスタンスが必要とするワークメモリのサイズです。
78 
79     /*!
80     @brief コンストラクタです。
81 
82            Receiverインスタンスを利用可能にするには、後で @ref Initialize を
83            呼ぶ必要があります。
84      */
85     Receiver(void);
86 
87 
88     /*!
89     @brief デストラクタです。
90 
91            @ref Finalize が呼ばれずにデストラクタが呼ばれた場合は、
92            ここで@ref Finalize が呼ばれます。
93      */
94     ~Receiver(void);
95 
96 
97     /*!
98     @brief インスタンスを初期化します。
99 
100            初期化が成功すると、内部で暗黙的に、@ref nn::uds::EndpointDescriptorが2つ消費されます。
101            初期化に失敗した場合は、@ref nn::uds::EndpointDescriptorは消費されずに関数が返ります。
102            この呼び出しでインスタンスに渡したメモリは、@ref Finalize を呼び出すまで
103            確保しておく必要があります。
104 
105     @param[in] config   初期化パラメータをまとめた構造体。詳細は ReceiverConifg を参照してください。
106 
107     @return 初期化処理の結果が返されます。具体的には、
108             @ref ResultSuccess, @ref ResultAlreadyInitialized, @ref ResultNullPointer, @ref ResultInvalidSize,
109             そのほか、UDS APIが返しうるリザルトコードが返される可能性があります。
110      */
111     nn::Result Initialize(const ReceiverConfig &config);
112 
113 
114     /*!
115     @brief Receiverインスタンスが使用していたリソース(受信バッファ・エンドポイントディスクリプタなど)を解放します。
116 
117     @return ありません。@ref Finalize の呼び出しは必ず成功します。
118             インスタンスの初期化がされていない状態で @ref Finalize を呼び出した場合は、
119             何も起こらずに関数呼び出しから返ります。
120      */
121     void Finalize(void);
122 
123 
124     /*!
125     @brief 接続を待ち受けるリクエストを発行します。
126 
127            リモートのSenderインスタンスが発行する接続要求を待ち受けるリクエストを発行します。
128            この関数呼び出しが成功すると、RECEIVER_STATE_WAITING状態に移行します。
129            実際の待ち受け動作は @ref Process 内部で実行されます。
130 
131     @return リクエストが受諾されれば、成功が返ります。
132             インスタンスの状態がRECEIVER_STATE_CLOSED以外のときにこの関数を呼び出すと、失敗が返ります。
133             具体的には、
134             @ref ResultSuccess, @ref ResultNotInitialized, @ref ResultUntimelyFunctionCall
135             が返される可能性があります。
136      */
137     nn::Result Wait(void);
138 
139 
140     /*!
141     @brief 状態をCLOSEDに戻すリクエストを発行します。
142 
143            全てのデータを受信できたと確認できてから呼ばれることを想定しています。
144            この関数呼び出しが成功すると、RECEIVER_STATE_CLOSED状態に移行します。
145 
146     @return リクエストが受諾されれば、成功が返ります。
147             インスタンスの状態がRECEIVER_STATE_FINISHED以外のときにこの関数を呼び出すと、失敗が返ります。
148             具体的には、
149             @ref ResultSuccess, @ref ResultNotInitialized, @ref ResultUntimelyFunctionCall
150             が返される可能性があります。
151      */
152     nn::Result Close(void);
153 
154 
155     /*!
156     @brief 受信バッファに溜められたデータを読み取ります。
157 
158            スループットの向上のために、この関数は毎ゲームフレーム程度の周期で
159            呼び出すことを推奨します。
160 
161     @param[out] pBuf      受信データの書き込み先バッファの先頭アドレスを与えます。
162     @param[out] pRecvSize 受信バッファから読み取ることのできたByte数が記録されます。
163                           読み取るデータが1Byteも存在していなかった場合は、0が書き込まれます。
164     @param[in]  bufSize   受信データの書き込み先バッファのサイズ(Byte数)を与えます。
165                           0を指定した場合は、何もせずに非エラーの値を返します。
166 
167     @return 関数の実行結果が返ります。
168             具体的には、
169             @ref ResultSuccess, @ref ResultDoNothing, @ref ResultNotInitialized,
170             @ref ResultNullPointer, @ref ResultUntimelyFunctionCall
171             が返される可能性があります。
172      */
173     nn::Result Receive(void *pBuf, size_t *pRecvSize, size_t bufSize);
174 
175 
176 /*!
177     @brief 通信処理を進行させます。実際の通信処理は、この関数の内部で実行されます。
178 
179            アプリケーションは、この関数を少なくとも毎ゲームフレーム程度の間隔で
180            呼び出す必要があります。
181            また、実データを送受信する局面においては、この関数を数回、連続して呼び出すことで、
182            送受信のパフォーマンスを改善できることがあります。
183            この関数呼び出し1回では、最大でも1400Byte程度の通信処理が行われるだけですが、
184            この関数を複数回呼び出すことで、より多くのデータを受信できる可能性が生まれます。
185            具体的なセッティングにつきましては、basicサンプルデモなどを参照してください。
186            なお、この関数の実行中は、他のメンバ関数(@ref Receive など)を呼ばないでください。
187            動作保証外となります。
188            Receiverインスタンスの状態遷移も、この関数の中で行われます。
189 
190     @return 一連の通信処理の結果が返ります。
191             具体的には、
192             @ref ResultSuccess, @ref ResultNotInitialized, @ref ResultResetReceived,
193             そのほか、UDS APIが返しうるリザルトコードが返される可能性があります。
194 */
195     nn::Result Process(void);
196 
197 
198     /*!
199     @brief 処理を中断します。
200 
201            プレイヤーの指示により、通信を強制的に中断したい場合などに
202            呼ばれることを想定しています。
203            この関数呼び出しにより、Receiverインスタンスは RECEIVER_STATE_CLOSED 状態に移行します。
204            この関数は、例外的に、@ref Process の実行を待たずに処理が実行されます。
205 
206     @return ありません。@ref Cancel 呼び出しは必ず成功します。
207      */
208     void Cancel(void);
209 
210 
211     /*!
212     @brief Receiverインスタンスの状態を取得します。
213 
214     @return 関数呼び出し時点でのインスタンスの状態が返されます。
215      */
216     enum ReceiverState GetStatus(void) const;
217 
218 
219     /*!
220     @brief 擬似的にパケロス率を設定します(デバッグ用)。この関数は、将来のリリースにおいて予告無く削除される可能性があります。
221 
222     @param[in] per      0 <= per <= 100の値を与えます。
223 
224     @return ありません。
225      */
226     void SetPacketLossRatio(int per);
227 
228 
229     /*!
230     @brief Receiverインスタンスの詳細な内部状態をプリントします(デバッグ用)。この関数は、将来のリリースにおいて予告無く削除される可能性があります。
231 
232     @return ありません。
233      */
234     void PrintDebugInfo(void) const;
235 
236 
237 private:
238     /*!
239     @brief コピーコンストラクタは封印します。
240      */
241     Receiver           (const Receiver&);
242 
243 
244     /*!
245     @brief 代入演算子は封印します。
246      */
247     Receiver& operator=(const Receiver&);
248 
249 
250     /*!
251     @brief プライベートメンバ変数。
252      */
253     ReceiverImpl *m_pImpl;
254 };
255 
256 
257 }}} // namespace nn::rdt::CTR
258 
259 #endif  // end of NN_RDT_RECEIVER_H_
260