1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: cec_Control.h
4
5 Copyright (C)2009 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: 31256 $
14 *---------------------------------------------------------------------------*/
15
16 #ifndef NN_CEC_CTR_CEC_CONTROL_H_
17 #define NN_CEC_CTR_CEC_CONTROL_H_
18 #include <nn/fnd.h>
19 #include <nn/cec/CTR/cec_Api.h>
20
21 namespace nn {
22 namespace cec {
23 namespace CTR {
24
25 struct CecAllocFunc
26 {
27 void* (*allocFunc)(size_t); //!< メモリアロケート関数へのポインタです。
28 void (*freeFunc)(void*); //!< メモリ解放関数へのポインタです。
29 };
30
31 //------------------------------------------------------------
32 // 通知用
33
34 /*!
35 @struct CecNotificationParam
36 @brief 受信情報のBOX個々の情報
37 */
38 struct CecNotificationParam
39 {
40 nn::fnd::DateTimeParameters recvDate; //!< 受信日時
41 u32 cecTitleId; //!< BOXの cecTitleId
42 u8 messageId[CEC_SIZEOF_MESSAGEID]; //!< 受信MessageのMessageID(先頭のMessageのみ)
43 };
44
45 /*!
46 @struct CecNotificationData
47 @brief 受信情報
48 */
49 struct CecNotificationData
50 {
51 size_t num; //!< 項目数
52 s32 count; //!< 受信回数(本体起動から) 通信が行われるとこの値が増加します。
53 CecNotificationParam param[MESSAGE_BOX_NUM_MAX]; //!< 個々のBOXの情報
54 };
55
56
57 /*!
58 @class CecControl
59 @brief Cecの状態を変更・情報の取得を行います。
60
61 Cecデーモンの状態はシステムに管理され、自動的に動作しています。<br>
62 MessageBoxへのアクセス(OpenMessageBox, ReadMessage, WriteMessage等)を行うと、
63 Cecデーモンの動作を中断してIDLE状態になります。<br>
64
65 */
66
67 class CecControl {
68
69 public:
70
71 enum ChangeDaemonState{
72 DAEMON_CHANGE_STATE_READY ,
73 DAEMON_CHANGE_STATE_STARTSCAN ,
74 DAEMON_CHANGE_STATE_STOP,
75 DAEMON_CHANGE_STATE_STOP_DAEMON,
76 DAEMON_CHANGE_STATE_START_DAEMON,
77 DAEMON_CHANGE_STATE_RESET_FILTER,
78
79 DAEMON_CHANGE_STATE_NDM_RESUME,
80 DAEMON_CHANGE_STATE_NDM_SUSPEND
81
82 };
83
84 /*!
85 @brief @ref GetCecState で取得される、Cecの状態を示す値です。DAEMON_STATE_IDLE のときしか BOXにアクセスすることはできません。
86 */
87 enum DaemonState
88 {
89 DAEMON_STATE_STOP, //!< 動作していません
90 DAEMON_STATE_IDLE, //!< 停止中
91 DAEMON_STATE_BUSY, //!< 処理中
92 DAEMON_STATE_SCAN, //!< スキャン中
93 DAEMON_STATE_READY, //!< READY状態(インターネット通信など、別の通信をしており、すれちがい通信に入っていない状態)
94 DAEMON_STATE_COMMUNICATING //!< 通信中
95 };
96
97
98 CecControl(size_t bufSize);
99 CecControl();
100 ~CecControl();
101
102 /*!
103 :private
104 * @brief cec に接続します。cec にアクセスするために最初に呼ぶ必要があります。
105 * @return nn::Result
106 */
107 static nn::Result Initialize();
108 //static nn::Result Initialize(CecAllocFunc& cecAllocFunc);
109 static nn::Result Initialize(nn::fnd::IAllocator& cecAllocFunc);
110 #if 0
111 static nn::Result InitializeSys();
112 #endif
113
114 /*!
115 :private
116 * @brief cec へのアクセスを終了します。
117 * @return nn::Result
118 */
119 static nn::Result Finalize();
120
121 #if 0
122 static nn::Result FinalizeSys();
123 #endif
124
125
126 static bool IsInitialized();
127 #if 0
128 static bool IsInitializedSys();
129 #endif
130
131 /*!
132 :private
133 * @brief cec を Ready 状態に移行させます。nn::cec::Initialize() ~ Finalize() の間は呼ぶことはできません。
134 (暫定的に用意されたAPIです。今後のバージョンでは、cecの状態を直接変更するAPIは削除されます。)
135 * @return nn::Result
136 */
137 static nn::Result ReadyDaemon();
138
139 /*!
140 * @brief cec の動作を開始させます。
141
142 MessageBox::CloseMessageBox の中で、 StartScanning(reset = false) が呼ばれます。
143
144 * @param[in] reset true をセットすると、BOXの内容を読み直して Scan を開始します。<br>
145 また、記憶していた通信相手のリストも消去され、同じ相手と再接続することが可能になります。このとき、設定中のボックスだけでなく、全てのボックス(アプリ)のデータが、再度交換される可能性があります。<br>
146 デバッグ時等、同じ相手と再接続する必要があるとき以外はtrueにしないでください。<br>
147 リストの消去は、nn::cec::CTR::MessageBox::DeleteMessageBox() で BOXを削除したときも行われます。
148
149 * @return nn::Result
150 * @retval ResultSuccess 成功しました。
151 * @retval ResultStateBusy Initialize が行われていないなどの理由で動作開始しませんでした。
152 * @retval 上記以外 失敗しました。
153 */
154 static nn::Result StartScanning(bool reset = false);
155
156 /*!
157 :private
158 * @brief ndmからcecをSuspendさせます。
159
160 * @return nn::Result
161 * @retval ResultSuccess 成功しました。
162 * @retval ResultStateBusy 停止処理を行いましたが、停止ステートになりませんでした。
163 * @retval 上記以外 失敗しました。
164 */
165 static nn::Result Suspend();
166
167 /*!
168 * @brief cec の動作を手動で停止します。
169
170 通信途中だった場合、通信を中断して停止(IDLE)ステータスに移行します。<br>
171 MessageBox にアクセスするには、停止状態である必要があります。<br>
172 MessageBox::OpenMessageBox の中で、 StopScanning(b_Immediate = true) が呼ばれます。<br>
173 事前にこの関数を使用することで、デーモンの動作を中断させず、停止状態になるのを待つことができます。<br><br>
174 b_Asyncにtrueをセットしたとき、複数回呼んでキャンセルが発生したときなど、この関数から抜けたときに停止ステータスになっていない可能性があります。<br>
175 この関数を呼んだ後に WriteMessage などを呼んでも、BUSY状態であるためにエラーになる可能性があるので注意してください。
176
177 * @param[in] b_Immediate true をセットすると、通信途中のデータの保存もキャンセルして停止させます。
178 * @param[in] b_Async true をセットすると、即座に返ります。
179 * @return nn::Result
180 * @retval ResultSuccess 成功しました。
181 * @retval ResultStateBusy 停止処理を行いましたが、停止ステートになりませんでした。
182 * @retval 上記以外 失敗しました。
183 */
184 static nn::Result StopScanning(bool b_Immediate = false, bool b_Async = false);
185
186 /*!
187 :private
188 * @brief CecDaemon を 停止させます。
189 (暫定的に用意されたAPIです。今後のバージョンでは、cecの状態を直接変更するAPIは削除されます。)
190
191 停止後は StartScanning を呼んでも動作開始しません。
192 * @return nn::Result
193 */
194 static nn::Result StopDaemon();
195
196 /*!
197 :private
198 * @brief CecDaemon を 動作開始させます。
199 (暫定的に用意されたAPIです。今後のバージョンでは、cecの状態を直接変更するAPIは削除されます。)
200 * @return nn::Result
201 */
202 static nn::Result StartDaemon();
203
204 /*!
205 :private
206 * @brief 受信したMessageの情報を取得します。
207 * @param[in] cecTitleId すれちがい通信ID を指定します。
208 * @param[out] pCecInfoBuffer CecNotificationData を受け取るバッファを指定します。
209 * @param[in] size バッファのサイズを指定します。
210 * @return nn::Result
211 */
212 static nn::Result GetCecInfoBuffer( u32 cecTitleId, u8 pCecInfoBuffer[], size_t size );
GetCecInfoBuffer(u8 pCecInfoBuffer[],size_t size)213 static nn::Result GetCecInfoBuffer( u8 pCecInfoBuffer[], size_t size )
214 {
215 return GetCecInfoBuffer( 0, pCecInfoBuffer, size );
216 };
217
218 /*!
219 * @brief CECの状態を取得します。
220 * @param[out] state 状態を示す @ref DaemonState が格納されます。 DAEMON_STATE_IDLE のときのみ、BOXにアクセス可能です。IDLE 以外の状態の遷移は外部から変更できない為、それぞれの状態をハンドリングする必要はありません。
221 * @return nn::Result
222 * @retval ResultSuccess 成功しました。
223 */
224 static nn::Result GetCecState( DaemonState* state );
225 static nn::Result GetCecState( u32* state );
226
227 static bool IsDaemonBusy(void);
228
229 /*!
230 :private
231 * @brief 受信の通知を受ける Event をセットします。
232 * @param[out] event 受信があったときに Signal される Event です。
233 * @return nn::Result
234 */
235 static nn::Result GetCecRecvEventHandle( nn::os::Event* event );
236
237 static nn::Result GetChangeStateEventHandle( nn::os::Event& event );
238
239 static nn::cec::CTR::TitleId MakeCecTitleId(bit32 id, bit8 variation = 0x0);
240
241 /* @brief NAND上の CECのBOX保存領域をフォーマットします。デバッグ用です。 */
242 static nn::Result FormatSaveData();
243
244 private:
245 static bool s_Initialized;
246 static bool s_NdmSuspended;
247
248 };
249
250
251
252
253 //! @name Initialize / Finalize
254 //@{
255
256
257 /*!
258 * @brief CEC Daemon に接続します。CEC MessageBox にアクセスするために最初に呼ぶ必要があります。
259
260 * @param[in] cecAllocFunc CEC ライブラリが使用するアロケータを指定します。
261
262 CEC ライブラリのMessageデータ処理に必要なメモリを確保するために
263 使用されます。最大で扱うMessageデータサイズ × 2 程度のメモリが使用されます。
264 * @return nn::Result
265 */
266 nn::Result Initialize(nn::fnd::IAllocator& cecAllocFunc);
267
268 /*!
269 * @brief CEC Daemon に接続します。CEC MessageBox にアクセスするために最初に呼ぶ必要があります。
270
271 * @return nn::Result
272 * @retval ResultSuccess 成功しました。
273 * @retval 上記以外 失敗しました。
274 */
275 nn::Result Initialize();
276
Initialize()277 inline nn::Result Initialize()
278 {
279 return CecControl::Initialize();
280 }
281
282 nn::Result Initialize(nn::cec::CTR::CecAllocFunc& cecAllocFunc);
283
Initialize(nn::fnd::IAllocator & cecAllocFunc)284 inline nn::Result Initialize(nn::fnd::IAllocator& cecAllocFunc)
285 {
286 return CecControl::Initialize(cecAllocFunc);
287 }
288
289 /*!
290 * @brief CEC Daemon へのアクセスを終了します。
291 * @return nn::Result
292 * @retval ResultSuccess 成功しました。
293 * @retval 上記以外 失敗しました。
294 */
295 nn::Result Finalize();
296
Finalize()297 inline nn::Result Finalize()
298 {
299 return CecControl::Finalize();
300 }
301
302 //@}
303
304 //! @name 受信通知
305 //@{
306
307 /*!
308 * @brief 受信の通知を受ける Event を指定します。
309
310 すれちがい通信が発生したときにSignalされるEventです。<br>
311 通信したことをリアルタイムに知りたいときに使用することができます。<br>
312 フォアグラウンドのアプリケーション宛のデータがあるかどうかは、
313 @ref GetCecInfoBuffer 等で確認することができます。
314
315 * @param[out] event 受信があったときに Signal される Event です。
316 * @return nn::Result
317 * @retval ResultSuccess 成功しました。
318 */
319 nn::Result GetCecRecvEventHandle( nn::os::Event* event );
GetCecRecvEventHandle(nn::os::Event * event)320 inline nn::Result GetCecRecvEventHandle( nn::os::Event* event )
321 {
322 return CecControl::GetCecRecvEventHandle( event );
323 }
324
325
326 /*!
327 * @brief 直前の通信で受信したMessageの情報を取得します。
328
329 @ref GetCecRecvEventHandle を使用して受信の通知を受け取った後、
330 フォアグラウンドのアプリケーション宛のデータがあるかどうかを調べる時等に使用できます。<br>
331 グルーピングされた複数のMessageを受け取ったときでも、取得できる情報は1つ分だけです。<br>
332 また、重複していたために破棄された受信データの情報は入りません。
333
334 * @param[in] cecTitleId すれちがい通信ID を指定します。
335 * @param[out] pCecInfoBuffer CecNotificationData を受け取るバッファを指定します。
336 * @param[in] size バッファのサイズを指定します。
337 * @return nn::Result
338 * @retval ResultSuccess 成功しました。
339 * @retval ResultNoData 取得できるデータがありませんでした。
340 */
341 nn::Result GetCecInfoBuffer( u32 cecTitleId, u8 pCecInfoBuffer[], size_t size );
342 nn::Result GetCecInfoBuffer( u8 pCecInfoBuffer[], size_t size );
343
GetCecInfoBuffer(u32 cecTitleId,u8 pCecInfoBuffer[],size_t size)344 inline nn::Result GetCecInfoBuffer( u32 cecTitleId, u8 pCecInfoBuffer[], size_t size )
345 {
346 return CecControl::GetCecInfoBuffer(cecTitleId, pCecInfoBuffer, size );
347 }
348
GetCecInfoBuffer(u8 pCecInfoBuffer[],size_t size)349 inline nn::Result GetCecInfoBuffer( u8 pCecInfoBuffer[], size_t size )
350 {
351 return CecControl::GetCecInfoBuffer(0, pCecInfoBuffer, size );
352 }
353
354 //@}
355
356
357 /*!
358 @brief 20bit のユニーク ID から、すれちがい通信で使用する
359 32bit の すれちがい通信ID(CecTitleId) を生成します。
360
361 @param[in] id 20bit の ユニークID です。複数タイトル間で共通のボックスを使用して通信したい場合は、どちらか片方のユニーク ID を指定してください。
362 @param[in] variation 使用しません。
363 * @return CecTitleId
364 */
365 nn::cec::CTR::TitleId MakeCecTitleId(bit32 id, bit8 variation = 0x0);
MakeCecTitleId(bit32 id,bit8 variation)366 inline nn::cec::CTR::TitleId MakeCecTitleId(bit32 id, bit8 variation)
367 {
368 return CecControl::MakeCecTitleId(id, variation);
369 }
370
371 } // end of namespace CTR
372 } // end of namespace cec
373 } // end of namespace nn
374
375
376
377 #endif // ifndef NN_CEC_CTR_CEC_CONTROL_H_
378