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