/*---------------------------------------------------------------------------* Project: RevoEX - demos - share File: init.c Copyright 2006 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. *---------------------------------------------------------------------------*/ #include #include #include #include #include #include #include "rexdemo/netconfig.h" #include "rexdemo/graphic.h" /*---------------------------------------------------------------------------* Variable Definitions *---------------------------------------------------------------------------*/ static u8 NetConfigId = 0; static char PeerName[256]; /*---------------------------------------------------------------------------* Internal function prototype declarations *---------------------------------------------------------------------------*/ BOOL REXDEMOStartNetwork(BOOL override) { s32 result = 0; /* Overwrite the network setting stored in NAND? */ if (override) { /* Overwrite the network setting based on argument analysis result (for debug) */ result = REXDEMOOverrideNetConfigAuto(); if (result < NCD_RESULT_SUCCESS) { REXDEMOError("REXDEMOOverrideNetConfigAuto() failed.(%d)", result); return FALSE; } } /* Create the heap to be given to the socket library */ if (!REXDEMOCreateHeapForSocket( REXDEMO_SOCKET_HEAPSIZE_DEFAULT )) { REXDEMOError("REXDEMOCreateHeapForSocket() failed."); return FALSE; } /* Initialize the socket library by specifying the allocator in REXDEMO */ result = SOInit( REXDEMOGetSOLibConfig() ); if (result == SO_EALREADY) { REXDEMOError("SOInit() already done. (%d)", result); } else if (result < SO_SUCCESS) { REXDEMOError("SOInit() failed.(%d)", result); return FALSE; } /* Start the network feature of the socket library */ result = SOStartup(); if (result == SO_EALREADY) { REXDEMOError("SOStartup() already done. (%d)", result); } else if (result < SO_SUCCESS) { REXDEMOError("SOStartup() failed.(%d)", result); REXDEMOError("Network Error Code is %d", -NETGetStartupErrorCode(result)); return FALSE; } /* SOStartup now waits for DHCP to be resolved */ return TRUE; } BOOL REXDEMOSafeSOFinish( void ) { s32 iRetry; s32 result; BOOL succeeded = TRUE; for ( iRetry = REXDEMO_NETWORK_TERMINATION_RETRY_LIMIT; iRetry > 0; iRetry-- ) { result = SOFinish(); if ( result == SO_EBUSY || result == SO_EAGAIN || result == SO_EINPROGRESS ) { s32 r; REXDEMOError("SOFinish() failed.(%d)\n", result); /* This is a state in which SOFinish cannot be called. Try SOCleanup.*/ REXDEMOReport( "Try SOCleanup()...\n" ); r = SOCleanup(); if ( r < SO_SUCCESS ) { REXDEMOError("SOCleanup() failed.(%d)\n", r); } /* wait for other processes to release their network-related resources*/ OSSleepMilliseconds( REXDEMO_NETWORK_TERMINATION_RETRY_WAIT ); } else { break; } } if (result == SO_EALREADY) { /* either SOFinish has already been called, or SOInit was not called in the first place*/ /* the state is the same as after SOFinish is called, so set the return value to TRUE*/ REXDEMOError("SOFinish() already done. (%d)", result); } else if (result < SO_SUCCESS) { /* an unexpected error in SOFinish that should not occur*/ /* error processing is required*/ REXDEMOError("SOFinish() failed.(%d)", result); succeeded = FALSE; } if ( iRetry <= 0 ) { /* The retry limit was reached*/ /* Error processing is required because network termination could not be carried out properly*/ REXDEMOError("Too many network termination retries; give up to call SOFinish().\n"); succeeded = FALSE; } return succeeded; } BOOL REXDEMOEndNetwork( void ) { s32 result = 0; BOOL succeeded = TRUE; /* Stop the network function of the socket library */ result = SOCleanup(); if (result == SO_EALREADY) { REXDEMOError("SOCleanup() already done. (%d)", result); } else if (result < SO_SUCCESS) { REXDEMOError("SOCleanup() failed.(%d)", result); succeeded = FALSE; } /* Deallocate the socket library resource */ if (REXDEMOSafeSOFinish() == FALSE) { succeeded = FALSE; } /* Deallocate the heap given to the socket library*/ REXDEMODestroyHeapForSocket(); return succeeded; } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------* Name : REXDEMOSetNetConfigId Description : Arguments : configId - Returns : None. *---------------------------------------------------------------------------*/ void REXDEMOSetNetConfigId( u8 configId ) { NetConfigId = configId; } /*---------------------------------------------------------------------------* Name : REXDEMOGetNetConfigId Description : Arguments : None. Returns : u8 - *---------------------------------------------------------------------------*/ u8 REXDEMOGetNetConfigId( void ) { return NetConfigId; } /*---------------------------------------------------------------------------* Name : REXDEMOSetPeerName Description : Arguments : peerName - Returns : None. *---------------------------------------------------------------------------*/ void REXDEMOSetPeerName( const char* peerName ) { if( peerName != NULL ) { (void)strncpy(PeerName, peerName, sizeof(PeerName)-1); PeerName[sizeof(PeerName)-1] = 0; } else { (void)memset(PeerName, 0, sizeof(PeerName)); } } /*---------------------------------------------------------------------------* Name : REXDEMOGetPeerName Description : Arguments : None. Returns : const u8* - *---------------------------------------------------------------------------*/ const char* REXDEMOGetPeerName( void ) { return PeerName; } /*---------------------------------------------------------------------------* Name : REXDEMOWaitForNCDReady Description : Wait until NCD is capable of receiving request. If this function enters an infinite loop, the firmware is invalid. Arguments : None. Returns : None. *---------------------------------------------------------------------------*/ void REXDEMOWaitForNCDReady( void ) { while(NCDGetLinkStatus() == NCD_RESULT_INPROGRESS) { OSSleepMilliseconds(100); } } /*---------------------------------------------------------------------------* Name : REXDEMOOverrideNetConfig Description : Force overwrite of NCD network setting. Arguments : pIfConfig - pIpConfig - Returns : s32 - *---------------------------------------------------------------------------*/ s32 REXDEMOOverrideNetConfig( const NCDIfConfig* pIfConfig, const NCDIpConfig* pIpConfig ) { s32 resultNcd; REXDEMOWaitForNCDReady(); ////////////////////////////////////////////////////////////////////////// // * NOTE * // NCDSetIfConfig, NCDSetIpConfig are test functions. // These functions should not be called in the retail release. Simply call SOStartup. // // In such case, the network setting configured to the console will be used. // The network setting for the development machines can be configured through the system tool or RevoEX/RVL/bin/tools/ncdconfigtool.elf. // ////////////////////////////////////////////////////////////////////////// if( pIfConfig != NULL ) { //OSReport("NCDSetIfConfig...\n"); resultNcd = NCDSetIfConfig( pIfConfig ); if( resultNcd != NCD_RESULT_SUCCESS ) { OSReport( "NCDSetIfConfig failed (%d)\n", resultNcd ); return resultNcd; } } if( pIpConfig != NULL ) { //OSReport("NCDSetIpConfig...\n"); resultNcd = NCDSetIpConfig( pIpConfig ); if( resultNcd != NCD_RESULT_SUCCESS ) { OSReport( "NCDSetIpConfig failed (%d)\n", resultNcd ); return resultNcd; } } //OSReport("REXDEMOOverrideNetConfig ok\n"); return NCD_RESULT_SUCCESS; } /*---------------------------------------------------------------------------* Name : REXDEMOOverrideNetConfigAuto Description : Force overwrite of NCD network setting with config.c network setting. config.c setting can be switched with REXDEMOSetNetConfigId(). Arguments : None. Returns : s32 - *---------------------------------------------------------------------------*/ s32 REXDEMOOverrideNetConfigAuto( void ) { NCDIfConfig ifConfig; NCDIfConfig* pIfConfig; NCDIpConfig ipConfig; NCDIpConfig* pIpConfig; u8 configId; s32 result; configId = REXDEMOGetNetConfigId(); pIfConfig = NULL; pIpConfig = NULL; if( REXDEMOCreateIfConfig( &ifConfig, configId ) ) { pIfConfig = &ifConfig; } if( REXDEMOCreateIpConfig( &ipConfig, configId ) ) { pIpConfig = &ipConfig; } result = REXDEMOOverrideNetConfig( pIfConfig, pIpConfig ); if (result < NCD_RESULT_SUCCESS) { return result; } return result; } /*---------------------------------------------------------------------------* Name : REXDEMOWaitForInterfaceReady Description : Waits until NCD prepares the interface. Arguments : msecTimeout - Returns : s32 - *---------------------------------------------------------------------------*/ s32 REXDEMOWaitForInterfaceReady( u32 msecTimeout ) { return REXDEMOWaitForInterfaceReadyEx( msecTimeout, FALSE, NULL ); } s32 REXDEMOWaitForInterfaceReadyEx( u32 msecTimeout, BOOL wantUp, volatile BOOL* flagCancel ) { u32 ms; s32 resultNcd; for ( ms = 0; msecTimeout == 0 || ms < msecTimeout; ms+=100 ) { if (flagCancel && *flagCancel) { break; } switch( resultNcd = NCDGetLinkStatus() ) { case NCD_RESULT_INPROGRESS: case NCD_LINKSTATUS_WORKING: /* in a state where network I/F still cannot be used */ break; case NCD_LINKSTATUS_NONE: /* set so that no communication is allowed */ OSReport( "Not allowed to use Network functions\n" ); return NCD_RESULT_FAILURE; case NCD_LINKSTATUS_WIRELESS_DOWN: if (wantUp) { break; } case NCD_LINKSTATUS_WIRED: case NCD_LINKSTATUS_WIRELESS_UP: return NCD_RESULT_SUCCESS; default: /* other errors are not normally returned*/ OSReport( "NCDGetLinkStatus() failure (%d)\n", resultNcd ); return resultNcd; } //OSReport("NCDGetLinkStatus() = %d\n", resultNcd); OSSleepTicks( OSMillisecondsToTicks( 100 ) ); } return NCD_RESULT_UNDECIDED; } /*---------------------------------------------------------------------------* Name : REXDEMOParseArgument Description : Arguments : argc - Returns : None. *---------------------------------------------------------------------------*/ void REXDEMOParseArgument( int argc, const char* argv[] ) { int curr_arg = 1; /* configId */ if( curr_arg < argc ) { BOOL f; int i; int id; const char* arg = argv[curr_arg]; f = FALSE; id = 0; for( i = 0; arg[i] != 0 && i < 256; i++ ) { if( '0' <= arg[i] && arg[i] <= '9' ) { f = TRUE; id *= 10; id += arg[i] - '0'; if( id >= 256 ) { /* configId runs from 0 to 255 */ f = FALSE; break; } } else { f = FALSE; break; } } if( f ) { NetConfigId = (u8)id; curr_arg++; } else { NetConfigId = 0; } } /* peerName */ if( curr_arg < argc ) { REXDEMOSetPeerName(argv[curr_arg]); } else { REXDEMOSetPeerName(NULL); } } /*---------------------------------------------------------------------------* $Log: netconfig.c,v $ Revision 1.10 2007/09/07 02:13:31 seiki_masashi Separated the REXDEMOSafeSOFinish function. Revision 1.9 2007/09/07 00:41:27 seiki_masashi Improved the safety of network termination processing. Revision 1.8 2007/06/04 09:40:54 hirose_kazuki Added processing that is divided when the SO result is SO_EALREADY. Revision 1.7 2007/06/04 05:29:05 seiki_masashi Fixed a processing bug when errors occurred. Revision 1.6 2007/05/28 08:37:49 hirose_kazuki Added REXDEMODestroyHeapForSocket() call. Revision 1.5 2007/01/29 07:55:24 terui The implementation of the REXDEMOCreatePeerAddressAuto function was moved to netfunc.c. The implementation of the REXDEMOGetPeerAddress function was moved to netfunc.c. Revision 1.4 2006/09/25 07:06:13 seiki_masashi Revised so that the network setting on the NAND will be used for configId 0. Revised so that peerName is also gotten from the command line argument. Revision 1.3 2006/09/25 02:07:07 seiki_masashi Small fix Revision 1.2 2006/09/25 02:00:37 seiki_masashi Followed the specification change of SOStartup. Added comments for cautions regarding NCDSetIfConfig Revision 1.1 2006/08/29 07:19:20 adachi_hiroaki Changed prefix. Cleaned up code elsewhere. *---------------------------------------------------------------------------*/