1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - WXC - demos - simple-2
3   File:     user.c
4 
5   Copyright 2005-2009 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:: 2007-11-15#$
14   $Rev: 2414 $
15   $Author: hatamoto_minoru $
16  *---------------------------------------------------------------------------*/
17 #include <nitro.h>
18 
19 #include <nitro/wxc.h>
20 #include "user.h"
21 #include "common.h"
22 #include "dispfunc.h"
23 
24 
25 /*****************************************************************************/
26 /* Constants */
27 
28 /* GGID used for testing */
29 #define SDK_MAKEGGID_SYSTEM(num)              (0x003FFF00 | (num))
30 #define GGID_ORG_1                            SDK_MAKEGGID_SYSTEM(0x53)
31 #define GGID_ORG_2                            SDK_MAKEGGID_SYSTEM(0x54)
32 
33 /* Send/receive data size for testing */
34 #define DATA_SIZE (1024 * 20)
35 
36 
37 /*****************************************************************************/
38 /* Variables */
39 
40 /* Number of successful exchanges */
41 static int data_exchange_count = 0;
42 
43 /* Data buffer for testing */
44 static u8 send_data[DATA_SIZE];
45 static u8 recv_data[DATA_SIZE];
46 
47 static u8 send_data2[DATA_SIZE];
48 static u8 recv_data2[DATA_SIZE];
49 
50 extern int passby_endflg;
51 extern BOOL passby_ggid[MENU_MAX];     // GGID that does chance encounter communications
52 extern BOOL send_comp_flg;
53 
54 static int register_count;
55 
56 static u32 delete_ggid;
57 
58 /*---------------------------------------------------------------------------*
59   Name:         CalcHash
60 
61   Description:  Hash calculation for a simple check.
62 
63   Arguments:    src: Calculation target buffer
64 
65   Returns:      The calculated value.
66  *---------------------------------------------------------------------------*/
CalcHash(const u8 * src)67 static u8 CalcHash(const u8 *src)
68 {
69     int     i;
70     u8      sum = 0;
71     for (i = 0; i < DATA_SIZE - 1; i++)
72     {
73         sum ^= src[i];
74     }
75     return sum;
76 }
77 
78 /*---------------------------------------------------------------------------*
79   Name:         CreateData
80 
81   Description:  Creates send data.
82 
83   Arguments:    buf: Data storage target
84 
85   Returns:      None.
86  *---------------------------------------------------------------------------*/
CreateData(void * buf)87 static void CreateData(void *buf)
88 {
89 	*(OSTick*)buf = OS_GetTick();
90 	OS_GetMacAddress((u8*)buf + sizeof(OSTick));
91 }
92 
93 
94 /*---------------------------------------------------------------------------*
95   Name:         user_callback
96 
97   Description:  Data exchange complete callback.
98 
99   Arguments:    stat: Notification status (normally WXC_STATE_EXCHANGE_DONE)
100                 arg: Notification argument (receive data buffer)
101 
102   Returns:      The calculated value.
103  *---------------------------------------------------------------------------*/
user_callback(WXCStateCode stat,void * arg)104 static void user_callback(WXCStateCode stat, void *arg)
105 {
106 #pragma unused(stat)
107 
108     const WXCBlockDataFormat * block = (const WXCBlockDataFormat *)arg;
109     u8      sum = 0;
110     u8     *data = (u8 *)block->buffer;
111 
112     const u8 *dst_mac = data + sizeof(OSTick);
113 
114     ++data_exchange_count;
115 
116     /* Displays debug receive data */
117     sum = CalcHash(data);
118 
119     if (sum == data[DATA_SIZE - 1])
120     {
121         BgPrintf((s16)1, (s16)5, WHITE, "sum OK 0x%02X %6d %6d sec", sum, data_exchange_count,
122                 OS_TicksToSeconds(OS_GetTick()));
123         //BgPrintf((s16)1, (s16)6, WHITE, "%s", data);
124         BgPrintf((s16)1, (s16)6, WHITE, "  (from %02X:%02X:%02X:%02X:%02X:%02X)\n\n",
125 					dst_mac[0], dst_mac[1], dst_mac[2], dst_mac[3], dst_mac[4], dst_mac[5]);
126     }
127     else
128     {
129         BgPrintf((s16)1, (s16)5, WHITE, "sum NG 0x%02X %6d %6d sec", sum, data_exchange_count,
130                 OS_TicksToSeconds(OS_GetTick()));
131     }
132 
133 	delete_ggid = 0;
134 
135     // Set to close after a single communication (unless it's set to send all data)
136     if(send_comp_flg == TRUE)
137     {
138 		if( WXC_IsParentMode() == TRUE)
139         {
140             const WMParentParam *param;
141 
142             // Get parent (self) information
143             param = WXC_GetParentParam();
144             /* Get the GGID of the registered data to delete */
145 	    	delete_ggid = param->ggid;
146         }
147         else
148         {
149             const WMBssDesc *bss;
150 
151             // Get parent (target) MAC address
152             bss = WXC_GetParentBssDesc();
153             /* Get the GGID of the registered data to delete */
154         	delete_ggid = bss->gameInfo.ggid;
155         }
156 
157 		register_count--;
158 
159         if(register_count <= 0)
160 		{
161 			if( WXC_IsParentMode() == TRUE)
162             {
163                 passby_endflg = 1;
164             }
165             else
166             {
167                 passby_endflg = 2;
168             }
169 		}
170 		else
171 		{
172             // To run WXC_UnregisterData, call WXC_Stop and set the state to WXC_STATE_READY
173             WXC_Stop();
174         }
175 	}
176 	else
177 	{
178         if( WXC_IsParentMode() == TRUE)
179         {
180             passby_endflg = 1;
181         }
182         else
183         {
184             passby_endflg = 2;
185         }
186     }
187     MI_CpuClear32(data, DATA_SIZE);
188 }
189 
190 
191 /*---------------------------------------------------------------------------*
192   Name:         system_callback
193 
194   Description:  WXC library system callback.
195 
196   Arguments:    stat: Notification status (normally WXC_STATE_EXCHANGE_DONE)
197                 arg: Notification argument (receive data buffer)
198 
199   Returns:      The calculated value.
200  *---------------------------------------------------------------------------*/
system_callback(WXCStateCode state,void * arg)201 static void system_callback(WXCStateCode state, void *arg)
202 {
203     switch (state)
204     {
205     case WXC_STATE_READY:
206         /*
207          * Issued from a WXC_Init function call.
208          * arg is always NULL.
209          */
210         // If, rather than unregistering data, you only want to temporarily stop exchanging it, you may also use WXC_SetInitialData during a user_callback for the same results
211         //
212         if(delete_ggid != 0)
213             WXC_UnregisterData(delete_ggid);
214         /* Library wireless startup */
215         WXC_Start();
216         break;
217 
218     case WXC_STATE_ACTIVE:
219         /*
220          * Issued from a WXC_Start function call.
221          * arg is always NULL.
222          */
223         break;
224 
225     case WXC_STATE_ENDING:
226         /*
227          * Issued from a WXC_End function call.
228          * arg is always NULL.
229          */
230         break;
231 
232     case WXC_STATE_END:
233         /*
234          * Issued upon completion of the shutdown processing run by the WXC_End function.
235          * arg is internal work memory allocated by the WXC_Init function.
236          * At this point, work memory is deallocated by the user.
237          */
238         {
239             void *system_work = arg;
240             OS_Free(system_work);
241         }
242         break;
243 
244     case WXC_STATE_EXCHANGE_DONE:
245         /*
246          * Data exchange complete (not currently issued)
247          */
248         break;
249     }
250 }
251 
252 
User_Init(void)253 void User_Init(void)
254 {
255 	register_count = 0;
256 	delete_ggid = 0;
257 
258     /* Initializes the internal status of the library */
259     WXC_Init(OS_Alloc(WXC_WORK_SIZE), system_callback, 2);
260 
261     /*
262      * Register a data block.
263      * Currently, the send/receive data size is the same for this and other systems.
264      */
265     // Register if flag is set
266     if(passby_ggid[0] == TRUE)
267     {
268         CreateData(send_data);
269         send_data[DATA_SIZE - 2] = (u8)GGID_ORG_1;
270         send_data[DATA_SIZE - 1] = CalcHash(send_data);
271         WXC_RegisterCommonData(GGID_ORG_1, user_callback, send_data, DATA_SIZE, recv_data, DATA_SIZE);
272 
273         register_count++;
274     }
275 
276     /*
277      * Register one more data block as test.
278      * Under current specifications, time-sharing is used to select each data block and data is exchanged with the child that has the same GGID.
279      *
280      */
281     // Register if flag is set
282 
283     if(passby_ggid[1] == TRUE)
284     {
285         CreateData(send_data2);
286         send_data2[DATA_SIZE - 2] = (u8)GGID_ORG_2;
287         send_data2[DATA_SIZE - 1] = CalcHash(send_data2);
288         WXC_RegisterCommonData(GGID_ORG_2, user_callback, send_data2, DATA_SIZE, recv_data2, DATA_SIZE);
289 
290         register_count++;
291     }
292 }
293