1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - WM - demos - wireless-all
3   File:     wh_datasharing.c
4 
5   Copyright 2006-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   $Date:: 2008-09-18#$
14   $Rev: 8573 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 
18 #ifdef SDK_TWL
19 #include <twl.h>
20 #else
21 #include <nitro.h>
22 #endif
23 
24 #include "common.h"
25 
26 
27 /*****************************************************************************/
28 /* Functions */
29 
30 /*---------------------------------------------------------------------------*
31   Name:         StateCallbackForWFS
32 
33   Description:  WFS callback function.
34                 This is called when the state became WFS_STATE_READY.
35                 WFS_GetStatus() can be used at any position to make a determination without receiving notification with this callback.
36 
37 
38   Arguments:    arg:       User-defined argument specified in the callback
39 
40   Returns:      None.
41  *---------------------------------------------------------------------------*/
StateCallbackForWFS(void * arg)42 static void StateCallbackForWFS(void *arg)
43 {
44     (void)arg;
45     switch (WFS_GetStatus())
46     {
47     case WFS_STATE_READY:
48         OS_TPrintf("WFS ready.\n");
49         break;
50     }
51 }
52 
53 /*---------------------------------------------------------------------------*
54   Name:         AllocatorForWFS
55 
56   Description:  Dynamic allocation function for memory specified in WFS.
57 
58   Arguments:    arg:       User-defined argument specified in the allocator
59                 size:      Required size if requesting memory allocation
60                 ptr:       If NULL, allocates memory. Otherwise, requests deallocation.
61 
62   Returns:      If ptr is NULL, the amount of memory in size is allocated and its pointer returned.
63                 If not, the ptr memory is released.
64                 If released, the return value is simply ignored.
65  *---------------------------------------------------------------------------*/
AllocatorForWFS(void * arg,u32 size,void * ptr)66 static void *AllocatorForWFS(void *arg, u32 size, void *ptr)
67 {
68     (void)arg;
69     if (!ptr)
70         return OS_Alloc(size);
71     else
72     {
73         OS_Free(ptr);
74         return NULL;
75     }
76 }
77 
78 /*---------------------------------------------------------------------------*
79   Name:         JudgeConnectableChild
80 
81   Description:  Determines if the child is connectable during reconnect.
82 
83   Arguments:    cb:      Information for the child attempting to connect
84 
85   Returns:      If connection is accepted, TRUE.
86                 If not accepted, FALSE.
87  *---------------------------------------------------------------------------*/
JudgeConnectableChild(WMStartParentCallback * cb)88 static BOOL JudgeConnectableChild(WMStartParentCallback *cb)
89 {
90     /*  Search the MAC address for the AID of when multibooting the child of cb->aid */
91     u16     playerNo = MBP_GetPlayerNo(cb->macAddress);
92     OS_TPrintf("MB child(%d) -> DS child(%d)\n", playerNo, cb->aid);
93     return (playerNo != 0);
94 }
95 
96 /*---------------------------------------------------------------------------*
97   Name:         StartWirelessParent
98 
99   Description:  Starts the parent wireless communication process.
100 
101   Arguments:    None.
102 
103   Returns:      None.
104  *---------------------------------------------------------------------------*/
StartWirelessParent(void)105 void StartWirelessParent(void)
106 {
107     /* Initialize WFS and start connection processing */
108     WFS_InitParent(PORT_WFS, StateCallbackForWFS, AllocatorForWFS,
109                    NULL, WH_PARENT_MAX_SIZE, NULL, TRUE);
110     WH_SetJudgeAcceptFunc(JudgeConnectableChild);
111     (void)WH_ParentConnect(WH_CONNECTMODE_DS_PARENT, WM_GetNextTgid(), GetCurrentChannel());
112 }
113 
114 /*---------------------------------------------------------------------------*
115   Name:         StartWirelessChild
116 
117   Description:  Starts the child wireless communication process.
118 
119   Arguments:    None.
120 
121   Returns:      None.
122  *---------------------------------------------------------------------------*/
StartWirelessChild(void)123 void StartWirelessChild(void)
124 {
125     for (;;)
126     {
127         /* Starts WFS initialization, parent search, and connection processes */
128         WaitWHState(WH_SYSSTATE_IDLE);
129         WFS_InitChild(PORT_WFS, StateCallbackForWFS, AllocatorForWFS, NULL);
130         WH_SetGgid(WH_GGID);
131         (void)WH_ChildConnectAuto(WH_CONNECTMODE_DS_CHILD,
132                                   (const u8 *)MB_GetMultiBootParentBssDesc()->bssid, 0);
133         while ((WH_GetSystemState() == WH_SYSSTATE_BUSY) ||
134                (WH_GetSystemState() == WH_SYSSTATE_SCANNING))
135         {
136             (void)WaitNextFrame();
137             PrintString(9, 11, 0xf, "Now working...");
138             if (IS_PAD_TRIGGER(PAD_BUTTON_START))
139             {
140                 (void)WH_Finalize();
141             }
142         }
143         /* Retries if connection fails */
144         if (WH_GetSystemState() == WH_SYSSTATE_CONNECT_FAIL)
145         {
146             WH_Reset();
147             WaitWHState(WH_SYSSTATE_IDLE);
148         }
149         /* End here if an unexpected error occurs */
150         else if (WH_GetSystemState() == WH_SYSSTATE_ERROR)
151         {
152             for (;;)
153             {
154                 static int over_max_entry_count = 0;
155 
156                 (void)WaitNextFrame();
157 
158                 if (WH_GetLastError() == WM_ERRCODE_OVER_MAX_ENTRY)
159                 {
160                     // Considering the possibility of another download child having connected to the parent while reconnecting to the parent, retry the connection several times.
161                     //
162                     // If the retry fails, it is really OVER_MAX_ENTRY.
163                     if (over_max_entry_count < 10)
164                     {
165                         WH_Reset();
166 
167                         over_max_entry_count++;
168 
169                         break;
170                     }
171                     else
172                     {
173                         PrintString(5, 13, 0xf, "OVER_MAX_ENTRY");
174                     }
175                 }
176                 PrintString(5, 10, 0x1, "======= ERROR! =======");
177             }
178         }
179         else
180         {
181             break;
182         }
183     }
184 
185 }
186