1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - WM - libraries
3   File:     wm_standard.c
4 
5   Copyright 2003-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-11-19#$
14   $Rev: 9342 $
15   $Author: okajima_manabu $
16  *---------------------------------------------------------------------------*/
17 
18 #include    <nitro/wm.h>
19 #include    "wm_arm9_private.h"
20 
21 
22 /*---------------------------------------------------------------------------*
23     Internal Function Definitions
24  *---------------------------------------------------------------------------*/
25 static BOOL WmCheckParentParameter(const WMParentParam *param);
26 
27 
28 /*---------------------------------------------------------------------------*
29   Name:         WM_Enable
30 
31   Description:  Makes the wireless hardware to the usable state.
32                 Internal state changes from READY state to STOP state.
33 
34   Arguments:    callback    -   Callback function that is called when the asynchronous process completes.
35 
36   Returns:      WMErrCode   -   Returns the processing result. Returns WM_ERRCODE_OPERATING if asynchronous processing started successfully. Afterwards, the asynchronous processing results will be passed to the callback.
37 
38 
39  *---------------------------------------------------------------------------*/
WM_Enable(WMCallbackFunc callback)40 WMErrCode WM_Enable(WMCallbackFunc callback)
41 {
42     return WMi_EnableEx(callback, 0);
43 }
44 
45 /*---------------------------------------------------------------------------*
46   Name:         WM_EnableForListening
47 
48   Description:  Makes the wireless hardware to the usable state.
49                 Internal state changes from READY state to STOP state.
50                 Operations that require sending radio signals are not available.
51 
52   Arguments:    callback    -   Callback function that is called when the asynchronous process completes.
53                 blink       -   Whether to flash the LED
54 
55   Returns:      WMErrCode   -   Returns the processing result.
56                                 Returns WM_ERRCODE_OPERATING if asynchronous processing started successfully. Afterwards, the asynchronous processing results will be passed to the callback.
57 
58  *---------------------------------------------------------------------------*/
WM_EnableForListening(WMCallbackFunc callback,BOOL blink)59 WMErrCode WM_EnableForListening(WMCallbackFunc callback, BOOL blink)
60 {
61     u32 miscFlags = WM_MISC_FLAG_LISTEN_ONLY;
62 
63     if (!blink)
64     {
65         miscFlags |= WM_MISC_FLAG_NO_BLINK;
66     }
67 
68     return WMi_EnableEx(callback, miscFlags);
69 }
70 
71 /*---------------------------------------------------------------------------*
72   Name:         WMi_EnableEx
73 
74   Description:  Makes the wireless hardware to the usable state.
75                 Internal state changes from READY state to STOP state.
76 
77   Arguments:    callback    -   Callback function that is called when the asynchronous process completes.
78                 miscFlags   -   Flags during initialization
79 
80   Returns:      WMErrCode   -   Returns the processing result.
81                                 Returns WM_ERRCODE_OPERATING if asynchronous processing started successfully. Afterwards, the asynchronous processing results will be passed to the callback.
82 
83  *---------------------------------------------------------------------------*/
WMi_EnableEx(WMCallbackFunc callback,u32 miscFlags)84 WMErrCode WMi_EnableEx(WMCallbackFunc callback, u32 miscFlags)
85 {
86     WMErrCode result;
87 
88     // Cannot execute if not in READY state
89     result = WMi_CheckState(WM_STATE_READY);
90     WM_CHECK_RESULT(result);
91 
92     // Register callback function
93     WMi_SetCallbackTable(WM_APIID_ENABLE, callback);
94 
95     // Register a callback to prohibit sleeping during communications.
96     WMi_RegisterSleepCallback();
97 
98     // Notify ARM7 with FIFO
99     {
100         WMArm9Buf *p = WMi_GetSystemWork();
101 
102         result = WMi_SendCommand(WM_APIID_ENABLE, 4,
103                                  (u32)(p->WM7), (u32)(p->status), (u32)(p->fifo7to9), miscFlags);
104         WM_CHECK_RESULT(result);
105     }
106 
107     // Normal end
108     return WM_ERRCODE_OPERATING;
109 }
110 
111 /*---------------------------------------------------------------------------*
112   Name:         WM_Disable
113 
114   Description:  Changes the wireless hardware to the use prohibited state.
115                 Internal state changes from STOP state to READY state.
116 
117   Arguments:    callback    -   Callback function that is called when the asynchronous process completes.
118 
119   Returns:      WMErrCode   -   Returns the processing result. Returns WM_ERRCODE_OPERATING if asynchronous processing started successfully. Afterwards, the asynchronous processing results will be passed to the callback.
120 
121 
122  *---------------------------------------------------------------------------*/
WM_Disable(WMCallbackFunc callback)123 WMErrCode WM_Disable(WMCallbackFunc callback)
124 {
125     WMErrCode result;
126 
127     // Cannot execute if not in STOP state
128     result = WMi_CheckState(WM_STATE_STOP);
129     WM_CHECK_RESULT(result);
130 
131     // Register callback function
132     WMi_SetCallbackTable(WM_APIID_DISABLE, callback);
133 
134     // Notify ARM7 with FIFO
135     result = WMi_SendCommand(WM_APIID_DISABLE, 0);
136     WM_CHECK_RESULT(result);
137 
138     return WM_ERRCODE_OPERATING;
139 }
140 
141 /*---------------------------------------------------------------------------*
142   Name:         WM_PowerOn
143 
144   Description:  Starts up the wireless hardware.
145                 Internal state changes from STOP state to IDLE state.
146 
147   Arguments:    callback    -   Callback function that is called when the asynchronous process completes.
148 
149   Returns:      WMErrCode   -   Returns the processing result. Returns WM_ERRCODE_OPERATING if asynchronous processing started successfully. Afterwards, the asynchronous processing results will be passed to the callback.
150 
151 
152  *---------------------------------------------------------------------------*/
WM_PowerOn(WMCallbackFunc callback)153 WMErrCode WM_PowerOn(WMCallbackFunc callback)
154 {
155     WMErrCode result;
156 
157     // Cannot execute if not in STOP state
158     result = WMi_CheckState(WM_STATE_STOP);
159     WM_CHECK_RESULT(result);
160 
161     // Register callback function
162     WMi_SetCallbackTable(WM_APIID_POWER_ON, callback);
163 
164     // Notify ARM7 with FIFO
165     result = WMi_SendCommand(WM_APIID_POWER_ON, 0);
166     WM_CHECK_RESULT(result);
167 
168     return WM_ERRCODE_OPERATING;
169 }
170 
171 /*---------------------------------------------------------------------------*
172   Name:         WM_PowerOff
173 
174   Description:  Shuts down the wireless hardware.
175                 Internal state changes from IDLE state to STOP state.
176 
177   Arguments:    callback    -   Callback function that is called when the asynchronous process completes.
178 
179   Returns:      WMErrCode   -   Returns the processing result. Returns WM_ERRCODE_OPERATING if asynchronous processing started successfully. Afterwards, the asynchronous processing results will be passed to the callback.
180 
181 
182  *---------------------------------------------------------------------------*/
WM_PowerOff(WMCallbackFunc callback)183 WMErrCode WM_PowerOff(WMCallbackFunc callback)
184 {
185     WMErrCode result;
186 
187     // Cannot execute if not in IDLE state.
188     result = WMi_CheckState(WM_STATE_IDLE);
189     WM_CHECK_RESULT(result);
190 
191     // Register callback function
192     WMi_SetCallbackTable(WM_APIID_POWER_OFF, callback);
193 
194     // Notify ARM7 with FIFO
195     result = WMi_SendCommand(WM_APIID_POWER_OFF, 0);
196     WM_CHECK_RESULT(result);
197 
198     return WM_ERRCODE_OPERATING;
199 }
200 
201 /*---------------------------------------------------------------------------*
202   Name:         WM_Initialize
203 
204   Description:  Performs the WM initialization process.
205 
206   Arguments:    wmSysBuf    -   Pointer to the buffer allocated by the caller.
207                                 Only as much as WM_SYSTEM_BUF_SIZE is required for buffer size.
208                 callback    -   Callback function that is called when the asynchronous process completes.
209                 dmaNo       -   DMA number used by WM
210 
211   Returns:      WMErrCode   -   Returns the processing result. Returns WM_ERRCODE_OPERATING if asynchronous processing started successfully. Afterwards, the asynchronous processing results will be passed to the callback.
212 
213 
214  *---------------------------------------------------------------------------*/
WM_Initialize(void * wmSysBuf,WMCallbackFunc callback,u16 dmaNo)215 WMErrCode WM_Initialize(void *wmSysBuf, WMCallbackFunc callback, u16 dmaNo)
216 {
217     return WMi_InitializeEx(wmSysBuf, callback, dmaNo, 0);
218 }
219 
220 /*---------------------------------------------------------------------------*
221   Name:         WM_InitializeForListening
222 
223   Description:  Performs the WM initialization process.
224                 Operations that require sending radio signals are not available.
225 
226   Arguments:    wmSysBuf    -   Pointer to the buffer allocated by the caller.
227                                 Only as much as WM_SYSTEM_BUF_SIZE is required for buffer size.
228                 callback    -   Callback function that is called when the asynchronous process completes.
229                 dmaNo       -   DMA number used by WM
230                 blink       -   Whether to flash the LED
231 
232   Returns:      WMErrCode   -   Returns the processing result.
233                                 Returns WM_ERRCODE_OPERATING if asynchronous processing started successfully. Afterwards, the asynchronous processing results will be passed to the callback.
234 
235  *---------------------------------------------------------------------------*/
WM_InitializeForListening(void * wmSysBuf,WMCallbackFunc callback,u16 dmaNo,BOOL blink)236 WMErrCode WM_InitializeForListening(void *wmSysBuf, WMCallbackFunc callback, u16 dmaNo, BOOL blink)
237 {
238     u32 miscFlags = WM_MISC_FLAG_LISTEN_ONLY;
239 
240     if (!blink)
241     {
242         miscFlags |= WM_MISC_FLAG_NO_BLINK;
243     }
244 
245     return WMi_InitializeEx(wmSysBuf, callback, dmaNo, miscFlags);
246 }
247 
248 /*---------------------------------------------------------------------------*
249   Name:         WMi_InitializeEx
250 
251   Description:  Performs the WM initialization process.
252 
253   Arguments:    wmSysBuf    -   Pointer to the buffer allocated by the caller.
254                                 Only as much as WM_SYSTEM_BUF_SIZE is required for buffer size.
255                 callback    -   Callback function that is called when the asynchronous process completes.
256                 dmaNo       -   DMA number used by WM
257                 miscFlags   -   Flags during initialization
258 
259   Returns:      WMErrCode   -   Returns the processing result.
260                                 Returns WM_ERRCODE_OPERATING if asynchronous processing started successfully. Afterwards, the asynchronous processing results will be passed to the callback.
261 
262  *---------------------------------------------------------------------------*/
WMi_InitializeEx(void * wmSysBuf,WMCallbackFunc callback,u16 dmaNo,u32 miscFlags)263 WMErrCode WMi_InitializeEx(void *wmSysBuf, WMCallbackFunc callback, u16 dmaNo, u32 miscFlags)
264 {
265     WMErrCode result;
266 
267     // Execute the initialization
268     result = WM_Init(wmSysBuf, dmaNo);
269     WM_CHECK_RESULT(result);
270 
271     // Register callback function
272     WMi_SetCallbackTable(WM_APIID_INITIALIZE, callback);
273 
274     // Register a callback to prohibit sleeping during communications.
275     WMi_RegisterSleepCallback();
276 
277     // Notify ARM7 with FIFO
278     {
279         WMArm9Buf *p = WMi_GetSystemWork();
280 
281         result = WMi_SendCommand(WM_APIID_INITIALIZE, 4,
282                                  (u32)(p->WM7), (u32)(p->status), (u32)(p->fifo7to9), miscFlags);
283         WM_CHECK_RESULT(result);
284     }
285 
286     // Normal end
287     return WM_ERRCODE_OPERATING;
288 }
289 
290 /*---------------------------------------------------------------------------*
291   Name:         WM_Reset
292 
293   Description:  Resets the wireless library, and restores the state immediately after the initialization.
294 
295   Arguments:    callback    -   Callback function that is called when the asynchronous process completes.
296 
297   Returns:      WMErrCode   -   Returns the processing result. Returns WM_ERRCODE_OPERATING if asynchronous processing started successfully. Afterwards, the asynchronous processing results will be passed to the callback.
298 
299 
300  *---------------------------------------------------------------------------*/
WM_Reset(WMCallbackFunc callback)301 WMErrCode WM_Reset(WMCallbackFunc callback)
302 {
303     WMErrCode result;
304 
305     // Confirm that wireless hardware has started
306     result = WMi_CheckIdle();
307     WM_CHECK_RESULT(result);
308 
309     // Register callback function
310     WMi_SetCallbackTable(WM_APIID_RESET, callback);
311 
312     // Notify ARM7 with FIFO
313     result = WMi_SendCommand(WM_APIID_RESET, 0);
314     WM_CHECK_RESULT(result);
315 
316     return WM_ERRCODE_OPERATING;
317 }
318 
319 /*---------------------------------------------------------------------------*
320   Name:         WM_End
321 
322   Description:  Closes the wireless library.
323 
324   Arguments:    callback    -   Callback function that is called when the asynchronous process completes.
325 
326   Returns:      WMErrCode   -   Returns the processing result. Returns WM_ERRCODE_OPERATING if asynchronous processing started successfully. Afterwards, the asynchronous processing results will be passed to the callback.
327 
328 
329  *---------------------------------------------------------------------------*/
WM_End(WMCallbackFunc callback)330 WMErrCode WM_End(WMCallbackFunc callback)
331 {
332     WMErrCode result;
333 
334     // Cannot execute if not in IDLE state.
335     result = WMi_CheckState(WM_STATE_IDLE);
336     WM_CHECK_RESULT(result);
337 
338     // Register callback function
339     WMi_SetCallbackTable(WM_APIID_END, callback);
340 
341     // Notify ARM7 with FIFO
342     result = WMi_SendCommand(WM_APIID_END, 0);
343     WM_CHECK_RESULT(result);
344 
345     // On the ARM9 side, perform the processing for ending the WM library inside the callback.
346 
347     return WM_ERRCODE_OPERATING;
348 }
349 
350 /*---------------------------------------------------------------------------*
351   Name:         WM_SetParentParameter
352 
353   Description:  Sets the parent device information.
354 
355   Arguments:    callback    -   Callback function that is called when the asynchronous process completes.
356                 pparaBuf    -   Pointer to the structure that indicates the parent information.
357                                 Note that the pparaBuf and pparaBuf->userGameInfo objects will be forcibly stored in the cache.
358 
359 
360   Returns:      WMErrCode   -   Returns the processing result. Returns WM_ERRCODE_OPERATING if asynchronous processing started successfully. Afterwards, the asynchronous processing results will be passed to the callback.
361 
362 
363  *---------------------------------------------------------------------------*/
WM_SetParentParameter(WMCallbackFunc callback,const WMParentParam * pparaBuf)364 WMErrCode WM_SetParentParameter(WMCallbackFunc callback, const WMParentParam *pparaBuf)
365 {
366     WMErrCode result;
367 
368     // Cannot execute if not in IDLE state.
369     result = WMi_CheckState(WM_STATE_IDLE);
370     WM_CHECK_RESULT(result);
371 
372     #ifdef SDK_TWL // Return an error if the TWL System Settings are configured not to use wireless.
373     if( OS_IsRunOnTwl() )
374     {
375         if( WMi_CheckEnableFlag() == FALSE )
376         {
377             return WM_ERRCODE_WM_DISABLE;
378         }
379     }
380     #endif
381 
382     // Check parameters
383     if (pparaBuf == NULL)
384     {
385         WM_WARNING("Parameter \"pparaBuf\" must not be NULL.\n");
386         return WM_ERRCODE_INVALID_PARAM;
387     }
388     if ((u32)pparaBuf & 0x01f)
389     {
390         // Alignment check is a warning only, not an error
391         WM_WARNING("Parameter \"pparaBuf\" is not 32-byte aligned.\n");
392     }
393     if (pparaBuf->userGameInfoLength > 0)
394     {
395         if (pparaBuf->userGameInfo == NULL)
396         {
397             WM_WARNING("Parameter \"pparaBuf->userGameInfo\" must not be NULL.\n");
398             return WM_ERRCODE_INVALID_PARAM;
399         }
400         if ((u32)(pparaBuf->userGameInfo) & 0x01f)
401         {
402             // Alignment check is a warning only, not an error
403             WM_WARNING("Parameter \"pparaBuf->userGameInfo\" is not 32-byte aligned.\n");
404         }
405     }
406 
407     // Check maximum data transfer length
408     if ((pparaBuf->parentMaxSize +
409          (pparaBuf->KS_Flag ? WM_SIZE_KS_PARENT_DATA + WM_SIZE_MP_PARENT_PADDING : 0) >
410          WM_SIZE_MP_DATA_MAX)
411         || (pparaBuf->childMaxSize +
412             (pparaBuf->KS_Flag ? WM_SIZE_KS_CHILD_DATA + WM_SIZE_MP_CHILD_PADDING : 0) >
413             WM_SIZE_MP_DATA_MAX))
414     {
415         WM_WARNING("Transfer data size is over %d byte.\n", WM_SIZE_MP_DATA_MAX);
416         return WM_ERRCODE_INVALID_PARAM;
417     }
418     (void)WmCheckParentParameter(pparaBuf);
419 
420     // Register callback function
421     WMi_SetCallbackTable(WM_APIID_SET_P_PARAM, callback);
422 
423     // Write out the specified buffer's cache
424     DC_StoreRange((void *)pparaBuf, WM_PARENT_PARAM_SIZE);
425     if (pparaBuf->userGameInfoLength > 0)
426     {
427         DC_StoreRange(pparaBuf->userGameInfo, pparaBuf->userGameInfoLength);
428     }
429 
430     // Notify ARM7 with FIFO
431     result = WMi_SendCommand(WM_APIID_SET_P_PARAM, 1, (u32)pparaBuf);
432     WM_CHECK_RESULT(result);
433 
434     return WM_ERRCODE_OPERATING;
435 }
436 
437 /*---------------------------------------------------------------------------*
438   Name:         WmCheckParentParameter
439 
440   Description:  This is a debugging function that checks whether parameters for the parent settings fall within the admissible range given by the guidelines.
441 
442 
443   Arguments:    param:       Pointer to parent settings parameters to check.
444 
445   Returns:      BOOL:        Returns TRUE if no problems, or FALSE if settings values are not admissible.
446 
447  *---------------------------------------------------------------------------*/
WmCheckParentParameter(const WMParentParam * param)448 static BOOL WmCheckParentParameter(const WMParentParam *param)
449 {
450     // User game information can be up to 112 bytes
451     if (param->userGameInfoLength > WM_SIZE_USER_GAMEINFO)
452     {
453         OS_TWarning("User gameInfo length must be less than %d .\n", WM_SIZE_USER_GAMEINFO);
454         return FALSE;
455     }
456     // Beacon transmission interval from 10 to 1000
457     if ((param->beaconPeriod < 10) || (param->beaconPeriod > 1000))
458     {
459         OS_TWarning("Beacon send period must be between 10 and 1000 .\n");
460         return FALSE;
461     }
462     // Connection channels are 1 to 14
463     if ((param->channel < 1) || (param->channel > 14))
464     {
465         OS_TWarning("Channel must be between 1 and 14 .\n");
466         return FALSE;
467     }
468     return TRUE;
469 }
470 
471 /*---------------------------------------------------------------------------*
472   Name:         WMi_StartParentEx
473 
474   Description:  Starts the communication as parent device.
475 
476   Arguments:    callback    -   Callback function that is called when the asynchronous process completes.
477                 powerSave   -   When using power save mode, TRUE. When not using it, FALSE.
478 
479   Returns:      WMErrCode   -   Returns the processing result. Returns WM_ERRCODE_OPERATING if asynchronous processing started successfully. Afterwards, the asynchronous processing results will be passed to the callback.
480 
481 
482  *---------------------------------------------------------------------------*/
WMi_StartParentEx(WMCallbackFunc callback,BOOL powerSave)483 WMErrCode WMi_StartParentEx(WMCallbackFunc callback, BOOL powerSave)
484 {
485     WMErrCode result;
486 
487     // Cannot execute if not in IDLE state.
488     result = WMi_CheckState(WM_STATE_IDLE);
489     WM_CHECK_RESULT(result);
490 
491     #ifdef SDK_TWL // Return an error if the TWL System Settings are configured not to use wireless.
492     if( OS_IsRunOnTwl() )
493     {
494         if( WMi_CheckEnableFlag() == FALSE )
495         {
496             return WM_ERRCODE_WM_DISABLE;
497         }
498     }
499     #endif
500 
501     {
502         WMArm9Buf *w9b = WMi_GetSystemWork();
503 #ifdef WM_DEBUG
504         if (w9b->connectedAidBitmap != 0)
505         {
506             WM_DPRINTF("Warning: connectedAidBitmap should be 0, but %04x",
507                        w9b->connectedAidBitmap);
508         }
509 #endif
510         w9b->myAid = 0;
511         w9b->connectedAidBitmap = 0;
512     }
513 
514     // Register callback function
515     WMi_SetCallbackTable(WM_APIID_START_PARENT, callback);
516 
517     // Notify ARM7 with FIFO
518     result = WMi_SendCommand(WM_APIID_START_PARENT, 1, (u32)powerSave);
519     WM_CHECK_RESULT(result);
520 
521     return WM_ERRCODE_OPERATING;
522 }
523 
524 /*---------------------------------------------------------------------------*
525   Name:         WM_StartParent
526 
527   Description:  Starts the communication as parent device.
528 
529   Arguments:    callback    -   Callback function that is called when the asynchronous process completes.
530 
531   Returns:      WMErrCode   -   Returns the processing result. Returns WM_ERRCODE_OPERATING if asynchronous processing started successfully. Afterwards, the asynchronous processing results will be passed to the callback.
532 
533 
534  *---------------------------------------------------------------------------*/
WM_StartParent(WMCallbackFunc callback)535 WMErrCode WM_StartParent(WMCallbackFunc callback)
536 {
537     return WMi_StartParentEx(callback, TRUE);
538 }
539 
540 /*---------------------------------------------------------------------------*
541   Name:         WM_EndParent
542 
543   Description:  Stops the communication as a parent.
544 
545   Arguments:    callback    -   Callback function that is called when the asynchronous process completes.
546 
547   Returns:      WMErrCode   -   Returns the processing result. Returns WM_ERRCODE_OPERATING if asynchronous processing started successfully. Afterwards, the asynchronous processing results will be passed to the callback.
548 
549 
550  *---------------------------------------------------------------------------*/
WM_EndParent(WMCallbackFunc callback)551 WMErrCode WM_EndParent(WMCallbackFunc callback)
552 {
553     WMErrCode result;
554 
555     // Cannot execute if not in PARENT state
556     result = WMi_CheckState(WM_STATE_PARENT);
557     WM_CHECK_RESULT(result);
558 
559     // Register callback function
560     WMi_SetCallbackTable(WM_APIID_END_PARENT, callback);
561 
562     // Notify ARM7 with FIFO
563     result = WMi_SendCommand(WM_APIID_END_PARENT, 0);
564     WM_CHECK_RESULT(result);
565 
566     return WM_ERRCODE_OPERATING;
567 }
568 
569 /*---------------------------------------------------------------------------*
570   Name:         WM_StartScan
571 
572   Description:  As a child device, starts scanning for a parent device.
573                 Obtains one device's parent information with each call.
574                 It can be called repeatedly without calling WM_EndScan.
575 
576   Arguments:    callback    -   Callback function that is called when the asynchronous process completes.
577                 param       -   Pointer to the structure that shows the scan information.
578                                 The ARM7 directly writes scan result information to param->scanBuf, so it must match the cache line.
579 
580 
581   Returns:      WMErrCode   -   Returns the processing result. Returns WM_ERRCODE_OPERATING if asynchronous processing started successfully. Afterwards, the asynchronous processing results will be passed to the callback.
582 
583 
584  *---------------------------------------------------------------------------*/
WM_StartScan(WMCallbackFunc callback,const WMScanParam * param)585 WMErrCode WM_StartScan(WMCallbackFunc callback, const WMScanParam *param)
586 {
587     WMErrCode result;
588 
589     // Not executable outside of IDLE CALSS1 SCAN state
590     result = WMi_CheckStateEx(3, WM_STATE_IDLE, WM_STATE_CLASS1, WM_STATE_SCAN);
591     WM_CHECK_RESULT(result);
592 
593     #ifdef SDK_TWL // Return an error if the TWL System Settings are configured not to use wireless.
594     if( OS_IsRunOnTwl() )
595     {
596         if( WMi_CheckEnableFlag() == FALSE )
597         {
598             return WM_ERRCODE_WM_DISABLE;
599         }
600     }
601     #endif
602 
603     // Check parameters
604     if (param == NULL)
605     {
606         WM_WARNING("Parameter \"param\" must not be NULL.\n");
607         return WM_ERRCODE_INVALID_PARAM;
608     }
609     if (param->scanBuf == NULL)
610     {
611         WM_WARNING("Parameter \"param->scanBuf\" must not be NULL.\n");
612         return WM_ERRCODE_INVALID_PARAM;
613     }
614     if ((param->channel < 1) || (param->channel > 14))
615     {
616         WM_WARNING("Parameter \"param->channel\" must be between 1 and 14.\n");
617         return WM_ERRCODE_INVALID_PARAM;
618     }
619     if ((u32)(param->scanBuf) & 0x01f)
620     {
621         // Alignment check is a warning only, not an error
622         WM_WARNING("Parameter \"param->scanBuf\" is not 32-byte aligned.\n");
623     }
624 
625     // Register callback function
626     WMi_SetCallbackTable(WM_APIID_START_SCAN, callback);
627 
628     // Notify ARM7 with FIFO
629     {
630         WMStartScanReq Req;
631 
632         Req.apiid = WM_APIID_START_SCAN;
633         Req.channel = param->channel;
634         Req.scanBuf = param->scanBuf;
635         Req.maxChannelTime = param->maxChannelTime;
636         Req.bssid[0] = param->bssid[0];
637         Req.bssid[1] = param->bssid[1];
638         Req.bssid[2] = param->bssid[2];
639         Req.bssid[3] = param->bssid[3];
640         Req.bssid[4] = param->bssid[4];
641         Req.bssid[5] = param->bssid[5];
642         result = WMi_SendCommandDirect(&Req, sizeof(Req));
643         WM_CHECK_RESULT(result);
644     }
645 
646     return WM_ERRCODE_OPERATING;
647 }
648 
649 /*---------------------------------------------------------------------------*
650   Name:         WM_StartScanEx
651 
652   Description:  As a child device, starts scanning for a parent device.
653                 Obtains multiple devices' parent information with one call.
654                 It can be called repeatedly without calling WM_EndScan.
655 
656   Arguments:    callback    -   Callback function that is called when the asynchronous process completes.
657                 param       -   Pointer to the structure that shows the scan information.
658                            The ARM7 directly writes scan result information to param->scanBuf, so it must match the cache line.
659 
660 
661   Returns:      int:       Returns WM_ERRCODE_* type processing results.
662  *---------------------------------------------------------------------------*/
WM_StartScanEx(WMCallbackFunc callback,const WMScanExParam * param)663 WMErrCode WM_StartScanEx(WMCallbackFunc callback, const WMScanExParam *param)
664 {
665     WMErrCode result;
666 
667     // Not executable outside of IDLE CALSS1 SCAN state
668     result = WMi_CheckStateEx(3, WM_STATE_IDLE, WM_STATE_CLASS1, WM_STATE_SCAN);
669     WM_CHECK_RESULT(result);
670 
671     #ifdef SDK_TWL // Return an error if the TWL System Settings are configured not to use wireless.
672     if( OS_IsRunOnTwl() )
673     {
674         if( WMi_CheckEnableFlag() == FALSE )
675         {
676             return WM_ERRCODE_WM_DISABLE;
677         }
678     }
679     #endif
680 
681     // Check parameters
682     if (param == NULL)
683     {
684         WM_WARNING("Parameter \"param\" must not be NULL.\n");
685         return WM_ERRCODE_INVALID_PARAM;
686     }
687     if (param->scanBuf == NULL)
688     {
689         WM_WARNING("Parameter \"param->scanBuf\" must not be NULL.\n");
690         return WM_ERRCODE_INVALID_PARAM;
691     }
692     if (param->scanBufSize > WM_SIZE_SCAN_EX_BUF)
693     {
694         WM_WARNING
695             ("Parameter \"param->scanBufSize\" must be less than or equal to WM_SIZE_SCAN_EX_BUF.\n");
696         return WM_ERRCODE_INVALID_PARAM;
697     }
698     if ((u32)(param->scanBuf) & 0x01f)
699     {
700         // Alignment check is a warning only, not an error
701         WM_WARNING("Parameter \"param->scanBuf\" is not 32-byte aligned.\n");
702     }
703     if (param->ssidLength > WM_SIZE_SSID)
704     {
705         WM_WARNING("Parameter \"param->ssidLength\" must be less than or equal to WM_SIZE_SSID.\n");
706         return WM_ERRCODE_INVALID_PARAM;
707     }
708     if (param->scanType != WM_SCANTYPE_ACTIVE && param->scanType != WM_SCANTYPE_PASSIVE
709         && param->scanType != WM_SCANTYPE_ACTIVE_CUSTOM
710         && param->scanType != WM_SCANTYPE_PASSIVE_CUSTOM)
711     {
712         WM_WARNING
713             ("Parameter \"param->scanType\" must be WM_SCANTYPE_PASSIVE or WM_SCANTYPE_ACTIVE.\n");
714         return WM_ERRCODE_INVALID_PARAM;
715     }
716     if ((param->scanType == WM_SCANTYPE_ACTIVE_CUSTOM
717          || param->scanType == WM_SCANTYPE_PASSIVE_CUSTOM) && param->ssidMatchLength > WM_SIZE_SSID)
718     {
719         WM_WARNING
720             ("Parameter \"param->ssidMatchLength\" must be less than or equal to WM_SIZE_SSID.\n");
721         return WM_ERRCODE_INVALID_PARAM;
722     }
723 
724     // Register callback function
725     WMi_SetCallbackTable(WM_APIID_START_SCAN_EX, callback);
726 
727     // Notify ARM7 with FIFO
728     {
729         WMStartScanExReq Req;
730 
731         Req.apiid = WM_APIID_START_SCAN_EX;
732         Req.channelList = param->channelList;
733         Req.scanBuf = param->scanBuf;
734         Req.scanBufSize = param->scanBufSize;
735         Req.maxChannelTime = param->maxChannelTime;
736         MI_CpuCopy8(param->bssid, Req.bssid, WM_SIZE_MACADDR);
737         Req.scanType = param->scanType;
738         Req.ssidMatchLength = param->ssidMatchLength;
739         Req.ssidLength = param->ssidLength;
740         MI_CpuCopy8(param->ssid, Req.ssid, WM_SIZE_SSID);
741 
742         result = WMi_SendCommandDirect(&Req, sizeof(Req));
743         WM_CHECK_RESULT(result);
744     }
745 
746     return WM_ERRCODE_OPERATING;
747 }
748 
749 /*---------------------------------------------------------------------------*
750   Name:         WM_EndScan
751 
752   Description:  Stops the scan process as a child device.
753 
754   Arguments:    callback    -   Callback function that is called when the asynchronous process completes.
755 
756   Returns:      WMErrCode   -   Returns the processing result. Returns WM_ERRCODE_OPERATING if asynchronous processing started successfully. Afterwards, the asynchronous processing results will be passed to the callback.
757 
758 
759  *---------------------------------------------------------------------------*/
WM_EndScan(WMCallbackFunc callback)760 WMErrCode WM_EndScan(WMCallbackFunc callback)
761 {
762     WMErrCode result;
763 
764     // Cannot execute if not in SCAN state
765     result = WMi_CheckState(WM_STATE_SCAN);
766     WM_CHECK_RESULT(result);
767 
768     // Register callback function
769     WMi_SetCallbackTable(WM_APIID_END_SCAN, callback);
770 
771     // Notify ARM7 with FIFO
772     result = WMi_SendCommand(WM_APIID_END_SCAN, 0);
773     WM_CHECK_RESULT(result);
774 
775     return WM_ERRCODE_OPERATING;
776 }
777 
778 /*---------------------------------------------------------------------------*
779   Name:         WM_StartConnectEx
780 
781   Description:  Starts the connection to the parent as a child device.
782 
783   Arguments:    callback    -   Callback function that is called when the asynchronous process completes.
784                 pInfo       -   Information of the parent to connect to.
785                                 Specifies the structure obtained with WM_StartScan.
786                                 Note that this structure is forcibly stored in the cache.
787 
788                 ssid        -   Child information to notify to the parent (24Byte(WM_SIZE_CHILD_SSID) fixed size)
789                 powerSave   -   When using power save mode, TRUE. When not using it, FALSE.
790                 authMode    -   Authentication mode selection.
791                                   WM_AUTHMODE_OPEN_SYSTEM : OPEN SYSTEM mode
792                                   WM_AUTHMODE_SHARED_KEY  : SHARED KEY mode
793 
794   Returns:      WMErrCode   -   Returns the processing result. Returns WM_ERRCODE_OPERATING if asynchronous processing started successfully. Afterwards, the asynchronous processing results will be passed to the callback.
795 
796 
797  *---------------------------------------------------------------------------*/
798 WMErrCode
WM_StartConnectEx(WMCallbackFunc callback,const WMBssDesc * pInfo,const u8 * ssid,BOOL powerSave,const u16 authMode)799 WM_StartConnectEx(WMCallbackFunc callback, const WMBssDesc *pInfo, const u8 *ssid,
800                   BOOL powerSave, const u16 authMode)
801 {
802     WMErrCode result;
803 
804     // Cannot execute if not in IDLE state.
805     result = WMi_CheckState(WM_STATE_IDLE);
806     WM_CHECK_RESULT(result);
807 
808     #ifdef SDK_TWL // Return an error if the TWL System Settings are configured not to use wireless.
809     if( OS_IsRunOnTwl() )
810     {
811         if( WMi_CheckEnableFlag() == FALSE )
812         {
813             return WM_ERRCODE_WM_DISABLE;
814         }
815     }
816     #endif
817 
818     // Check parameters
819     if (pInfo == NULL)
820     {
821         WM_WARNING("Parameter \"pInfo\" must not be NULL.\n");
822         return WM_ERRCODE_INVALID_PARAM;
823     }
824     if ((u32)pInfo & 0x01f)
825     {
826         // Alignment check is a warning only, not an error
827         WM_WARNING("Parameter \"pInfo\" is not 32-byte aligned.\n");
828     }
829     if ((authMode != WM_AUTHMODE_OPEN_SYSTEM) && (authMode != WM_AUTHMODE_SHARED_KEY))
830     {
831         WM_WARNING
832             ("Parameter \"authMode\" must be WM_AUTHMODE_OPEN_SYSTEM or WM_AUTHMODE_SHARED_KEY.\n");
833     }
834 
835     // Write out the specified buffer's cache
836     DC_StoreRange((void *)pInfo, (u32)(pInfo->length * 2));
837 
838     {
839         WMArm9Buf *w9b = WMi_GetSystemWork();
840 #ifdef WM_DEBUG
841         if (w9b->connectedAidBitmap != 0)
842         {
843             WM_DPRINTF("Warning: connectedAidBitmap should be 0, but %04x",
844                        w9b->connectedAidBitmap);
845         }
846 #endif
847         w9b->myAid = 0;
848         w9b->connectedAidBitmap = 0;
849     }
850 
851     // Register callback function
852     WMi_SetCallbackTable(WM_APIID_START_CONNECT, callback);
853 
854     // Notify ARM7 with FIFO
855     {
856         WMStartConnectReq Req;
857 
858         Req.apiid = WM_APIID_START_CONNECT;
859         Req.pInfo = (WMBssDesc *)pInfo;
860         if (ssid != NULL)
861         {
862             MI_CpuCopy8(ssid, Req.ssid, WM_SIZE_CHILD_SSID);
863         }
864         else
865         {
866             MI_CpuClear8(Req.ssid, WM_SIZE_CHILD_SSID);
867         }
868         Req.powerSave = powerSave;
869         Req.authMode = authMode;
870 
871         result = WMi_SendCommandDirect(&Req, sizeof(Req));
872         WM_CHECK_RESULT(result);
873     }
874 
875     return WM_ERRCODE_OPERATING;
876 }
877 
878 /*---------------------------------------------------------------------------*
879   Name:         WM_Disconnect
880 
881   Description:  Cuts off the connection that had been established.
882 
883   Arguments:    callback    -   Callback function that is called when the asynchronous process completes.
884                 aid         -   AID of the communication partner to be disconnected.
885                                 In the parent's case, individually disconnects children having IDs 1 - 15.
886                                 In the child's case, ends communication with the parent having ID 0.
887 
888   Returns:      WMErrCode   -   Returns the processing result.
889                                 Returns WM_ERRCODE_OPERATING if asynchronous processing started successfully. Afterwards, the asynchronous processing results will be passed to the callback.
890 
891  *---------------------------------------------------------------------------*/
WM_Disconnect(WMCallbackFunc callback,u16 aid)892 WMErrCode WM_Disconnect(WMCallbackFunc callback, u16 aid)
893 {
894     WMErrCode result;
895     WMArm9Buf *p = WMi_GetSystemWork();
896 
897     // Check the state
898     result = WMi_CheckStateEx(5,
899                               WM_STATE_PARENT, WM_STATE_MP_PARENT,
900                               WM_STATE_CHILD, WM_STATE_MP_CHILD, WM_STATE_DCF_CHILD);
901     WM_CHECK_RESULT(result);
902 
903     if (                               // p->status->state cache has been discarded
904            (p->status->state == WM_STATE_PARENT) || (p->status->state == WM_STATE_MP_PARENT))
905     {
906         // For parent
907         if ((aid < 1) || (aid > WM_NUM_MAX_CHILD))
908         {
909             WM_WARNING("Parameter \"aid\" must be between 1 and %d.\n", WM_NUM_MAX_CHILD);
910             return WM_ERRCODE_INVALID_PARAM;
911         }
912         DC_InvalidateRange(&(p->status->child_bitmap), 2);
913         if (!(p->status->child_bitmap & (0x0001 << aid)))
914         {
915             WM_WARNING("There is no child that have aid %d.\n", aid);
916             return WM_ERRCODE_NO_CHILD;
917         }
918     }
919     else
920     {
921         // For child
922         if (aid != 0)
923         {
924             WM_WARNING("Now child mode , so aid must be 0.\n");
925             return WM_ERRCODE_INVALID_PARAM;
926         }
927     }
928 
929     // Register callback function
930     WMi_SetCallbackTable(WM_APIID_DISCONNECT, callback);
931 
932     // Notify ARM7 with FIFO
933     result = WMi_SendCommand(WM_APIID_DISCONNECT, 1, (u32)(0x0001 << aid));
934     WM_CHECK_RESULT(result);
935 
936     return WM_ERRCODE_OPERATING;
937 }
938 
939 /*---------------------------------------------------------------------------*
940   Name:         WM_DisconnectChildren
941 
942   Description:  Disconnects the respective children with which the connection has been established. Function exclusively for parent use.
943 
944   Arguments:    callback    -   Callback function that is called when the asynchronous process completes.
945                 aidBitmap   -   AID bitfield of the children to be disconnected.
946                                 The lowest order bit will be ignored. Bits 1-15 indicate AID 1-15, respectively.
947                                 Bits that indicate disconnected child devices will be ignored, so specify 0xFFFF to disconnect all children regardless of their connection state.
948 
949 
950 
951   Returns:      WMErrCode   -   Returns the processing result.
952                                 Returns WM_ERRCODE_OPERATING if asynchronous processing started successfully. Afterwards, the asynchronous processing results will be passed to the callback.
953 
954  *---------------------------------------------------------------------------*/
WM_DisconnectChildren(WMCallbackFunc callback,u16 aidBitmap)955 WMErrCode WM_DisconnectChildren(WMCallbackFunc callback, u16 aidBitmap)
956 {
957     WMErrCode result;
958     WMArm9Buf *p = WMi_GetSystemWork();
959 
960     // Check the state
961     result = WMi_CheckStateEx(2, WM_STATE_PARENT, WM_STATE_MP_PARENT);
962     WM_CHECK_RESULT(result);
963 
964     // Check parameters
965     DC_InvalidateRange(&(p->status->child_bitmap), 2);
966     if (!(p->status->child_bitmap & aidBitmap & 0xfffe))
967     {
968         WM_WARNING("There is no child that is included in \"aidBitmap\" %04x_.\n", aidBitmap);
969         return WM_ERRCODE_NO_CHILD;
970     }
971 
972     // Register callback function
973     WMi_SetCallbackTable(WM_APIID_DISCONNECT, callback);
974 
975     // Notify ARM7 with FIFO
976     result = WMi_SendCommand(WM_APIID_DISCONNECT, 1, (u32)aidBitmap);
977     WM_CHECK_RESULT(result);
978 
979     return WM_ERRCODE_OPERATING;
980 }
981 
982 /*---------------------------------------------------------------------------*
983     End of file
984  *---------------------------------------------------------------------------*/
985