1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: cec_Message.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: 31024 $ 14 *---------------------------------------------------------------------------*/ 15 #ifndef NN_CEC_CTR_CEC_MESSAGE_H_ 16 #define NN_CEC_CTR_CEC_MESSAGE_H_ 17 18 #include <nn/fnd.h> 19 #include <nn/cec/CTR/cec_Const.h> 20 #include <nn/cec/CTR/cec_Types.h> 21 22 namespace nn { 23 namespace cec { 24 namespace CTR { 25 26 27 // メッセージデータ構造 28 struct CecMessageHeader; 29 30 #define CEC_EXHEADER_NUM_MAX (16) 31 #define CEC_EXHEADER_SIZE_MAX (8*1024) 32 33 /*! 34 :private 35 @struct CecMessageExHeader 36 @brief CEC の Message の拡張ヘッダ形式 37 */ 38 struct CecMessageExHeader 39 { 40 u32 exHeaderType; //!< 拡張ヘッダタイプ @ref CecMessageExHeaderType で指定します。 41 u32 exHeaderLen; //!< 拡張ヘッダデータ長 42 u8* exHeaderData; //!< 拡張ヘッダデータ 43 }; 44 45 #define LOAD_FLAG_POINTER 1 46 #define LOAD_FLAG_MALLOC 0 47 48 /*! 49 @class Message 50 @brief CEC Message を扱うクラスです。 51 */ 52 class Message 53 { 54 private: 55 struct CecMessageHeader m_cec_mh; 56 struct CecMessageExHeader m_cec_mhex[CEC_EXHEADER_NUM_MAX] NN_ATTRIBUTE_ALIGN(4); 57 s8 numOfExHeader; 58 NN_PADDING3; 59 u8* m_messBody; 60 u32 m_messBodyLen; 61 62 u8* m_pMessBody; 63 64 u8* m_pHash; 65 u32 m_hashSize; 66 67 u8 m_flag_pointer; 68 69 u8 m_flag_input; 70 71 u8 m_hmacKey[MESSAGE_HMAC_KEYLEN]; 72 73 NN_PADDING2; 74 75 u32 calcCecMessSize(); 76 nn::Result Init_Message(); 77 nn::Result SetExHeaderWithoutCalc(MessageExHeaderType exhType, size_t exhLen, const void* exhBody); 78 nn::Result SetMessageBodyWithoutCalc(const void* dataBody, size_t size); 79 nn::Result SetHmacSha256(void* input); 80 nn::Result GetHmacSha256(void* outBuf, u32 size = CEC_SIZEOF_HASH) const; 81 public: 82 83 /*! 84 * @brief コンストラクタ 85 * @return 86 */ 87 Message(); 88 89 Message(const void* messData, size_t messSize); 90 ~Message(); 91 92 93 94 //! @name 新規Message作成 95 //@{ 96 /*! 97 * @brief 新規 Message を作成します。 98 99 この関数で基本的なパラメータがセットされます。<br> 100 @ref SetMessageBody で本文部のデータをセットし、 @ref MessageBox::WriteMessage で送信BOXに書き込むと、すれちがい通信時にMessageが送信されます。 101 102 * @param[in] cecTitleId すれちがい通信ID 103 * @param[in] groupId Message グルーピングID<br> @ref SetGroupID でセットされる値と同じです。 104 * @param[in] messageTypeFlag Friend/非Friend を @ref MessageTypeFlag で指定します。 105 * @param[in] sendMode 送信モード(受信のみ/送信のみ/送受信/交換)を @ref SendMode で指定します。<br> @ref SetSendMode でセットされる値と同じです。 106 * @param[in] sendCount 送信回数<br> 送信回数と伝播回数は、同時に2以上にすること(複数回送信+伝播)はできません。 107 * @param[in] propagationCount 伝播回数<br> 送信回数と伝播回数は、同時に2以上にすること(複数回送信+伝播)はできません。 108 * @param[in] icon アイコンを指定します。<br> 109 フォーマット: RGB565 (リトルエンディアン)<br> 110 サイズ: 40×40 (3200Bytes)<br> 111 * @param[in] iconSize アイコンのデータサイズを指定します。 112 * @param[in] infoTextData Message の説明文をセットします。<br> 113 文字コード: UTF16-LE<br> 114 表示サイズ: 全角16文字×2行で表示できる文字数<br> 115 バッファ最大: 128×2Bytes (改行やNULL終端込み)<br> 116 * @param[in] infoTextSize Message の説明文のデータサイズを指定します。 117 * @return nn::Result 118 * @retval ResultSuccess 成功しました。 119 * @retval ResultInvalidArgument 無効な値が設定されています。 120 * @retval ResultInvalidCombination 送信回数と伝播回数の値が共に2以上に設定されています。 121 * @retval 上記以外 失敗しました。 122 */ 123 nn::Result NewMessage( 124 TitleId cecTitleId, u32 groupId, 125 MessageTypeFlag messageTypeFlag, SendMode sendMode, 126 u8 sendCount, u8 propagationCount, 127 void* icon, size_t iconSize, 128 wchar_t* infoTextData, size_t infoTextSize); 129 /*! 130 * @brief 新規 Message を作成します。 131 132 この関数で基本的なパラメータがセットされます。<br> 133 @ref SetMessageBody で本文部のデータをセットし、 @ref MessageBox::WriteMessage で送信BOXに書き込むと、すれちがい通信時にMessageが送信されます。<br> 134 <br> 135 アイコンとMessageの説明文のセットを別途行う必要があります。 136 137 * @param[in] cecTitleId すれちがい通信ID 138 * @param[in] groupId Message グルーピングID<br> @ref SetGroupID でセットされる値と同じです。 139 * @param[in] messageTypeFlag Friend/非Friend を @ref MessageTypeFlag で指定します。 140 * @param[in] sendMode 送信モード(受信のみ/送信のみ/送受信/交換)を @ref SendMode で指定します。<br> @ref SetSendMode でセットされる値と同じです。 141 * @param[in] sendCount 送信回数<br> 送信回数と伝播回数は、同時に2以上にすること(複数回送信+伝播)はできません。 142 * @param[in] propagationCount 伝播回数<br> 送信回数と伝播回数は、同時に2以上にすること(複数回送信+伝播)はできません。 143 * @return nn::Result 144 * @retval ResultSuccess 成功しました。 145 * @retval ResultInvalidArgument 無効な値が設定されています。 146 * @retval ResultInvalidCombination 送信回数と伝播回数の値が共に2以上に設定されています。 147 * @retval ResultTooLarge データサイズが大きすぎます。 148 * @retval ResultNotAuthorized 既にMessageIdが割り振られて確定されたメッセージを編集しようとしています。 149 * @retval 上記以外 失敗しました。 150 */ 151 nn::Result NewMessage( 152 TitleId cecTitleId, u32 groupId, 153 MessageTypeFlag messageTypeFlag, SendMode sendMode, 154 u8 sendCount, u8 propagationCount); 155 //@} 156 157 158 //! @name パラメータ 159 //@{ 160 /*! 161 :private 162 * @brief Message に すれちがい通信ID をセットします。 163 * @param[in] cecTitleId Title固有ID 164 * @return nn::Result 165 * @retval ResultSuccess 成功しました。 166 * @retval 上記以外 失敗しました。 167 */ 168 nn::Result SetCecTitleId(TitleId cecTitleId); 169 170 /*! 171 * @brief Message の すれちがい通信ID を取得します。 172 * @return CecTitleId 173 */ 174 u32 GetCecTitleId() const; 175 176 nn::Result SetCecTitleId_Str(const u8* cecTitleId_str); 177 u8* GetCecTitleId_Str() const; 178 179 /*! 180 * @brief Message に Group ID をセットします。送信BOX内の同じGroupIDを持つ Message が 181 グルーピングされ、一緒に送信されます。 182 183 ・1送信の最大サイズ以上はグルーピングされません。<br> 184 ・0 を指定した場合は、グルーピングされず、単独で送信されます。 185 186 * @param[in] groupId Group ID 187 * @return nn::Result 188 * @retval ResultSuccess 成功しました。 189 * @retval 上記以外 失敗しました。 190 */ 191 nn::Result SetGroupID(u32 groupId); 192 193 /*! 194 * @brief Message の Group ID を取得します。送信BOX内の同じGroupIDを持つ Message が 195 グルーピングされ、一緒に送信されます。 196 * @return Group ID 197 */ 198 u32 GetGroupID() const; 199 200 201 nn::Result SetSessionID(u32 sessionId); 202 u32 GetSessionID() const; 203 204 /*! 205 :private 206 * @brief Message のサイズを指定します。 207 * @param[in] messSize サイズ 208 * @return nn::Result 209 */ 210 nn::Result SetMessSize(const u32 messSize); 211 212 /*! 213 * @brief Message の サイズを取得します。 214 * @return サイズの値 215 */ 216 u32 GetMessSize() const; 217 218 /*! 219 :private 220 * @brief Message Header のサイズを指定します。 221 * @param[in] headerSize サイズ 222 * @return nn::Result 223 */ 224 nn::Result SetHeaderSize(u32 headerSize); 225 226 /*! 227 * @brief 拡張ヘッダを含む、Message Header の サイズを取得します。 228 * @return サイズの値 229 */ 230 u32 GetHeaderSize() const; 231 232 /*! 233 :private 234 * @brief Message 本文 のサイズを指定します。 235 * @param[in] bodySize サイズ 236 * @return nn::Result 237 */ 238 nn::Result SetBodySize(u32 bodySize); 239 240 /*! 241 * @brief Message 本文 の サイズを取得します。 242 * @return サイズの値 243 */ 244 u32 GetBodySize() const; 245 246 /*! 247 :private 248 * @brief Message の MessageID を指定します。 249 * @param[in] messId MessageID 250 * @return nn::Result 251 */ 252 nn::Result SetMessageId(const MessageId& messageId); 253 254 /*! 255 * @brief Message の MessageID を取得します。MessageID は、 256 Messageを作成して保存したときに付与されます。 257 * @param[out] messId MessageID 258 * @return MessageId 259 */ 260 MessageId GetMessageId(MessageId* messId) const; 261 262 nn::Result SetMessageVersion(const u32 messVersion); 263 u32 GetMessageVersion() const; 264 265 /*! 266 :private 267 * @brief 交換された Message の MessageID を指定します。 268 * @param[in] messIdPair MessageId 269 * @return nn::Result 270 */ 271 nn::Result SetMessageId_Pair(const MessageId& messIdPair); 272 273 /*! 274 * @brief 交換された Message の MessageID を取得します。通信の方式に「交換」を 275 指定して通信したとき、対になる 送信 Message の MessageID が、受信 Message に記録されます。 276 * @param[out] messIdPair MessageId 277 * @return MessageId 278 */ 279 MessageId GetMessageId_Pair(MessageId* messIdPair) const; 280 281 /*! 282 * @brief 送信対象を @ref MessageTypeFlag で指定します。 283 * @param[in] messTypeFlag @ref MessageTypeFlag 284 * @return nn::Result 285 * @retval ResultSuccess 成功しました。 286 */ 287 nn::Result SetMessageTypeFlag(MessageTypeFlag messTypeFlag); 288 289 /*! 290 * @brief 送信対象の指定の値を取得します。 291 * @return @ref MessageTypeFlag 292 */ 293 MessageTypeFlag GetMessageTypeFlag() const; 294 295 /*! 296 * @brief 送信モード(受信のみ/送信のみ/送受信/交換)を @ref SendMode で指定します。 297 * @param[in] sendMode @ref SendMode 298 * @return nn::Result 299 * @retval ResultSuccess 成功しました。 300 * @retval ResultInvalidArgument 無効な値が指定されています。 301 302 */ 303 nn::Result SetSendMode(SendMode sendMode); 304 305 /*! 306 * @brief 送信モード(受信のみ/送信のみ/送受信/交換)を取得します。 307 * @return @ref MessageTypeFlag 308 */ 309 SendMode GetSendMode() const; 310 311 312 nn::Result SetSenderID(u64 senderId); 313 u64 GetSenderID() const; 314 315 nn::Result SetSendDate(const nn::fnd::DateTimeParameters& date); 316 /*! 317 * @brief 受信 Message の送信時の時刻を取得します。通信相手の時計の時刻が入ります。 318 * @return @ref nn::fnd::DateTimeParameters 319 */ 320 nn::fnd::DateTimeParameters GetSendDate() const; 321 322 nn::Result SetRecvDate(const nn::fnd::DateTimeParameters& date); 323 /*! 324 * @brief 受信 Message の受信時の時刻を取得します。受信者の時計の時刻が入ります。 325 * @return @ref nn::fnd::DateTimeParameters 326 */ 327 nn::fnd::DateTimeParameters GetRecvDate() const; 328 329 nn::Result SetCreateDate(const nn::fnd::DateTimeParameters& date); 330 /*! 331 * @brief Message の作成時の時刻を取得します。 332 * @return @ref nn::fnd::DateTimeParameters 333 */ 334 nn::fnd::DateTimeParameters GetCreateDate() const; 335 336 /*! 337 * @brief 送信回数を指定します。送信されると 1 減算され、0になると送信されなくなります。 338 339 送信が完了し、送信回数が 0 になった後も、Messageは送信BOXに残ります。 340 341 * @param[in] sendCount 送信回数 342 * @return nn::Result 343 * @retval ResultSuccess 成功しました。 344 */ 345 nn::Result SetSendCount(const u8 sendCount); 346 347 /*! 348 * @brief 送信回数を取得します。送信されると 1 減算され、0になると送信されなくなります。 349 350 送信が完了し、送信回数が 0 になった後も、Messageは送信BOXに残ります。 351 352 * @return 送信回数 353 */ 354 u8 GetSendCount() const; 355 356 /*! 357 * @brief 伝播回数を指定します。受信時に 1 減算され、1以上の場合に送信BOXにコピーされます。 358 359 2 を指定した場合は、<br>[自分] ---(2)----> [Aさん] ---(1)----> [Bさん]<br> 360 のように、2回の送信が行われます。自分が送信したデータが、また自分に戻ってくる可能性もあるので注意してください。 361 362 * @param[in] propagationCount 伝播回数 363 * @return nn::Result 364 * @retval ResultSuccess 成功しました。 365 */ 366 nn::Result SetPropagationCount(u8 propagationCount); 367 368 /*! 369 * @brief 伝播回数を取得します。受信時に 1 減算され、1以上の場合に送信BOXにコピーされます。 370 * @return 伝播回数 371 */ 372 u8 GetPropagationCount() const; 373 374 /*! 375 :private 376 * @brief 未読フラグの値を指定します。 377 * @param[in] flag 未読 = 1 / 既読 = 0 378 <br>変更した値を保存するには、 @ref MessageBox::WriteMessage で 379 上書きする必要があります。 380 * @return nn::Result 381 */ 382 nn::Result SetFlag_Unread(u8 flag); 383 384 /*! 385 :private 386 * @brief 未読フラグの値を取得します。 387 この値は、受信時に 1 に設定される以外は、自動的に変化しません。 388 * @return 未読 = 1 / 既読 = 0 389 */ 390 u8 GetFlag_Unread() const; 391 392 /*! 393 :private 394 * @brief 新着フラグの値を指定します。 395 * @param[in] flag 新着 = 1 396 <br>変更した値を保存するには、 @ref MessageBox::WriteMessage で 397 上書きする必要があります。 398 399 * @return nn::Result 400 */ 401 nn::Result SetFlag_New(const u8 flag); 402 403 /*! 404 :private 405 * @brief 新着フラグの値を取得します。 406 この値は、受信時に 1 に設定される以外は、自動的に変化しません。 407 * @return 新着 = 1 408 */ 409 u8 GetFlag_New() const; 410 411 /*! 412 * @brief Message のヘッダに 16bit の値を入れておくことができます。 413 414 @ref MessageBox::GetMessageTag でも取得することができ、Messageの検索などに使うことができます。 415 416 * @param[in] tag 16 bit の値 417 * @return 418 */ 419 void SetTag(u16 tag); 420 421 /*! 422 * @brief Message のヘッダの Tag の値を取得します。 423 * @return Tag 424 */ 425 u16 GetTag() const; 426 427 /*! 428 * @brief Message の拡張ヘッダにデータをセットします。 429 430 ※ アイコン・説明文以外の アプリ独自のデータを入れることはできません。 431 432 * @param[in] exhType データ種別 @ref MessageExHeaderType で指定します。 433 * @param[in] exhLen データ長を指定します。最大長は 8KB です。 434 * @param[in] exhBody データ 435 * @return nn::Result 436 * @retval ResultSuccess 成功しました。 437 * @retval ResultTooLarge データサイズが大きすぎます。 438 * @retval ResultNotAuthorized 既にMessageIdが割り振られて確定されたメッセージを編集しようとしています。 439 * @retval 上記以外 失敗しました。 440 */ 441 nn::Result SetExHeader(MessageExHeaderType exhType, size_t exhLen, const void* exhBody); 442 443 /*! 444 * @brief Message の拡張ヘッダからデータを取得します。 445 * @param[in] exhType データ種別 @ref MessageExHeaderType で指定します。 446 * @param[out] exhLen データ長を取得します。 447 * @param[out] exhBody データを取得します。 448 * @return nn::Result 449 * @retval ResultSuccess 成功しました。 450 * @retval ResultNoData データがありません。 451 * @retval 上記以外 失敗しました。 452 */ 453 nn::Result GetExHeader(MessageExHeaderType exhType, size_t* exhLen, void** exhBody) const; 454 455 nn::Result SetModuleFilter(const u8* filter, size_t size); 456 457 /*! 458 :private 459 * @brief Message に Module Filter をセットします。 460 * @param[in] filterM Mask の値 461 * @param[in] filterC Condition の値 462 * @param[in] filterR Request の値 463 * @param[in] size サイズ(=Mのサイズ=Cのサイズ=Rのサイズ) 464 * @return nn::Result 465 */ 466 nn::Result SetModuleFilter_MCR(const u8* filterM,const u8* filterC,const u8* filterR, u8 size); 467 u32 GetModuleFilter(void** filter, size_t* size) const; 468 469 /*! 470 * @brief Message に Icon をセットします。 471 472 SetExHeader(MESSAGE_EXHEADER_TYPE_ICON, iconSize, iconData) と同じです。 473 474 * @param[in] iconData データ 475 * @param[in] iconSize データ長を指定します。最大長は 8KB です。 476 * @return nn::Result 477 * @retval ResultSuccess 成功しました。 478 * @retval ResultTooLarge データサイズが大きすぎます。 479 * @retval ResultNotAuthorized 既にMessageIdが割り振られて確定されたメッセージを編集しようとしています。 480 * @retval 上記以外 失敗しました。 481 */ SetIcon(void * iconData,size_t iconSize)482 inline nn::Result SetIcon(void* iconData, size_t iconSize) 483 { 484 return SetExHeader(MESSAGE_EXHEADER_TYPE_ICON, iconSize, iconData); 485 } 486 487 /*! 488 * @brief Message の Icon を取得します。 489 490 GetExHeader(MESSAGE_EXHEADER_TYPE_ICON, iconSize, iconData) と同じです。 491 492 * @param[out] iconData データ 493 * @param[out] iconSize データ長 494 * @return nn::Result 495 * @retval ResultSuccess 成功しました。 496 * @retval ResultNoData データがありません。 497 * @retval 上記以外 失敗しました。 498 */ GetIcon(void ** iconData,size_t * iconSize)499 inline nn::Result GetIcon(void** iconData, size_t* iconSize) const 500 { 501 return GetExHeader(MESSAGE_EXHEADER_TYPE_ICON, iconSize, iconData); 502 } 503 504 /*! 505 * @brief Message の説明文をセットします。 506 507 SetExHeader(MESSAGE_EXHEADER_TYPE_INFO, infoTextSize, infoTextData) と同じです。 508 509 * @param[in] infoTextData データ 510 * @param[in] infoTextSize データ長を指定します。最大長は 8KB です。 511 * @return nn::Result 512 * @retval ResultSuccess 成功しました。 513 * @retval ResultTooLarge データサイズが大きすぎます。 514 * @retval ResultNotAuthorized 既にMessageIdが割り振られて確定されたメッセージを編集しようとしています。 515 * @retval 上記以外 失敗しました。 516 */ SetInfoText(wchar_t * infoTextData,size_t infoTextSize)517 inline nn::Result SetInfoText(wchar_t* infoTextData, size_t infoTextSize) 518 { 519 return SetExHeader(MESSAGE_EXHEADER_TYPE_INFO , infoTextSize, infoTextData); 520 } 521 522 /*! 523 * @brief Message の説明文を取得します。 524 525 GetExHeader(MESSAGE_EXHEADER_TYPE_INFO, infoTextSize, infoTextData) と同じです。 526 527 * @param[out] infoTextData データ 528 * @param[out] infoTextSize データ長 529 * @return nn::Result 530 * @retval ResultSuccess 成功しました。 531 * @retval ResultNoData データがありません。 532 * @retval 上記以外 失敗しました。 533 */ GetInfoText(wchar_t ** infoTextData,size_t * infoTextSize)534 inline nn::Result GetInfoText(wchar_t** infoTextData, size_t* infoTextSize) const 535 { 536 return GetExHeader(MESSAGE_EXHEADER_TYPE_INFO , infoTextSize, reinterpret_cast<void**>(infoTextData)); 537 } 538 /*! 539 * @brief Message に データ本文 をセットします。 540 * @param[in] dataBody データ 541 * @param[in] size サイズを指定します。最大長は 96KB (ヘッダ/拡張ヘッダを含めて 100KB)です。 542 * @return nn::Result 543 * @retval ResultSuccess 成功しました。 544 * @retval ResultInvalidArgument データが無効です。 545 * @retval ResultTooLarge データサイズが大きすぎます。 546 * @retval ResultNotAuthorized 既にMessageIdが割り振られて確定されたメッセージを編集しようとしています。 547 * @retval 上記以外 失敗しました。 548 */ 549 nn::Result SetMessageBody(const void* dataBody, size_t size); 550 551 /*! 552 * @brief Message の データ本文を 取得します。 553 * @param[out] dataBody データを格納するバッファを指定 554 * @param[in] size バッファサイズを指定 555 * @return データ本文のサイズ 556 */ 557 u32 GetMessageBody(void* dataBody, size_t size) const; 558 559 /*! 560 * @brief Message の データ本文のポインタを 取得します。 561 * @param[out] pBody データ本文のポインタ 562 * @param[out] size データ本文のサイズが格納されます 563 * @return データ本文のポインタ 564 */ 565 void* GetMessageBodyPointer(void** pBody,size_t* size); 566 567 nn::Result SetMessageBodyPointer(void* p_dataBody, size_t size); 568 569 /* 570 void OpenMessage(); 571 void OpenMessage(u8* messId); 572 */ 573 //@} 574 575 void SetHmacKey(char* hmacKey); 576 577 /*! 578 :private 579 @brief バイナリデータ列を このクラスで扱うことができるようにします。 580 581 主に内部処理用です。通常はこのAPIを使用する必要はありません。 582 583 * @param[in] mess データバイナリ列 584 * @param[out] size データバイナリ列のサイズ 585 @return 586 */ 587 nn::Result InputMessage(const void* mess, size_t size); 588 589 nn::Result InputMessage(const void* mess); 590 591 nn::Result InputMessageHeaderWithEx(const void* mess, size_t size); 592 593 nn::Result InputMessageHeader(const void* mess, size_t size); 594 /*! 595 :private 596 @brief Message データを バイナリデータ列として出力します。 597 ネットワーク/ファイルへの出力を想定しています。 598 599 主に内部処理用です。通常はこのAPIを使用する必要はありません。 600 601 * @param[out] messData データバイナリ列 602 @return 603 */ 604 u32 OutputMessage(void* messData); 605 606 u32 MakeMessageBinary(void* messData) const; 607 void OutputMessageHeader(void* pHeaderBuf) const; 608 609 u32 CheckMessageSize(const void* mess); 610 611 void DumpMessage(); 612 NN_PADDING4; 613 }; 614 615 616 617 } // namespace CTR 618 } // namespace cec 619 } // namespace nn 620 621 622 623 624 625 626 #endif //NN_CEC_CTR_CEC_MESSAGE_H_ 627 628