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