1 /*---------------------------------------------------------------------------*
2   Project:  RevolutionDWC Demos
3   File:     ./cfriend/src/main.c
4 
5   Copyright 2005-2008 Nintendo. 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  *---------------------------------------------------------------------------*/
14 /**
15  *
16  *
17  * Brief comment:    Demo of the Wii Friend Link feature
18  *
19  * This is a demo that uses a WiiConnect24 message to announce one's Game Friend Code to a recipient with whom a Wii Friend relationship has been formed.
20  *
21  * Before running this demo, you must run a demo like frienddata to create a Game Friend Code.
22  *
23  * Overview of demo operations
24  * Send a WiiConnect24 message with the Game Friend Code embedded to yourself.
25  * (In practice, you should send the Game Friend Code to the desired recipient.)
26  * Due to the specifications of WiiConnect24, messages addressed to yourself are immediately stored in the inbox.
27  * Search the inbox for messages that contain Game Friend Codes, and display the Wii Number and the Game Friend Code of the sender.
28  *
29  *
30  */
31 #include "../../common/include/common.h"
32 #include <revolution/vf.h>
33 
34 #define MSGOBJ_ARRAY_SIZE   8
35 
36 /// Structure that contains the player information
37 static struct tagPlayerInfo
38 {
39     /// User data
40     DWCUserData     userdata;
41 
42     /// Friend data
43     DWCFriendData   friendlist[FRIEND_LIST_LEN];
44 
45 }
46 s_playerinfo ATTRIBUTE_ALIGN(32);
47 
48 static char s_nwc24WorkMem[NWC24_WORK_MEM_SIZE] ATTRIBUTE_ALIGN(32);
49 static char* TestSubject = "Test Message";
50 static char* TestMsgText =
51     "Hello WiiConnect24 World!!\x0d\x0a"
52     "This is a test mail.\x0d\x0a"
53     "Thank you.\x0d\x0a";
54 
55 static BOOL LoadFromNAND        ( void );
56 static BOOL SearchFriendMsgs    ( void );
57 static BOOL PostFriendMsg       ( void );
58 static void ViewMessage         ( NWC24MsgObj* msgObj );
59 static void PrintFrom           ( NWC24MsgObj* msgObj );
60 static void PrintTo             ( NWC24MsgObj* msgObj );
61 static void PrintSubject        ( NWC24MsgObj* msgObj );
62 static void PrintMsgType        ( NWC24MsgObj* msgObj );
63 static void PrintAppId          ( NWC24MsgObj* msgObj );
64 
65 
66 /**
67  * Load data from NAND
68  *
69  * Loads the user data and the friend roster from NAND.
70  *
71  * Return value:   TRUE:   There is user data in NAND flash memory.
72  * Return value:   FALSE:  There is no user data in NAND flash memory.
73  */
LoadFromNAND(void)74 BOOL LoadFromNAND( void )
75 {
76 
77     // Load from NAND
78     //
79     DWCDemoPrintf("Loading from NAND...\n");
80 
81     DWCDemoLoadNAND(    "playerinfo",
82                         0,
83                         (u8*)&s_playerinfo,
84                         sizeof( s_playerinfo ) );
85 
86     // Check if user data is valid
87     //
88     if ( DWC_CheckUserData( &s_playerinfo.userdata ) )
89     {
90 
91         // It was valid, so output the user data and return TRUE
92         DWC_ReportUserData( &s_playerinfo.userdata );
93         return TRUE;
94 
95     }
96 
97     // If valid user data had not been saved
98     //
99     // This demo cannot do anything if there is are no friends
100     //
101     DWCDemoPrintf( "No valid userdata found.\n" );
102 
103     return FALSE;
104 }
105 
106 /**
107  * Search for messages with Game Friend Code embedded
108  *
109  * Search the inbox for messages with an embedded Game Friend Code
110  * Delete the messages after displaying the details.
111  *
112  * Return value:   TRUE:    The search completed
113  * Return value:   FALSE:   An error occurred
114  */
SearchFriendMsgs(void)115 BOOL SearchFriendMsgs( void )
116 {
117     NWC24Err    err;
118     u32         iObj;
119     u32         numStored;
120     u32         numRemain;
121     u64         appFriendKey;
122     u32         msgId;
123     DWCCfMsgType msgType;
124     NWC24MsgObj msgObjArray[MSGOBJ_ARRAY_SIZE];
125 
126     // Set the search conditions
127     NWC24InitSearchConds();
128     NWC24SetSearchCondMsgBox(NWC24_RECV_BOX);
129 
130     do
131     {
132         /* Search messages */
133         err = NWC24SearchMsgs( msgObjArray, MSGOBJ_ARRAY_SIZE, &numStored, &numRemain );
134         if ( err != NWC24_OK )
135         {
136             DWCDemoPrintf( "NWC24SearchMsgs(): Error %d\n", err );
137             return FALSE;
138         }
139 
140         DWCDemoPrintf("[NWC24SearchMsgs(): Stored: %d Remain: %d]\n", numStored, numRemain);
141 
142         /* Display messages */
143         for ( iObj = 0 ; iObj < numStored ; ++iObj )
144         {
145             if ( DWC_CfGetAppFriendKeyFromNWC24Msg( &msgObjArray[iObj], &s_playerinfo.userdata, &appFriendKey, &msgType )
146                     == DWC_CF_ERROR_NONE)
147             {
148                 ViewMessage( &msgObjArray[iObj] );
149                 DWCDemoPrintf("Received a friend key message. appFriendKey: %012llu msgType: %d.\n", appFriendKey, msgType);
150 
151                 err = NWC24GetMsgId( &msgObjArray[iObj], &msgId );
152                 if ( err != NWC24_OK)
153                 {
154                     DWCDemoPrintf( "NWC24GetMsgId(): Error %d\n", err );
155                     return FALSE;
156                 }
157                 err = NWC24DeleteMsg( NWC24_RECV_BOX, msgId );
158                 if ( err != NWC24_OK)
159                 {
160                     DWCDemoPrintf( "NWC24DeleteMsg(): Error %d\n", err );
161                     return FALSE;
162                 }
163             }
164         }
165     }
166     while ( numRemain > 0 );
167     /* Repeat until all messages satisfying the search conditions have been gotten */
168 
169     DWCDemoPrintf("Completed searching messages.\n");
170     return TRUE;
171 }
172 
173 /**
174  * Send a message that with the Game Friend Code embedded
175  *
176  * Return value:   TRUE:    Completed transmission
177  * Return value:   FALSE:   An error occurred
178  */
PostFriendMsg(void)179 BOOL PostFriendMsg( void )
180 {
181     NWC24Err        err;
182     NWC24MsgObj     msgObj;
183     NWC24UserId     userid;
184 
185     // Initializes the object, specifies Wii-to-Wii message.
186     err = NWC24InitMsgObj(&msgObj, NWC24_MSGTYPE_WII);
187     if ( err != NWC24_OK )
188     {
189         DWCDemoPrintf("NWC24InitMsgObj(): error %d\n", err);
190         return FALSE;
191     }
192 
193     // Gets your own Wii number
194     NWC24GetMyUserId(&userid);
195 
196     // Specify the recipient
197     err = NWC24SetMsgToId(&msgObj, userid);
198     if ( err != NWC24_OK )
199     {
200         DWCDemoPrintf("NWC24SetMsgToId(): error %d\n", err);
201         return FALSE;
202     }
203 
204     // Subject
205     err = NWC24SetMsgSubject(&msgObj, TestSubject, (u32)strlen(TestSubject));
206     if ( err != NWC24_OK )
207     {
208         DWCDemoPrintf("NWC24SetMsgSubject(): error %d\n", err);
209         return FALSE;
210     }
211 
212     // Message body (text)
213     err = NWC24SetMsgText(&msgObj, TestMsgText, (u32)strlen(TestMsgText),
214                           NWC24_US_ASCII, NWC24_ENC_7BIT);
215     if ( err != NWC24_OK )
216     {
217         DWCDemoPrintf("NWC24SetMsgText(): error %d\n", err);
218         return FALSE;
219     }
220 
221     // Embed the Game Friend Code in the message
222     if (DWC_CfSetAppFriendKeyToNWC24Msg(&msgObj, &s_playerinfo.userdata, DWC_CF_MSG_TYPE_REQUEST) != DWC_CF_ERROR_NONE)
223     {
224         DWCDemoPrintf("DWC_CfSetAppFriendKeyToNWC24Msg(): error %d\n", err);
225         return FALSE;
226     }
227 
228     // Commit settings and post the message into the send box.
229     err = NWC24CommitMsg(&msgObj);
230     if ( err != NWC24_OK )
231     {
232         DWCDemoPrintf("NWC24CommitMsg: error %d\n", err);
233         return FALSE;
234     }
235 
236     DWCDemoPrintf("Posted a test message successfully.\n");
237 
238     return TRUE;
239 }
240 
241 //=============================================================================
242 /*!
243  *	@brief	Main
244  */
245 //=============================================================================
DWCDemoMain()246 void DWCDemoMain()
247 {
248     NWC24Err    err;
249     s32         result;
250 
251     /* NWC24 must be initialized */
252     result = NANDInit();
253     if ( result != NAND_RESULT_OK )
254     {
255         DWCDemoPrintf("NANDInit() failed.\n");
256         return;
257     }
258 
259     VFInit();
260 
261     if (!LoadFromNAND())
262     {
263         DWCDemoPrintf("LoadFromNAND() failed.\n");
264         return;
265     }
266 
267     err = NWC24OpenLib(s_nwc24WorkMem);
268     if ( err != NWC24_OK )
269     {
270         DWCDemoPrintf("NWC24OpenLib(): Error %d\n", err);
271         return;
272     }
273 
274 
275     // Send the message
276     if (!PostFriendMsg())
277     {
278         DWCDemoPrintf("PostFriendMsg() failed.\n");
279     }
280 
281     // Clear the receive buffer.
282     if (DWC_CfReset() != DWC_CF_ERROR_NONE)
283     {
284         DWCDemoPrintf("DWC_CfReset() failed.\n");
285     }
286 
287     // Receive the message
288     if (!SearchFriendMsgs())
289     {
290         DWCDemoPrintf("SearchFriendMsgs() failed.\n");
291     }
292 
293     err = NWC24CloseLib();
294     if ( err != NWC24_OK )
295     {
296         DWCDemoPrintf("NWC24CloseLib(): Error %d\n", err);
297         return;
298     }
299 
300     return;
301 }
302 
303 
304 /*---------------------------------------------------------------------------*
305    Views message data.
306  *---------------------------------------------------------------------------*/
ViewMessage(NWC24MsgObj * msgObj)307 static void ViewMessage( NWC24MsgObj* msgObj )
308 {
309     DWCDemoPrintf( "\n[From]     " );
310     PrintFrom( msgObj );
311 
312     DWCDemoPrintf( "\n[To]       " );
313     PrintTo( msgObj );
314 
315     DWCDemoPrintf( "\n[Subject]  " );
316     PrintSubject( msgObj );
317 
318     DWCDemoPrintf( "\n[Msg type] " );
319     PrintMsgType( msgObj );
320 
321     DWCDemoPrintf( "\n[App ID]   " );
322     PrintAppId( msgObj );
323 
324     DWCDemoPrintf( "\n-------------------------------------------\n" );
325     return;
326 }
327 
328 /*---------------------------------------------------------------------------*/
PrintFrom(NWC24MsgObj * msgObj)329 static void PrintFrom( NWC24MsgObj* msgObj )
330 {
331     NWC24Err        err;
332     NWC24MsgType    msgType;
333 
334     err = NWC24GetMsgType( msgObj, &msgType );
335     if ( err != NWC24_OK )
336     {
337         DWCDemoPrintf( "NWC24GetMsgType(): Error %d\n", err );
338         return;
339     }
340 
341     if ( msgType != NWC24_MSGTYPE_PUBLIC )
342     {
343         NWC24UserId     uid;
344 
345         err = NWC24GetMsgFromId( msgObj, &uid );
346         if ( err != NWC24_OK )
347         {
348             DWCDemoPrintf( "NWC24GetMsgFromId(): Error %d\n", err );
349             return;
350         }
351         DWCDemoPrintf( "%016llu", uid );
352     }
353     else
354     {
355         char    strAddr[NWC24MSG_MAX_ADDRSTR];
356 
357         err = NWC24ReadMsgFromAddr( msgObj, strAddr, NWC24MSG_MAX_ADDRSTR );
358         if ( err != NWC24_OK )
359         {
360             DWCDemoPrintf( "NWC24ReadMsgFromAddr(): Error %d\n", err );
361             return;
362         }
363         DWCDemoPrintf( "%s", strAddr );
364     }
365     return;
366 }
367 
368 /*---------------------------------------------------------------------------*/
PrintTo(NWC24MsgObj * msgObj)369 static void PrintTo( NWC24MsgObj* msgObj )
370 {
371     NWC24Err        err;
372     NWC24MsgType    msgType;
373     u32             numTo;
374     u32             iTo;
375 
376     err = NWC24GetMsgType( msgObj, &msgType );
377     if ( err != NWC24_OK )
378     {
379         DWCDemoPrintf( "NWC24GetMsgType(): Error %d\n", err );
380         return;
381     }
382 
383     err = NWC24GetMsgNumTo( msgObj, &numTo );
384     if ( err != NWC24_OK )
385     {
386         DWCDemoPrintf( "NWC24GetMsgNumTo(): Error %d\n", err );
387         return;
388     }
389 
390     if ( msgType != NWC24_MSGTYPE_PUBLIC )
391     {
392         NWC24UserId     uid;
393 
394         for ( iTo = 0; iTo < numTo; ++iTo )
395         {
396             err = NWC24ReadMsgToId( msgObj, iTo, &uid );
397             if ( err != NWC24_OK )
398             {
399                 DWCDemoPrintf( "NWC24ReadMsgToId(): Error %d\n", err );
400                 return;
401             }
402 
403             DWCDemoPrintf( "%016llu", uid );
404             if ( iTo < numTo - 1 )
405             {
406                 DWCDemoPrintf( ", " );
407             }
408         }
409     }
410     else
411     {
412         char    strAddr[NWC24MSG_MAX_ADDRSTR];
413 
414         for ( iTo = 0; iTo < numTo; ++iTo )
415         {
416             err = NWC24ReadMsgToAddr( msgObj, iTo, strAddr, NWC24MSG_MAX_ADDRSTR );
417             if ( err != NWC24_OK )
418             {
419                 DWCDemoPrintf( "NWC24ReadMsgToAddr(): Error %d\n", err );
420                 return;
421             }
422 
423             DWCDemoPrintf( "%s", strAddr );
424             if ( iTo < numTo - 1 )
425             {
426                 DWCDemoPrintf( ", " );
427             }
428         }
429     }
430     return;
431 }
432 
433 /*---------------------------------------------------------------------------*/
PrintSubject(NWC24MsgObj * msgObj)434 static void PrintSubject( NWC24MsgObj* msgObj )
435 {
436     NWC24Err    err;
437     u32         iBuf;
438     u32         bufSize;
439     char*       buffer  = NULL;
440 
441     err = NWC24GetMsgSubjectSize( msgObj, &bufSize );
442     if ( err != NWC24_OK )
443     {
444         DWCDemoPrintf( "NWC24GetMsgSubjectSize(): Error %d\n", err );
445         return;
446     }
447 
448     buffer = (char*)DWC_Alloc( (DWCAllocType)0, OSRoundUp32B(bufSize) );
449     err = NWC24ReadMsgSubject( msgObj, buffer, bufSize );
450     if ( err != NWC24_OK )
451     {
452         DWCDemoPrintf( "NWC24ReadMsgSubject(): Error %d\n", err );
453         DWC_Free( (DWCAllocType)0, buffer, 0 );
454         return;
455     }
456 
457     for ( iBuf = 0; iBuf < bufSize; ++iBuf )
458     {
459         if ( buffer[iBuf] != '\r' && buffer[iBuf] != '\n' )
460         {
461             DWCDemoPrintf( "%c", buffer[iBuf] );
462         }
463     }
464 
465     DWC_Free( (DWCAllocType)0, buffer, 0 );
466 
467     return;
468 }
469 
470 /*---------------------------------------------------------------------------*/
PrintMsgType(NWC24MsgObj * msgObj)471 static void PrintMsgType( NWC24MsgObj* msgObj )
472 {
473     NWC24Err        err;
474     NWC24MsgType    msgType;
475     char*           strMsgType;
476 
477     err = NWC24GetMsgType( msgObj, &msgType );
478     if ( err != NWC24_OK )
479     {
480         DWCDemoPrintf( "NWC24GetMsgType(): Error %d\n", err );
481         return;
482     }
483 
484     switch ( msgType )
485     {
486     case NWC24_MSGTYPE_WII_MENU_SHARED:
487         strMsgType = "Wii menu shared";
488         break;
489     case NWC24_MSGTYPE_WII_APP:
490         strMsgType = "Wii app";
491         break;
492     case NWC24_MSGTYPE_WII_MENU:
493         strMsgType = "Wii menu";
494         break;
495     case NWC24_MSGTYPE_WII_APP_HIDDEN:
496         strMsgType = "Wii app hidden";
497         break;
498     case NWC24_MSGTYPE_PUBLIC:
499         strMsgType = "Public";
500         break;
501     default:
502         strMsgType = "Unknown";
503     }
504 
505     DWCDemoPrintf( "%s", strMsgType );
506     return;
507 }
508 
509 /*---------------------------------------------------------------------------*/
PrintAppId(NWC24MsgObj * msgObj)510 static void PrintAppId( NWC24MsgObj* msgObj )
511 {
512     NWC24Err        err;
513     u32             appId;
514 
515     err = NWC24GetMsgAppId( msgObj, &appId );
516     if ( err != NWC24_OK )
517     {
518         DWCDemoPrintf( "NWC24GetMsgAppId(): Error %d\n", err );
519         return;
520     }
521 
522     DWCDemoPrintf( "0x%08x", appId );
523     return;
524 }
525