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