1 /*---------------------------------------------------------------------------*
2 Project: RevoEX - demos - share
3 File: init.c
4
5 Copyright 2006 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 #include <revolution/os.h>
15 #include <revolution/ncd.h>
16 #include <revolution/so.h>
17 #include <revolution/net.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include "rexdemo/netconfig.h"
21 #include "rexdemo/graphic.h"
22
23 /*---------------------------------------------------------------------------*
24 Variable Definitions
25 *---------------------------------------------------------------------------*/
26
27 static u8 NetConfigId = 0;
28 static char PeerName[256];
29
30 /*---------------------------------------------------------------------------*
31 Internal function prototype declarations
32 *---------------------------------------------------------------------------*/
33
34 BOOL
REXDEMOStartNetwork(BOOL override)35 REXDEMOStartNetwork(BOOL override)
36 {
37 s32 result = 0;
38
39 /* Overwrite the network setting stored in NAND? */
40 if (override)
41 {
42 /* Overwrite the network setting based on argument analysis result (for debug) */
43 result = REXDEMOOverrideNetConfigAuto();
44 if (result < NCD_RESULT_SUCCESS)
45 {
46 REXDEMOError("REXDEMOOverrideNetConfigAuto() failed.(%d)", result);
47 return FALSE;
48 }
49 }
50
51 /* Create the heap to be given to the socket library */
52 if (!REXDEMOCreateHeapForSocket( REXDEMO_SOCKET_HEAPSIZE_DEFAULT ))
53 {
54 REXDEMOError("REXDEMOCreateHeapForSocket() failed.");
55 return FALSE;
56 }
57 /* Initialize the socket library by specifying the allocator in REXDEMO */
58 result = SOInit( REXDEMOGetSOLibConfig() );
59 if (result == SO_EALREADY)
60 {
61 REXDEMOError("SOInit() already done. (%d)", result);
62 }
63 else if (result < SO_SUCCESS)
64 {
65 REXDEMOError("SOInit() failed.(%d)", result);
66 return FALSE;
67 }
68
69 /* Start the network feature of the socket library */
70 result = SOStartup();
71 if (result == SO_EALREADY)
72 {
73 REXDEMOError("SOStartup() already done. (%d)", result);
74 }
75 else if (result < SO_SUCCESS)
76 {
77 REXDEMOError("SOStartup() failed.(%d)", result);
78 REXDEMOError("Network Error Code is %d", -NETGetStartupErrorCode(result));
79 return FALSE;
80 }
81
82 /* SOStartup now waits for DHCP to be resolved */
83
84 return TRUE;
85 }
86
87 BOOL
REXDEMOSafeSOFinish(void)88 REXDEMOSafeSOFinish( void )
89 {
90 s32 iRetry;
91 s32 result;
92 BOOL succeeded = TRUE;
93
94 for ( iRetry = REXDEMO_NETWORK_TERMINATION_RETRY_LIMIT; iRetry > 0; iRetry-- )
95 {
96 result = SOFinish();
97 if ( result == SO_EBUSY || result == SO_EAGAIN || result == SO_EINPROGRESS )
98 {
99 s32 r;
100 REXDEMOError("SOFinish() failed.(%d)\n", result);
101
102 /* This is a state in which SOFinish cannot be called. Try SOCleanup.*/
103 REXDEMOReport( "Try SOCleanup()...\n" );
104 r = SOCleanup();
105 if ( r < SO_SUCCESS )
106 {
107 REXDEMOError("SOCleanup() failed.(%d)\n", r);
108 }
109 /* wait for other processes to release their network-related resources*/
110 OSSleepMilliseconds( REXDEMO_NETWORK_TERMINATION_RETRY_WAIT );
111 }
112 else
113 {
114 break;
115 }
116 }
117 if (result == SO_EALREADY)
118 {
119 /* either SOFinish has already been called, or SOInit was not called in the first place*/
120 /* the state is the same as after SOFinish is called, so set the return value to TRUE*/
121 REXDEMOError("SOFinish() already done. (%d)", result);
122 }
123 else if (result < SO_SUCCESS)
124 {
125 /* an unexpected error in SOFinish that should not occur*/
126 /* error processing is required*/
127 REXDEMOError("SOFinish() failed.(%d)", result);
128 succeeded = FALSE;
129 }
130
131 if ( iRetry <= 0 )
132 {
133 /* The retry limit was reached*/
134 /* Error processing is required because network termination could not be carried out properly*/
135 REXDEMOError("Too many network termination retries; give up to call SOFinish().\n");
136 succeeded = FALSE;
137 }
138
139 return succeeded;
140 }
141
142 BOOL
REXDEMOEndNetwork(void)143 REXDEMOEndNetwork( void )
144 {
145 s32 result = 0;
146 BOOL succeeded = TRUE;
147
148 /* Stop the network function of the socket library */
149 result = SOCleanup();
150 if (result == SO_EALREADY)
151 {
152 REXDEMOError("SOCleanup() already done. (%d)", result);
153 }
154 else if (result < SO_SUCCESS)
155 {
156 REXDEMOError("SOCleanup() failed.(%d)", result);
157 succeeded = FALSE;
158 }
159
160 /* Deallocate the socket library resource */
161 if (REXDEMOSafeSOFinish() == FALSE)
162 {
163 succeeded = FALSE;
164 }
165
166 /* Deallocate the heap given to the socket library*/
167 REXDEMODestroyHeapForSocket();
168
169 return succeeded;
170 }
171
172 /*---------------------------------------------------------------------------*
173 *---------------------------------------------------------------------------*/
174
175 /*---------------------------------------------------------------------------*
176 Name : REXDEMOSetNetConfigId
177 Description :
178 Arguments : configId -
179 Returns : None.
180 *---------------------------------------------------------------------------*/
181 void
REXDEMOSetNetConfigId(u8 configId)182 REXDEMOSetNetConfigId( u8 configId )
183 {
184 NetConfigId = configId;
185 }
186
187 /*---------------------------------------------------------------------------*
188 Name : REXDEMOGetNetConfigId
189 Description :
190 Arguments : None.
191 Returns : u8 -
192 *---------------------------------------------------------------------------*/
193 u8
REXDEMOGetNetConfigId(void)194 REXDEMOGetNetConfigId( void )
195 {
196 return NetConfigId;
197 }
198
199 /*---------------------------------------------------------------------------*
200 Name : REXDEMOSetPeerName
201 Description :
202 Arguments : peerName -
203 Returns : None.
204 *---------------------------------------------------------------------------*/
205 void
REXDEMOSetPeerName(const char * peerName)206 REXDEMOSetPeerName( const char* peerName )
207 {
208 if( peerName != NULL )
209 {
210 (void)strncpy(PeerName, peerName, sizeof(PeerName)-1);
211 PeerName[sizeof(PeerName)-1] = 0;
212 }
213 else
214 {
215 (void)memset(PeerName, 0, sizeof(PeerName));
216 }
217 }
218
219 /*---------------------------------------------------------------------------*
220 Name : REXDEMOGetPeerName
221 Description :
222 Arguments : None.
223 Returns : const u8* -
224 *---------------------------------------------------------------------------*/
225 const char*
REXDEMOGetPeerName(void)226 REXDEMOGetPeerName( void )
227 {
228 return PeerName;
229 }
230
231 /*---------------------------------------------------------------------------*
232 Name : REXDEMOWaitForNCDReady
233 Description : Wait until NCD is capable of receiving request.
234 If this function enters an infinite loop, the firmware is invalid.
235 Arguments : None.
236 Returns : None.
237 *---------------------------------------------------------------------------*/
238 void
REXDEMOWaitForNCDReady(void)239 REXDEMOWaitForNCDReady( void )
240 {
241 while(NCDGetLinkStatus() == NCD_RESULT_INPROGRESS)
242 {
243 OSSleepMilliseconds(100);
244 }
245 }
246
247 /*---------------------------------------------------------------------------*
248 Name : REXDEMOOverrideNetConfig
249 Description : Force overwrite of NCD network setting.
250 Arguments : pIfConfig -
251 pIpConfig -
252 Returns : s32 -
253 *---------------------------------------------------------------------------*/
254 s32
REXDEMOOverrideNetConfig(const NCDIfConfig * pIfConfig,const NCDIpConfig * pIpConfig)255 REXDEMOOverrideNetConfig( const NCDIfConfig* pIfConfig, const NCDIpConfig* pIpConfig )
256 {
257 s32 resultNcd;
258
259 REXDEMOWaitForNCDReady();
260
261 //////////////////////////////////////////////////////////////////////////
262 // * NOTE *
263 // NCDSetIfConfig, NCDSetIpConfig are test functions.
264 // These functions should not be called in the retail release. Simply call SOStartup.
265 //
266 // In such case, the network setting configured to the console will be used.
267 // The network setting for the development machines can be configured through the system tool or RevoEX/RVL/bin/tools/ncdconfigtool.elf.
268 //
269 //////////////////////////////////////////////////////////////////////////
270
271 if( pIfConfig != NULL )
272 {
273 //OSReport("NCDSetIfConfig...\n");
274 resultNcd = NCDSetIfConfig( pIfConfig );
275 if( resultNcd != NCD_RESULT_SUCCESS )
276 {
277 OSReport( "NCDSetIfConfig failed (%d)\n", resultNcd );
278 return resultNcd;
279 }
280 }
281
282 if( pIpConfig != NULL )
283 {
284 //OSReport("NCDSetIpConfig...\n");
285 resultNcd = NCDSetIpConfig( pIpConfig );
286 if( resultNcd != NCD_RESULT_SUCCESS )
287 {
288 OSReport( "NCDSetIpConfig failed (%d)\n", resultNcd );
289 return resultNcd;
290 }
291 }
292
293 //OSReport("REXDEMOOverrideNetConfig ok\n");
294 return NCD_RESULT_SUCCESS;
295 }
296
297 /*---------------------------------------------------------------------------*
298 Name : REXDEMOOverrideNetConfigAuto
299 Description : Force overwrite of NCD network setting with config.c network setting.
300
301 config.c setting can be switched with REXDEMOSetNetConfigId().
302 Arguments : None.
303 Returns : s32 -
304 *---------------------------------------------------------------------------*/
305 s32
REXDEMOOverrideNetConfigAuto(void)306 REXDEMOOverrideNetConfigAuto( void )
307 {
308 NCDIfConfig ifConfig;
309 NCDIfConfig* pIfConfig;
310 NCDIpConfig ipConfig;
311 NCDIpConfig* pIpConfig;
312 u8 configId;
313 s32 result;
314
315 configId = REXDEMOGetNetConfigId();
316 pIfConfig = NULL;
317 pIpConfig = NULL;
318 if( REXDEMOCreateIfConfig( &ifConfig, configId ) )
319 {
320 pIfConfig = &ifConfig;
321 }
322 if( REXDEMOCreateIpConfig( &ipConfig, configId ) )
323 {
324 pIpConfig = &ipConfig;
325 }
326
327 result = REXDEMOOverrideNetConfig( pIfConfig, pIpConfig );
328 if (result < NCD_RESULT_SUCCESS)
329 {
330 return result;
331 }
332 return result;
333 }
334
335 /*---------------------------------------------------------------------------*
336 Name : REXDEMOWaitForInterfaceReady
337 Description : Waits until NCD prepares the interface.
338 Arguments : msecTimeout -
339 Returns : s32 -
340 *---------------------------------------------------------------------------*/
341 s32
REXDEMOWaitForInterfaceReady(u32 msecTimeout)342 REXDEMOWaitForInterfaceReady( u32 msecTimeout )
343 {
344 return REXDEMOWaitForInterfaceReadyEx( msecTimeout, FALSE, NULL );
345 }
346
347 s32
REXDEMOWaitForInterfaceReadyEx(u32 msecTimeout,BOOL wantUp,volatile BOOL * flagCancel)348 REXDEMOWaitForInterfaceReadyEx( u32 msecTimeout, BOOL wantUp, volatile BOOL* flagCancel )
349 {
350 u32 ms;
351 s32 resultNcd;
352 for ( ms = 0; msecTimeout == 0 || ms < msecTimeout; ms+=100 )
353 {
354 if (flagCancel && *flagCancel)
355 {
356 break;
357 }
358 switch( resultNcd = NCDGetLinkStatus() )
359 {
360 case NCD_RESULT_INPROGRESS:
361 case NCD_LINKSTATUS_WORKING:
362 /* in a state where network I/F still cannot be used */
363 break;
364 case NCD_LINKSTATUS_NONE:
365 /* set so that no communication is allowed */
366 OSReport( "Not allowed to use Network functions\n" );
367 return NCD_RESULT_FAILURE;
368
369 case NCD_LINKSTATUS_WIRELESS_DOWN:
370 if (wantUp)
371 {
372 break;
373 }
374 case NCD_LINKSTATUS_WIRED:
375 case NCD_LINKSTATUS_WIRELESS_UP:
376 return NCD_RESULT_SUCCESS;
377 default:
378 /* other errors are not normally returned*/
379 OSReport( "NCDGetLinkStatus() failure (%d)\n", resultNcd );
380 return resultNcd;
381 }
382 //OSReport("NCDGetLinkStatus() = %d\n", resultNcd);
383 OSSleepTicks( OSMillisecondsToTicks( 100 ) );
384 }
385 return NCD_RESULT_UNDECIDED;
386 }
387
388 /*---------------------------------------------------------------------------*
389 Name : REXDEMOParseArgument
390 Description :
391 Arguments : argc -
392 Returns : None.
393 *---------------------------------------------------------------------------*/
394 void
REXDEMOParseArgument(int argc,const char * argv[])395 REXDEMOParseArgument( int argc, const char* argv[] )
396 {
397 int curr_arg = 1;
398
399 /* configId */
400 if( curr_arg < argc )
401 {
402 BOOL f;
403 int i;
404 int id;
405 const char* arg = argv[curr_arg];
406
407 f = FALSE;
408 id = 0;
409 for( i = 0; arg[i] != 0 && i < 256; i++ )
410 {
411 if( '0' <= arg[i] && arg[i] <= '9' )
412 {
413 f = TRUE;
414 id *= 10;
415 id += arg[i] - '0';
416 if( id >= 256 )
417 {
418 /* configId runs from 0 to 255 */
419 f = FALSE;
420 break;
421 }
422 }
423 else
424 {
425 f = FALSE;
426 break;
427 }
428 }
429
430 if( f )
431 {
432 NetConfigId = (u8)id;
433 curr_arg++;
434 }
435 else
436 {
437 NetConfigId = 0;
438 }
439 }
440
441 /* peerName */
442 if( curr_arg < argc )
443 {
444 REXDEMOSetPeerName(argv[curr_arg]);
445 }
446 else
447 {
448 REXDEMOSetPeerName(NULL);
449 }
450 }
451
452 /*---------------------------------------------------------------------------*
453 $Log: netconfig.c,v $
454 Revision 1.10 2007/09/07 02:13:31 seiki_masashi
455 Separated the REXDEMOSafeSOFinish function.
456
457 Revision 1.9 2007/09/07 00:41:27 seiki_masashi
458 Improved the safety of network termination processing.
459
460 Revision 1.8 2007/06/04 09:40:54 hirose_kazuki
461 Added processing that is divided when the SO result is SO_EALREADY.
462
463 Revision 1.7 2007/06/04 05:29:05 seiki_masashi
464 Fixed a processing bug when errors occurred.
465
466 Revision 1.6 2007/05/28 08:37:49 hirose_kazuki
467 Added REXDEMODestroyHeapForSocket() call.
468
469 Revision 1.5 2007/01/29 07:55:24 terui
470 The implementation of the REXDEMOCreatePeerAddressAuto function was moved to netfunc.c.
471 The implementation of the REXDEMOGetPeerAddress function was moved to netfunc.c.
472
473 Revision 1.4 2006/09/25 07:06:13 seiki_masashi
474 Revised so that the network setting on the NAND will be used for configId 0.
475 Revised so that peerName is also gotten from the command line argument.
476
477 Revision 1.3 2006/09/25 02:07:07 seiki_masashi
478 Small fix
479
480 Revision 1.2 2006/09/25 02:00:37 seiki_masashi
481 Followed the specification change of SOStartup.
482 Added comments for cautions regarding NCDSetIfConfig
483
484 Revision 1.1 2006/08/29 07:19:20 adachi_hiroaki
485 Changed prefix. Cleaned up code elsewhere.
486
487 *---------------------------------------------------------------------------*/
488