1 /*---------------------------------------------------------------------------*
2 Project: WiiConnect24
3 File: Download.c
4
5 Copyright 2007 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 $Log: Download.c,v $
14 Revision 1.2 2007/11/30 08:49:07 adachi_hiroaki
15 Changed the priority that is set
16
17 Revision 1.1 2007/06/07 06:06:39 adachi_hiroaki
18 Added a demo of the download feature.
19
20
21 *---------------------------------------------------------------------------*/
22
23 /*---------------------------------------------------------------------------*
24
25 *---------------------------------------------------------------------------*/
26
27 #include <string.h>
28 #include <revolution/os.h>
29 #include <revolution/mem.h>
30 #include <revolution/nand.h>
31 #include <revolution/net.h>
32 #include <revolution/vf.h>
33 #include <revolution/nwc24.h>
34 #include <revolution/nwc24/NWC24Dl.h>
35
36 /*---------------------------------------------------------------------------*
37 Macros
38 *---------------------------------------------------------------------------*/
39
40 #define VERIFY_NWC24ERR(err, expected) ASSERTMSG( err == expected, "unexpected error code: %d", err )
41
42 #define URL "http://nintendo/file.bin"
43
44 #define DRIVE "C"
45
46 /* Force simulation of the initial run (it is best to initialize the task list with nwc24init.elf)*/
47 //#define SIMULATE_FIRSTRUN
48
49 /* Do not use a signature*/
50 #define NOSIGN
51
52 /* Use the public key prepared by the application*/
53 //#define USE_MYPUBLICKEY
54
55 BOOL DownloadTaskMain( void );
56
57 /*---------------------------------------------------------------------------*
58 Static Data
59 *---------------------------------------------------------------------------*/
60
61 /* The application's public key is specified here. It is easiest to use makeo*/
62 static u8 publicKey[] =
63 {
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
90 };
91
92 /*---------------------------------------------------------------------------*
93 Forward references to local functions
94 *---------------------------------------------------------------------------*/
95 static void SetProperty( NWC24DlTask* task );
96 static NWC24Err UpdateTask( NWC24DlTask* task );
97 static BOOL CheckVf( NWC24DlTask* task, NWC24Err* nwc24Err, VFErr* vfErr );
98
main()99 int main()
100 {
101 OSReport("*******************************************************\n");
102 OSReport(" WiiConnect24 download sample\n");
103 OSReport("*******************************************************\n");
104 VFInit();
105 if (DownloadTaskMain())
106 {
107 OSReport("==== Waiting... ====\n");
108 OSSleepSeconds(60*5);
109
110 (void) DownloadTaskMain();
111 }
112 else
113 {
114 OSReport("NG\n");
115 }
116 OSHalt("Finished.\n");
117 return 0;
118 }
119
DownloadTaskMain(void)120 BOOL DownloadTaskMain( void )
121 {
122 static u32 libWorkMem[NWC24_WORK_MEM_SIZE/sizeof(u32)] ATTRIBUTE_ALIGN(32);
123
124 NWC24Err err = NWC24_OK;
125 NWC24Err err2 = NWC24_OK;
126 VFErr vfErr = VF_ERR_SUCCESS;
127 NWC24DlTask dlTask;
128
129 /*
130 Ease the restrictions on the parameters for the sake of debugging.
131 (Incorporating this into products is prohibited)
132 */
133 NWC24EnableDlLaxParameterChecking(TRUE);
134
135 /*
136 Reduce the scheduler interval to make the downloads happen earlier
137 (Incorporating this into products is prohibited)
138 */
139 (void) NWC24SetScheduleSpan(10, 1);
140
141 err = NWC24OpenLib(&libWorkMem);
142 if (err < NWC24_OK)
143 {
144 return FALSE;
145 }
146
147 /* Update the task*/
148 err = UpdateTask(&dlTask);
149
150 if (err < NWC24_OK)
151 {
152 goto close;
153 }
154
155 /* Display the task's content to the console*/
156 (void) NWC24DumpDlTask(&dlTask);
157
158 /* Check that the content was downloaded*/
159 if (CheckVf(&dlTask, &err, &vfErr))
160 {
161 OSReport("a new content was found.\n");
162 }
163
164
165 close:
166 err2 = NWC24CloseLib();
167 return err == NWC24_OK;
168 }
169
UpdateTask(NWC24DlTask * task)170 static NWC24Err UpdateTask( NWC24DlTask* task )
171 {
172 NWC24Err err;
173 u16 myId = 0;
174
175 /*
176 Get the tasks that have already been registered. Register again if it failed.
177
178 NOTE: This function cannot be used if one application has registering two or more tasks.
179
180 The application must record each task ID and get them with NWC24GetDlTask().
181
182 */
183 #ifndef SIMULATE_FIRSTRUN
184 err = NWC24GetDlTaskMine( task );
185 #else
186 err = NWC24_ERR_NOT_FOUND;
187 #endif
188 if (err == NWC24_ERR_NOT_FOUND)
189 {
190 /*
191 The task has been deleted due to initial registration, expiration, or other such reasons, so it is necessary to recreate it.
192
193 */
194
195 /* Create a new binary data receiving-type task*/
196 err = NWC24InitDlTask(task, NWC24_DLTYPE_OCTETSTREAM);
197 if (err < NWC24_OK)
198 {
199 return err;
200 }
201 /*
202 If the task was newly created, configure the required items.
203 */
204 SetProperty( task );
205 }
206 else if (err < NWC24_OK)
207 {
208 return err;
209 }
210
211 /*
212 Specify the number of remaining downloads.
213 Each time a download is done, the number is decreased by one; when it reaches zero, the task is removed.
214 For this reason, it is necessary to restore the value each time the application is run in order to prevent the task from being removed.
215 */
216 err = NWC24SetDlCount( task, 50 );
217 if (err < NWC24_OK)
218 {
219 return err;
220 }
221
222 /*
223 Register the task data in the task list
224 */
225 err = NWC24AddDlTask(task);
226 if (err < NWC24_OK)
227 {
228 return err;
229 }
230 return NWC24_OK;
231 }
232
233
SetProperty(NWC24DlTask * task)234 static void SetProperty( NWC24DlTask* task )
235 {
236 NWC24Err err;
237 u32 flags = 0;
238 /* Specify the URL*/
239 err = NWC24SetDlUrl( task, URL );
240 VERIFY_NWC24ERR( err, NWC24_OK );
241
242 /*
243 Specify the priority. Tasks will be run with priority given to those with lower values.
244 The values should be set following the guidelines.
245 */
246 err = NWC24SetDlPriority( task, 192 );
247 VERIFY_NWC24ERR( err, NWC24_OK );
248
249 /*
250 Specify the execution interval of the download task
251 Note that task execution won't necessarily be performed in this interval
252 */
253 err = NWC24SetDlInterval( task, 1 );
254 VERIFY_NWC24ERR( err, NWC24_OK );
255
256 /*
257 Specify the file name when storing in VF
258 */
259 err = NWC24SetDlFilename(task, "file.dat");
260 VERIFY_NWC24ERR( err, NWC24_OK );
261
262 #ifdef USE_MYPUBLICKEY
263 err = NWC24SetDlPublicKey(task, publicKey);
264 VERIFY_NWC24ERR( err, NWC24_OK );
265
266 flags |= NWC24_DL_FLAG_USE_MYPUBLICKEY;
267 #endif
268
269 /*
270 Specify to download unsigned content without any further processing.
271 If parameter checking has been disabled for tasks, this cannot be used for http:// URLs.
272 */
273 #ifdef NOSIGN
274 flags |= NWC24_DL_FLAG_RAW_CONTENT;
275 #endif
276
277 err = NWC24SetDlFlags(task, flags);
278 VERIFY_NWC24ERR( err, NWC24_OK );
279
280 }
281
CheckVf(NWC24DlTask * task,NWC24Err * nwc24Err,VFErr * vfErr)282 static BOOL CheckVf( NWC24DlTask* task, NWC24Err* nwc24Err, VFErr* vfErr )
283 {
284 VFFile* vfFile = NULL;
285 BOOL create = TRUE;
286 BOOL result = FALSE;
287 char bufVfName[NAND_MAX_PATH];
288 char bufVfContentName[VF_PATH_BUF_SIZE];
289
290 /* Load the content that was obtained using the VF library*/
291
292 /* Get the VFF file name*/
293 *nwc24Err = NWC24GetDlVfName(task, bufVfName, sizeof(bufVfName));
294 VERIFY_NWC24ERR( *nwc24Err, NWC24_OK );
295
296 /* Get the file name of the content that was saved within VFF*/
297 *nwc24Err = NWC24GetDlFilename(task, bufVfContentName, sizeof(bufVfContentName));
298 VERIFY_NWC24ERR( *nwc24Err, NWC24_OK );
299
300 OSReport("VF archive = %s\n", bufVfName);
301
302 /* Mount */
303 *vfErr = VFMountDriveNANDFlash( DRIVE, bufVfName );
304 if (*vfErr == VF_ERR_SUCCESS)
305 {
306 vfFile = VFOpenFile(bufVfContentName, "r", 0);
307 if ( vfFile )
308 {
309 /* Load the content that was downloaded here*/
310 {
311 s32 length = 0;
312 length = VFGetFileSizeByFd( vfFile );
313 OSReport("filename = %s, size = %d\n", bufVfContentName, length);
314
315 /*
316 In order to check whether the content is new or not, you must embed data such as the sequence number and the creation date within the content, and when checking the received content, make the determination by comparing it with the previously-received information.
317
318
319 */
320 }
321 (void)VFCloseFile( vfFile );
322
323 /* If the later file is not required, delete it.*/
324 *vfErr = VFDeleteFile(bufVfContentName);
325 result = TRUE;
326 create = FALSE;
327 }
328 else
329 {
330 result = FALSE;
331 /* Find out the reason that the file failed to open*/
332 *vfErr = VFGetLastError();
333 if (*vfErr == VF_ERR_ENOENT)
334 {
335 /* The file simple doesn't exist. Recreating VFF is not necessary*/
336 create = FALSE;
337 }
338 else
339 {
340 /* There is a chance that the VFF file is corrupted. Recreate it just in case*/
341 create = TRUE;
342 }
343 }
344 (void)VFUnmountDrive( DRIVE );
345 }
346 else
347 {
348 result = FALSE;
349 create = TRUE;
350 }
351
352 /* Processing if recreating the VFF file is required*/
353 if (create)
354 {
355 /* If recreating, delete it first*/
356 (void)NANDDelete(bufVfName);
357
358 /* Before creating VFF, check it with NANDCheck()*/
359
360 /*
361 Prepare a 500 KB VF archive as the destination for storing the download file
362 Files that exceed this size will not be downloaded
363 */
364 *nwc24Err = NWC24CreateDlVf(task, 500*1024);
365
366 /* If creation failed, handle it in the same way as you would if save data creation failed*/
367 }
368 return result;
369 }
370
371 #if 0
372 static void CheckErrors( NWC24DlTask* task )
373 {
374 NWC24Err err;
375 int globalErr = 0, count = 0;
376
377 /* Get the error that occurred when the task was running*/
378 err = NWC24GetDlError( task, &globalErr, &count );
379 VERIFY_NWC24ERR( err, NWC24_OK );
380
381 if (count > 0 && globalErr != 0)
382 {
383 /* No guidelines have been prepared that relate to the handling of error codes*/
384 OSReport("error %d\n", globalErr);
385
386 /* Clear the error information that was stored in the task*/
387 (void) NWC24ClearDlError( task );
388 }
389 }
390 #endif
391
392 /*---------------------------------------------------------------------------*/
393
394 /*---------------------------------------------------------------------------*/
395