1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     uds_Type.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: 31395 $
14  *---------------------------------------------------------------------------*/
15 
16 /*! @file
17     @brief    UDS 型の定義
18 */
19 
20 #ifndef NN_UDS_CTR_UDS_TYPE_H_
21 #define NN_UDS_CTR_UDS_TYPE_H_
22 
23 #include <nn.h>
24 #include <nn/cfg.h>
25 
26 namespace nn {
27 namespace uds {
28 namespace CTR {
29 
30     namespace
31     {
32         const char PORT_NAME_UDS[]    = "nwm::UDS";
33     }
34 
35 const u16 BROADCAST_NODE_ID = 0xffff;               //!<ネットワークの全ノード宛を示す ノード ID です。 BROADCAST_NODE_ID 宛に送信したデータは Spectator も取得可能です。
36 
37 const u8 NODE_MAX     = 16;                         //!< ネットワークの最大接続数の最大値です。将来的に 16 台通信をサポートする予定ですが、CTR-SDK 0.14 現在では多台数での十分な動作確認が行えていないため 13 台以上の通信は動作保証範囲外とします。
38 const u8 ENDPOINT_MAX = 16;                         //!< 生成できる endpoint の最大数です。この値は将来変更される可能性があります。
39 
40 const u16 UDS_PACKET_PAYLOAD_MAX_SIZE   = 1478;     //!< 一回の @ref nn::uds::CTR::SendTo で送信可能なデータの最大サイズです。
41 const u8  NET_DESC_APPDATA_SIZE_MAX      = 200;     //!< ビーコンにセットできる任意データの最大サイズです。
42 
43 /*!
44   @name   ローカル通信 ID 関連
45   @{
46 */
47 const bit32 TEST_UNIQUE_ID_MASK = 0x000FFF00;  //!< テストプログラムや実験プロジェクトなど アプリケーションのユニーク ID が割り当てられない場合、0xFFF00 - 0xFFFFF をテスト用IDとして利用可能です。SDK のサンプルもこれを利用します。
48 /*!
49   @}
50 */
51 /*!
52   @name   送受信オプション
53   @{
54 */
55 const bit8 NO_WAIT = 0x01;         //!< @ref SendTo で指定した場合、UDS 内のバッファリングを省略し、即時無線送信を行います。 <BR> @ref Receive / @ref ReceiveFrom で指定した場合、データを受信していない場合でも即時終了します。
56 const bit8 FORCE_DIRECT_BC = 0x02; //!< @ref SendTo で指定した場合、送信先を問わず Direct Broadcast 送信します。Client 間の Unicast 通信もMaster を介さないため、低レイテンシで通信できますが、隠れ端末問題が生じます。
57 const bit8 FORCE_UNICAST   = 0x04; //!< @ref SendTo で指定した場合、Client は必ず Master を経由してパケットを送信します。隠れ端末問題を考慮する必要がなくなりますが、Client の送信のレイテンシが高くなります。
58 /*!
59   @}
60 */
61 
62 const u8 MAC_ADDRESS_SIZE   = 6;
63 const u8 OUI_SIZE           = 3;
64 
65 /*!
66   @brief        UDS のステートを表す列挙型です。
67 */
68 enum State
69 {
70     STATE_NONE,                     //!< 未初期化 (Initialize をしていない) 状態です
71     STATE_PROCESSING_INITIALIZE,    //!< Initialize 処理中を示す内部ステートです。アプリがこの値を取得することはありません
72     STATE_PROCESSING_FINALIZE,      //!< Finalize 処理中を示す内部ステートです。アプリがこの値を取得することはありません
73     STATE_DISCONNECTED,             //!< 通信を行っていない(未接続)状態です
74     STATE_CREATING_NETWORK,         //!< 未接続状態から、新規にネットワークを構築し Master として動作するまでの中間ステートです。 自動的に STATE_MASTER に遷移します
75     STATE_DESTROYING_NETWORK,       //!< Master としての動作を終了し、未接続状態になるまでの中間ステートです。 自動的に STATE_DISCONNECTED に遷移します
76     STATE_MASTER,                   //!< Master として動作している状態です
77     STATE_CONNECTING_NETWORK,       //!< 未接続状態から、指定したネットワークを構築し Client もしくは Spectator として動作するまでの中間ステートです。接続に失敗した場合は STATE_DISCONNECTED に、接続に成功した場合は STATE_CLIENT/STATE_SPECTATOR に遷移します
78     STATE_DISCONNECTING_NETWORK,    //!< ネットワークから離脱し、未接続状態になるまでの中間ステートです。 自動的に STATE_DISCONNECTED に遷移します。
79     STATE_CLIENT,                   //!< Client として動作している状態です。通信状況が悪化しネットワーク接続が維持できなくなった場合、自動的に STATE_DISCONNECTING_NETWORK に遷移します。
80     STATE_SPECTATOR,                //!< Spectator として動作している状態です。通信状況が悪化しネットワーク接続が維持できなくなった場合、自動的に STATE_DISCONNECTING_NETWORK に遷移します。
81     STATE_ERROR,                    //!< UDS ライブラリを Finalize すべき状態です。UDS を使用中に無線スイッチが OFF されたり、スリープが発生した場合に遷移します。
82     STATE_MAX,
83     STATE_MAX_BIT = (1u << 31)
84 
85 };
86 
87 const State STATE_AUDIENCE = STATE_SPECTATOR;
88 
89 /*!
90   @brief        切断理由を表す列挙型です。
91 */
92 enum DisconnectReason
93 {
94     BEFORE_COMMUNICATION,       //!< まだ通信をしていない状態を示します。
95     NETWORK_IS_AVAILABLE,       //!< 接続は維持されている
96     REQUEST_FROM_MYSELF,        //!< 自身の操作でネットワークから切断した
97     REQUEST_FROM_SYSTEM,        //!< CTR のシステムからの要求 (無線OFFモードへの遷移、スリープ遷移) でネットワークから切断した
98     DISCARDED_FROM_NETWORK,     //!< Master からの指示でネットワークから追放された
99     CONNECTION_LOST,            //!< 通信状況が悪化し、接続が維持できなくなった
100     UNKNOWN_DISCONNECT_REASON,   //!< 未知の理由で切断された
101     DISCONNECT_REASON_MAX,
102     DISCONNECT_REASON_MAX_BIT = (1u << 31)
103 };
104 
105 /*!
106   @brief        ネットワークに接続する際のモードを表す列挙型です。
107 */
108 enum ConnectType
109 {
110     CONNECT_AS_CLIENT = 1,          //!< Client ( 送受信が行え、接続時に ノードID が付与されるノード)  としてネットワークに接続
111     CONNECT_AS_SPECTATOR,           //!< Spectator ( 受信のみが可能な、接続時に ノードID が付与されないノード ) としてネットワークに接続
112     CONNECT_AS_MASTER               //!< Master としてネットワークに接続 (ライブラリの内部でのみ使用します)
113 };
114 
115 const ConnectType CONNECT_AS_AUDIENCE  = CONNECT_AS_SPECTATOR ;
116 
117 /*!
118   @brief        ネットワークの省電力モードを表す列挙型です。
119 */
120 enum PowerSaveMode
121 {
122     ALWAYS_ACTIVE,      //!< レイテンシ/トラフィック重視で、省電力機能を使わないモード
123     POWERSAVE_NORMAL,   //!< 通常設定です。レイテンシが高くなりますが ALWAYS_ACTIVE よりも 20% 弱通信にかかる電力が低減します。
124     POWERSAVE_HIGH,      //!< 省電力重視設定です。レイテンシが高くなりますが ALWAYS_ACTIVE よりも 50% 弱通信にかかる電力が低減します。
125     POWERSAVE_MODE_MAX
126 };
127 
128 /*!
129   @brief        通信品質(リンクレベル) を表す列挙型です。 リンクレベルは現在調整中です。
130 */
131 enum LinkLevel
132 {
133     LINK_LEVEL_0 = 0,   //!< 非常に通信品質が悪い、もしくは通信が成立していない
134     LINK_LEVEL_1,       //!< 通信品質が悪い
135     LINK_LEVEL_2,       //!< 通信品質があまり良くない
136     LINK_LEVEL_3        //!< 通信品質がよい
137 };
138 
139 
140 
141 /*!
142   @brief        UDS の接続状態を示す構造体です。
143 */
144 struct ConnectionStatus
145 {
146     State               nowState;                   //!< 現在のステート
147     DisconnectReason    disconnectReason;           //!< 切断理由。 ネットワーク接続中は必ず NETWORK_IS_AVAILABLE を返します
148     u16                 myNodeId;                   //!< 自身のノードID
149     bit16               updateNodeBitmap;           //!< 前回 GetConnectionStatus した時から変化のあった NodeID リストを示すビットマップです。
150     u16                 nodeIdList[NODE_MAX];       //!< 現在ネットワークに接続しているノードの一覧。
151     u8                  nowEntry;                   //!< ネットワークに接続しているノードの数
152     u8                  maxEntry;                   //!< ネットワークの最大同時接続数 (通信中に変化することはありません)
153     bit16               slotBitmap;                 //!< どのスロットにノード情報が格納されているかを示すビットマップです。 updateNodeBitmap と異なり、前回の差分ではありません。
154 };
155 
156 static const size_t SCRAMBLED_LOCAL_FRINED_CODE_SIZE = 12; //!< @ref ScrambledLocalFriendCode のバイト長です。
157 
158 /*!
159   @brief @ref friends ライブラリを利用することで、ローカルフレンドコードに変換可能な情報です。
160 
161         ローカル通信でフレンド機能を容易に行えるように、かつ特定ユーザーの追跡は出来ないというユーザーのプライバシーを守る意味合いから
162         UDS ライブラリではローカルフレンドコードそのものではなく、 @ref friends ライブラリに問い合わせることでローカルフレンドコードを
163         取得可能な @ref SCRAMBLED_LOCAL_FRINED_CODE_SIZE Byte のデータ列を取得するようにしています。
164 
165         このデータは同じデバイスでも次回の通信では別の値になるため、デバイスを特定する用途には利用できません。
166 */
167 struct ScrambledLocalFriendCode
168 {
169         bit16 value[SCRAMBLED_LOCAL_FRINED_CODE_SIZE/sizeof(bit16)];
170 };
171 
172 /*!
173   @brief        ネットワークに接続しているノードのユーザー情報を示す構造体です。
174 */
175 struct NodeInformation
176 {
177     ScrambledLocalFriendCode scrambledLocalFriendCode; //!< プライバシー保護を考慮した、friends ライブラリ経由でローカルフレンドコードに変換可能なデータです。
178     nn::cfg::CTR::UserName userName; //!< ユーザー名情報です。 詳細は @ref nn::cfg::CTR::UserName を参照してください
179     u16     nodeId;             //!< ノードID
180     NN_PADDING2;
181 };
182 
183 const u8 NODE_INFORMATION_SIZE = sizeof(NodeInformation);
184 
185 /*!
186   @brief        endpoint ディスクリプタ。ソケット記述子に相当します。
187 
188                 現在は ID のみを格納していますが、今後フィールドが追加される可能性があります。
189 */
190 struct EndpointDescriptor
191 {
192     u32  id;                 //!< @ref CreateEndpoint を実行する毎に振り分けられる ID です。
193 };
194 
195 
196 //以下 内部処理で使用する定義です。
197 namespace detail{
198 
199     /*!
200     :private
201     @brief RadioStrengthInfo クラス内部用の構造体です。
202     */
203     struct RadioStrength
204     {
205         s8   rssi;
206         bool isValid;
207     };
208 
209     /*!
210     :private
211     @class nn::uds::CTR::detail::RadioStrengthInfo
212     @brief GeLinkLevel よりも詳細な受信している電波の強さを取得します。@ref GetRadioStrangthInfo で取得してください。
213            取得できる値は相対的な電波の強弱を判断するための指標としてお使い下さい。
214     */
215     class RadioStrengthInfo
216     {
217     public:
RadioStrengthInfo()218         RadioStrengthInfo(){m_IsInitialized = false;}
219         void Initialize( const RadioStrength& masterLink, const RadioStrength directLink[NODE_MAX] );
~RadioStrengthInfo()220         ~RadioStrengthInfo(){m_IsInitialized = false;}
221 
222         s8 GetAverage();    //!< 自身が受信している電波強度の平均値
223         s8 GetMinimum();    //!< 自身が受信している電波強度の最小値
224         s8 GetMaximum();    //!< 自身が受信している電波強度の最大値
225         s8 GetMasterLink(); //!< Master から受信される電波の強度、自身が Master の場合は 0
226 
227     private:
228         bool m_IsInitialized;
229         void GetRawData(s8 rawLink[NODE_MAX] ); //!< 自身が受信している電波の強度の生データを取得 (0=無効なデータ)
230 
231         RadioStrength m_MasterLink;
232         RadioStrength m_DirectLink[NODE_MAX];
233     };
234 
235     // DestroyEndpoint 時に取得可能な Endpoint 毎の受信結果
236     struct ReceiveReport
237     {
238         u32 id;             //!< Endpoint の ID ( EndpointDescriptor.id )
239         u16 targetNodeId;   //!< 対象ノード ID
240         u16 port;           //!< ポート番号
241         u32 receiveCount;   //!< Attach した Endpoint が受信したパケット総数
242         u32 lostCount;      //!< 受信バッファ溢れによってロストしたパケット数
243     };
244 
UDS_BE2LE16(u16 value)245     inline u16 UDS_BE2LE16( u16 value )
246     {
247         return static_cast<u16>( (((value) & 0xFF00UL) >> 8UL) | (((value) & 0x00FFUL) << 8UL));
248     }
249 
UDS_BE2LE32(u32 value)250     inline u32 UDS_BE2LE32( u32 value )
251     {
252     return static_cast<u32>( (((value) & 0xFF000000UL) >> 24UL) | (((value) & 0x00FF0000UL) >> 8UL) | (((value) & 0x0000FF00UL) << 8UL) | (((value) & 0x000000FFUL) << 24UL));
253     }
254 
UDS_BE2LE64(u64 value)255     inline u64 UDS_BE2LE64( u64 value )
256     {
257         u64 returnValue;
258         u32* tmpA = reinterpret_cast<u32*>(&(returnValue));
259         u32* tmpB = reinterpret_cast<u32*>(&(value));
260 
261         tmpA[0] = UDS_BE2LE32(tmpB[1]);
262         tmpA[1] = UDS_BE2LE32(tmpB[0]);
263 
264         return returnValue;
265     }
266 
UDS_LE2BE32(u32 value)267     inline u32 UDS_LE2BE32( u32 value)
268     {
269         return static_cast<u32>( (((value) & 0xFF000000UL) >> 24UL) | (((value) & 0x00FF0000UL) >> 8UL) | (((value) & 0x0000FF00UL) << 8UL) | (((value) & 0x000000FFUL) << 24UL));
270     }
271 
UDS_LE2BE16(u16 value)272     inline u16 UDS_LE2BE16( u16 value )
273     {
274         return static_cast<u16>( (((value) & 0xFF00UL) >> 8UL) | (((value) & 0x00FFUL) << 8UL));
275     }
276 
UDS_LE2BE64(u64 value)277     inline u64 UDS_LE2BE64( u64 value )
278     {
279         u64 returnValue;
280         u32* tmpA = reinterpret_cast<u32*>(&(returnValue));
281         u32* tmpB = reinterpret_cast<u32*>(&(value));
282 
283         tmpA[0] = UDS_LE2BE32(tmpB[1]);
284         tmpA[1] = UDS_LE2BE32(tmpB[0]);
285 
286         return returnValue;
287     }
288 
289 /*
290 inline u32 UDS_LE2BE32( u32 value)
291 {
292     NN_ASM("rev value, value");
293     return value;
294 }
295 */
296 
297 } //end of namespace detail
298 
299 } // end of namespace CTR
300 } // end of namespace uds
301 } // end of namespace nn
302 
303 #endif /* NN_UDS_CTR_UDS_TYPE_H_ */
304