/*---------------------------------------------------------------------------* Project: RevolutionDWC Demos File: ./cfriend/src/main.c Copyright 2005-2008 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. *---------------------------------------------------------------------------*/ /** * * * Brief comment: Demo of the Wii Friend Link feature * * 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. * * Before running this demo, you must run a demo like frienddata to create a Game Friend Code. * * Overview of demo operations * Send a WiiConnect24 message with the Game Friend Code embedded to yourself. * (In practice, you should send the Game Friend Code to the desired recipient.) * Due to the specifications of WiiConnect24, messages addressed to yourself are immediately stored in the inbox. * Search the inbox for messages that contain Game Friend Codes, and display the Wii Number and the Game Friend Code of the sender. * * */ #include "../../common/include/common.h" #include #define MSGOBJ_ARRAY_SIZE 8 /// Structure that contains the player information static struct tagPlayerInfo { /// User data DWCUserData userdata; /// Friend data DWCFriendData friendlist[FRIEND_LIST_LEN]; } s_playerinfo ATTRIBUTE_ALIGN(32); static char s_nwc24WorkMem[NWC24_WORK_MEM_SIZE] ATTRIBUTE_ALIGN(32); static char* TestSubject = "Test Message"; static char* TestMsgText = "Hello WiiConnect24 World!!\x0d\x0a" "This is a test mail.\x0d\x0a" "Thank you.\x0d\x0a"; static BOOL LoadFromNAND ( void ); static BOOL SearchFriendMsgs ( void ); static BOOL PostFriendMsg ( void ); static void ViewMessage ( NWC24MsgObj* msgObj ); static void PrintFrom ( NWC24MsgObj* msgObj ); static void PrintTo ( NWC24MsgObj* msgObj ); static void PrintSubject ( NWC24MsgObj* msgObj ); static void PrintMsgType ( NWC24MsgObj* msgObj ); static void PrintAppId ( NWC24MsgObj* msgObj ); /** * Load data from NAND * * Loads the user data and the friend roster from NAND. * * Return value: TRUE: There is user data in NAND flash memory. * Return value: FALSE: There is no user data in NAND flash memory. */ BOOL LoadFromNAND( void ) { // Load from NAND // DWCDemoPrintf("Loading from NAND...\n"); DWCDemoLoadNAND( "playerinfo", 0, (u8*)&s_playerinfo, sizeof( s_playerinfo ) ); // Check if user data is valid // if ( DWC_CheckUserData( &s_playerinfo.userdata ) ) { // It was valid, so output the user data and return TRUE DWC_ReportUserData( &s_playerinfo.userdata ); return TRUE; } // If valid user data had not been saved // // This demo cannot do anything if there is are no friends // DWCDemoPrintf( "No valid userdata found.\n" ); return FALSE; } /** * Search for messages with Game Friend Code embedded * * Search the inbox for messages with an embedded Game Friend Code * Delete the messages after displaying the details. * * Return value: TRUE: The search completed * Return value: FALSE: An error occurred */ BOOL SearchFriendMsgs( void ) { NWC24Err err; u32 iObj; u32 numStored; u32 numRemain; u64 appFriendKey; u32 msgId; DWCCfMsgType msgType; NWC24MsgObj msgObjArray[MSGOBJ_ARRAY_SIZE]; // Set the search conditions NWC24InitSearchConds(); NWC24SetSearchCondMsgBox(NWC24_RECV_BOX); do { /* Search messages */ err = NWC24SearchMsgs( msgObjArray, MSGOBJ_ARRAY_SIZE, &numStored, &numRemain ); if ( err != NWC24_OK ) { DWCDemoPrintf( "NWC24SearchMsgs(): Error %d\n", err ); return FALSE; } DWCDemoPrintf("[NWC24SearchMsgs(): Stored: %d Remain: %d]\n", numStored, numRemain); /* Display messages */ for ( iObj = 0 ; iObj < numStored ; ++iObj ) { if ( DWC_CfGetAppFriendKeyFromNWC24Msg( &msgObjArray[iObj], &s_playerinfo.userdata, &appFriendKey, &msgType ) == DWC_CF_ERROR_NONE) { ViewMessage( &msgObjArray[iObj] ); DWCDemoPrintf("Received a friend key message. appFriendKey: %012llu msgType: %d.\n", appFriendKey, msgType); err = NWC24GetMsgId( &msgObjArray[iObj], &msgId ); if ( err != NWC24_OK) { DWCDemoPrintf( "NWC24GetMsgId(): Error %d\n", err ); return FALSE; } err = NWC24DeleteMsg( NWC24_RECV_BOX, msgId ); if ( err != NWC24_OK) { DWCDemoPrintf( "NWC24DeleteMsg(): Error %d\n", err ); return FALSE; } } } } while ( numRemain > 0 ); /* Repeat until all messages satisfying the search conditions have been gotten */ DWCDemoPrintf("Completed searching messages.\n"); return TRUE; } /** * Send a message that with the Game Friend Code embedded * * Return value: TRUE: Completed transmission * Return value: FALSE: An error occurred */ BOOL PostFriendMsg( void ) { NWC24Err err; NWC24MsgObj msgObj; NWC24UserId userid; // Initializes the object, specifies Wii-to-Wii message. err = NWC24InitMsgObj(&msgObj, NWC24_MSGTYPE_WII); if ( err != NWC24_OK ) { DWCDemoPrintf("NWC24InitMsgObj(): error %d\n", err); return FALSE; } // Gets your own Wii number NWC24GetMyUserId(&userid); // Specify the recipient err = NWC24SetMsgToId(&msgObj, userid); if ( err != NWC24_OK ) { DWCDemoPrintf("NWC24SetMsgToId(): error %d\n", err); return FALSE; } // Subject err = NWC24SetMsgSubject(&msgObj, TestSubject, (u32)strlen(TestSubject)); if ( err != NWC24_OK ) { DWCDemoPrintf("NWC24SetMsgSubject(): error %d\n", err); return FALSE; } // Message body (text) err = NWC24SetMsgText(&msgObj, TestMsgText, (u32)strlen(TestMsgText), NWC24_US_ASCII, NWC24_ENC_7BIT); if ( err != NWC24_OK ) { DWCDemoPrintf("NWC24SetMsgText(): error %d\n", err); return FALSE; } // Embed the Game Friend Code in the message if (DWC_CfSetAppFriendKeyToNWC24Msg(&msgObj, &s_playerinfo.userdata, DWC_CF_MSG_TYPE_REQUEST) != DWC_CF_ERROR_NONE) { DWCDemoPrintf("DWC_CfSetAppFriendKeyToNWC24Msg(): error %d\n", err); return FALSE; } // Commit settings and post the message into the send box. err = NWC24CommitMsg(&msgObj); if ( err != NWC24_OK ) { DWCDemoPrintf("NWC24CommitMsg: error %d\n", err); return FALSE; } DWCDemoPrintf("Posted a test message successfully.\n"); return TRUE; } //============================================================================= /*! * @brief Main */ //============================================================================= void DWCDemoMain() { NWC24Err err; s32 result; /* NWC24 must be initialized */ result = NANDInit(); if ( result != NAND_RESULT_OK ) { DWCDemoPrintf("NANDInit() failed.\n"); return; } VFInit(); if (!LoadFromNAND()) { DWCDemoPrintf("LoadFromNAND() failed.\n"); return; } err = NWC24OpenLib(s_nwc24WorkMem); if ( err != NWC24_OK ) { DWCDemoPrintf("NWC24OpenLib(): Error %d\n", err); return; } // Send the message if (!PostFriendMsg()) { DWCDemoPrintf("PostFriendMsg() failed.\n"); } // Clear the receive buffer. if (DWC_CfReset() != DWC_CF_ERROR_NONE) { DWCDemoPrintf("DWC_CfReset() failed.\n"); } // Receive the message if (!SearchFriendMsgs()) { DWCDemoPrintf("SearchFriendMsgs() failed.\n"); } err = NWC24CloseLib(); if ( err != NWC24_OK ) { DWCDemoPrintf("NWC24CloseLib(): Error %d\n", err); return; } return; } /*---------------------------------------------------------------------------* Views message data. *---------------------------------------------------------------------------*/ static void ViewMessage( NWC24MsgObj* msgObj ) { DWCDemoPrintf( "\n[From] " ); PrintFrom( msgObj ); DWCDemoPrintf( "\n[To] " ); PrintTo( msgObj ); DWCDemoPrintf( "\n[Subject] " ); PrintSubject( msgObj ); DWCDemoPrintf( "\n[Msg type] " ); PrintMsgType( msgObj ); DWCDemoPrintf( "\n[App ID] " ); PrintAppId( msgObj ); DWCDemoPrintf( "\n-------------------------------------------\n" ); return; } /*---------------------------------------------------------------------------*/ static void PrintFrom( NWC24MsgObj* msgObj ) { NWC24Err err; NWC24MsgType msgType; err = NWC24GetMsgType( msgObj, &msgType ); if ( err != NWC24_OK ) { DWCDemoPrintf( "NWC24GetMsgType(): Error %d\n", err ); return; } if ( msgType != NWC24_MSGTYPE_PUBLIC ) { NWC24UserId uid; err = NWC24GetMsgFromId( msgObj, &uid ); if ( err != NWC24_OK ) { DWCDemoPrintf( "NWC24GetMsgFromId(): Error %d\n", err ); return; } DWCDemoPrintf( "%016llu", uid ); } else { char strAddr[NWC24MSG_MAX_ADDRSTR]; err = NWC24ReadMsgFromAddr( msgObj, strAddr, NWC24MSG_MAX_ADDRSTR ); if ( err != NWC24_OK ) { DWCDemoPrintf( "NWC24ReadMsgFromAddr(): Error %d\n", err ); return; } DWCDemoPrintf( "%s", strAddr ); } return; } /*---------------------------------------------------------------------------*/ static void PrintTo( NWC24MsgObj* msgObj ) { NWC24Err err; NWC24MsgType msgType; u32 numTo; u32 iTo; err = NWC24GetMsgType( msgObj, &msgType ); if ( err != NWC24_OK ) { DWCDemoPrintf( "NWC24GetMsgType(): Error %d\n", err ); return; } err = NWC24GetMsgNumTo( msgObj, &numTo ); if ( err != NWC24_OK ) { DWCDemoPrintf( "NWC24GetMsgNumTo(): Error %d\n", err ); return; } if ( msgType != NWC24_MSGTYPE_PUBLIC ) { NWC24UserId uid; for ( iTo = 0; iTo < numTo; ++iTo ) { err = NWC24ReadMsgToId( msgObj, iTo, &uid ); if ( err != NWC24_OK ) { DWCDemoPrintf( "NWC24ReadMsgToId(): Error %d\n", err ); return; } DWCDemoPrintf( "%016llu", uid ); if ( iTo < numTo - 1 ) { DWCDemoPrintf( ", " ); } } } else { char strAddr[NWC24MSG_MAX_ADDRSTR]; for ( iTo = 0; iTo < numTo; ++iTo ) { err = NWC24ReadMsgToAddr( msgObj, iTo, strAddr, NWC24MSG_MAX_ADDRSTR ); if ( err != NWC24_OK ) { DWCDemoPrintf( "NWC24ReadMsgToAddr(): Error %d\n", err ); return; } DWCDemoPrintf( "%s", strAddr ); if ( iTo < numTo - 1 ) { DWCDemoPrintf( ", " ); } } } return; } /*---------------------------------------------------------------------------*/ static void PrintSubject( NWC24MsgObj* msgObj ) { NWC24Err err; u32 iBuf; u32 bufSize; char* buffer = NULL; err = NWC24GetMsgSubjectSize( msgObj, &bufSize ); if ( err != NWC24_OK ) { DWCDemoPrintf( "NWC24GetMsgSubjectSize(): Error %d\n", err ); return; } buffer = (char*)DWC_Alloc( (DWCAllocType)0, OSRoundUp32B(bufSize) ); err = NWC24ReadMsgSubject( msgObj, buffer, bufSize ); if ( err != NWC24_OK ) { DWCDemoPrintf( "NWC24ReadMsgSubject(): Error %d\n", err ); DWC_Free( (DWCAllocType)0, buffer, 0 ); return; } for ( iBuf = 0; iBuf < bufSize; ++iBuf ) { if ( buffer[iBuf] != '\r' && buffer[iBuf] != '\n' ) { DWCDemoPrintf( "%c", buffer[iBuf] ); } } DWC_Free( (DWCAllocType)0, buffer, 0 ); return; } /*---------------------------------------------------------------------------*/ static void PrintMsgType( NWC24MsgObj* msgObj ) { NWC24Err err; NWC24MsgType msgType; char* strMsgType; err = NWC24GetMsgType( msgObj, &msgType ); if ( err != NWC24_OK ) { DWCDemoPrintf( "NWC24GetMsgType(): Error %d\n", err ); return; } switch ( msgType ) { case NWC24_MSGTYPE_WII_MENU_SHARED: strMsgType = "Wii menu shared"; break; case NWC24_MSGTYPE_WII_APP: strMsgType = "Wii app"; break; case NWC24_MSGTYPE_WII_MENU: strMsgType = "Wii menu"; break; case NWC24_MSGTYPE_WII_APP_HIDDEN: strMsgType = "Wii app hidden"; break; case NWC24_MSGTYPE_PUBLIC: strMsgType = "Public"; break; default: strMsgType = "Unknown"; } DWCDemoPrintf( "%s", strMsgType ); return; } /*---------------------------------------------------------------------------*/ static void PrintAppId( NWC24MsgObj* msgObj ) { NWC24Err err; u32 appId; err = NWC24GetMsgAppId( msgObj, &appId ); if ( err != NWC24_OK ) { DWCDemoPrintf( "NWC24GetMsgAppId(): Error %d\n", err ); return; } DWCDemoPrintf( "0x%08x", appId ); return; }