1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - WXC - demos - unregister-1
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 "font.h"
22 #include "text.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(0x55)
31 
32 /* Send/receive data size for testing */
33 #define DATA_SIZE (1024 * 20)
34 
35 
36 /*****************************************************************************/
37 /* Variables */
38 
39 /* Number of successful exchanges */
40 static int data_exchange_count = 0;
41 
42 /* Data buffer for testing */
43 static u8 send_data[DATA_SIZE];
44 static u8 recv_data[DATA_SIZE];
45 
46 
47 /*---------------------------------------------------------------------------*
48   Name:         CalcHash
49 
50   Description:  Hash calculation for a simple check.
51 
52   Arguments:    src: Calculation target buffer
53 
54   Returns:      The calculated value.
55  *---------------------------------------------------------------------------*/
CalcHash(const u8 * src)56 static u8 CalcHash(const u8 *src)
57 {
58     int     i;
59     u8      sum = 0;
60     for (i = 0; i < DATA_SIZE - 1; i++)
61     {
62         sum ^= src[i];
63     }
64     return sum;
65 }
66 
67 /*---------------------------------------------------------------------------*
68   Name:         CreateData
69 
70   Description:  Creates send data.
71 
72   Arguments:    buf: Data storage target.
73 
74   Returns:      None.
75  *---------------------------------------------------------------------------*/
CreateData(void * buf)76 static void CreateData(void *buf)
77 {
78 	*(OSTick*)buf = OS_GetTick();
79 	OS_GetMacAddress((u8*)buf + sizeof(OSTick));
80 }
81 
82 /*---------------------------------------------------------------------------*
83   Name:         user_callback
84 
85   Description:  Data exchange complete callback
86 
87   Arguments:    stat: Notification status (normally WXC_STATE_EXCHANGE_DONE)
88                 arg: Notification argument (receive data buffer)
89 
90   Returns:      The calculated value.
91  *---------------------------------------------------------------------------*/
user_callback(WXCStateCode stat,void * arg)92 static void user_callback(WXCStateCode stat, void *arg)
93 {
94 #pragma unused(stat)
95 
96     const WXCBlockDataFormat * block = (const WXCBlockDataFormat *)arg;
97     u8      sum = 0;
98     u8     *data = (u8 *)block->buffer;
99 
100 	SDK_ASSERT(stat == WXC_STATE_EXCHANGE_DONE);
101     ++data_exchange_count;
102 
103     /* Displays debug receive data */
104     sum = CalcHash(data);
105 
106     if (sum == data[DATA_SIZE - 1])
107     {
108         mprintf("sum OK 0x%02X %6d %6d sec\n", sum, data_exchange_count,
109                 OS_TicksToSeconds(OS_GetTick()));
110 
111 		/* Determines whether received data is its own or re-sent */
112 		{
113 			u8 mac[6];
114 			const u8 *dst_mac = data + sizeof(OSTick);
115 			int i;
116 
117 			OS_GetMacAddress(mac);
118 			for ( i = 0 ; (i < sizeof(mac)) && (dst_mac[i] == mac[i]) ; ++i )
119 			{
120 			}
121 			/* If it is its own sent data, it regenerates data */
122 			if(i >= sizeof(mac))
123 			{
124 				mprintf("  (own data before %6d sec)\n",
125 					OS_TicksToSeconds(OS_GetTick() - *(OSTick*)data));
126 				CreateData(send_data);
127 			}
128 			/* If it is data from a new sender, it forwards the data as is */
129 			else
130 			{
131 				mprintf("  (from %02X:%02X:%02X:%02X:%02X:%02X)\n\n",
132 					dst_mac[0], dst_mac[1], dst_mac[2], dst_mac[3], dst_mac[4], dst_mac[5]);
133 				MI_CpuCopy8(data, send_data, sizeof(send_data));
134 			}
135 			/*
136 			 * Pause to unregister data and then register it again.
137 			 * Even though the current library allows WXC_SetInitialData() to be used for equivalent processing here without pausing wireless features, we are employing the method shown here anyway because this sample shows how to use WXC_UnregisterData().
138 			 *
139 			 *
140 			 *
141 			 */
142 			WXC_Stop();
143 		}
144     }
145     else
146     {
147         mprintf("sum NG 0x%02X sum 0x0%02X %6d sec\n", sum, data[DATA_SIZE - 1],
148                 OS_TicksToSeconds(OS_GetTick()));
149     }
150 
151     MI_CpuClear32(data, DATA_SIZE);
152 }
153 
154 /*---------------------------------------------------------------------------*
155   Name:         system_callback
156 
157   Description:  WXC library system callback.
158 
159   Arguments:    stat: Notification status
160                 arg: Notification argument (the meaning changes based on the notification status)
161 
162   Returns:      The calculated value.
163  *---------------------------------------------------------------------------*/
system_callback(WXCStateCode state,void * arg)164 static void system_callback(WXCStateCode state, void *arg)
165 {
166 	switch (state)
167 	{
168 	case WXC_STATE_READY:
169 		/*
170 		 * Issued from a WXC_Init function call or when WXC_Stop completes.
171 		 * arg is always NULL.
172 		 */
173 
174 		/* If there is currently registered data, it is cancelled here */
175 		if (data_exchange_count > 0)
176 		{
177 			WXC_UnregisterData(GGID_ORG_1);
178 		}
179 		/* Newly registers data for the next exchange */
180 		send_data[DATA_SIZE - 2] = (u8)GGID_ORG_1;
181 		send_data[DATA_SIZE - 1] = CalcHash(send_data);
182 		WXC_RegisterCommonData(GGID_ORG_1, user_callback, send_data, DATA_SIZE, recv_data, DATA_SIZE);
183 		/* Library wireless startup */
184 		WXC_Start();
185 		break;
186 
187 	case WXC_STATE_ACTIVE:
188         /*
189 		 * Issued from a WXC_Start function call.
190 		 * arg is always NULL.
191 		 */
192 		break;
193 
194 	case WXC_STATE_ENDING:
195 		/*
196 		 * Issued from a WXC_End function call.
197 		 * arg is always NULL.
198 		 */
199 		break;
200 
201 	case WXC_STATE_END:
202 		/*
203 		 * Issued upon completion of the shutdown processing run by the WXC_End function.
204 		 * arg is internal work memory allocated by the WXC_Init function.
205 		 * At this point, work memory is deallocated by the user.
206 		 */
207 		{
208 			void *system_work = arg;
209 			OS_Free(system_work);
210 		}
211 		break;
212 
213 	case WXC_STATE_CONNECTED:
214 		/*
215 		 * Issued when a new connection is made.
216 		 * arg is a pointer to the WXCUserInfo structure that shows the connection target.
217 		 */
218 		{
219 			const WXCUserInfo * user = (const WXCUserInfo *)arg;
220 			OS_TPrintf("connected(%2d):%02X:%02X:%02X:%02X:%02X:%02X\n",
221 				user->aid,
222 				user->macAddress[0], user->macAddress[1], user->macAddress[2],
223 				user->macAddress[3], user->macAddress[4], user->macAddress[5]);
224 		}
225 		break;
226 
227 	case WXC_STATE_EXCHANGE_DONE:
228 		/*
229 		 * Data exchange complete (not currently issued)
230 		 */
231 		break;
232 	}
233 }
234 
235 
User_Init(void)236 void User_Init(void)
237 {
238     /* Initializes data for the next exchange */
239     data_exchange_count = 0;
240     CreateData(send_data);
241     /* Initializes the internal status of the library */
242     WXC_Init(OS_Alloc(WXC_WORK_SIZE), system_callback, 2);
243 }
244