/*---------------------------------------------------------------------------*
  Project:  NitroSDK - WM - libraries
  File:     wm_etc.c

  Copyright 2003,2004 Nintendo.  All rights reserved.

  These coded instructions, statements, and computer programs contain
  proprietary information of Nintendo of America Inc. and/or Nintendo
  Company Ltd., and are protected by Federal copyright law.  They may
  not be disclosed to third parties or copied or duplicated in any form,
  in whole or in part, without the prior written consent of Nintendo.

  $Log: wm_etc.c,v $
  Revision 1.9  2004/11/17 07:30:24  terui
  In WM_SetGameInfo, revised MI_CpuCopy32to MI_CpuCopy16

  Revision 1.8  2004/11/09 00:03:44  seiki_masashi
  Implemented a timeout caused by a Null response.

  Revision 1.7  2004/11/02 07:27:14  terui
  Fixed comments.

  Revision 1.6  2004/10/22 04:37:28  terui
  Changed functions that returned int type as WMErrCode so that they return
  WMErrCode enumerator type.

  Revision 1.5  2004/10/18 11:09:16  terui
  Changed the WM_SetBeaconPeriod function to private.

  Revision 1.4  2004/10/04 13:40:25  terui
  Standardized the game group ID as u32 type

  Revision 1.3  2004/10/01 04:03:16  terui
  Modified so that the features can be restricted with the WM_ENABLE_TESTMODE switch

  Revision 1.2  2004/09/20 10:27:36  ooe
  Added WMSP_SetBeaconPeriod.

  Revision 1.1  2004/09/10 11:03:30  terui
  New upload reflecting breakup of wm.c.

  $NoKeywords: $
 *---------------------------------------------------------------------------*/

#include    <nitro/wm.h>
#include    "wm_arm9_private.h"


/*---------------------------------------------------------------------------*
    Constant definitions
 *---------------------------------------------------------------------------*/
#define     WM_SIZE_TEMP_USR_GAME_INFO_BUF 128


/*---------------------------------------------------------------------------*
    Internal variable definitions
 *---------------------------------------------------------------------------*/
static u32  tmpUserGameInfoBuf[ WM_SIZE_TEMP_USR_GAME_INFO_BUF / sizeof(u32) ]  ATTRIBUTE_ALIGN(32);


#ifdef  WM_ENABLE_TESTMODE
/*---------------------------------------------------------------------------*
  Name:         WM_StartTestMode

  Description:  Starts test mode communication.

  Arguments:    callback    -   Callback function called when asynchronous process ends.
                signal      -   0: no modulation (data=0), 1: no modulation (data=1), 2:PN15 grade,
                                3:01 pattern (with scrambling), 4:01 pattern (without scrambling)
                rate        -   1:1Mbps, 2:2Mbps
                channel     -   Specifies channel to send data (1-14).

  Returns:      WMErrCode   -   Returns process results. WM_ERRCODE_OPERATING is returned
  					when an asynchronous process started normally. After that, asynchronous
                                	process results are again passed to callback.
 *---------------------------------------------------------------------------*/
WMErrCode
WM_StartTestMode( WMCallbackFunc callback , u16 signal , u16 rate , u16 channel )
{
    WMErrCode   result;

    // Cannot run unless state is IDLE
    result = WMi_CheckState( WM_STATE_IDLE );
    WM_CHECK_RESULT( result );

    // Save the callback function
    WMi_SetCallbackTable( WM_APIID_START_TESTMODE , callback );

    // Notify ARM7 with FIFO
    {
        WMStartTestModeReq  *Req =
            (WMStartTestModeReq*)( WMi_GetSystemWork()->fifo9to7 );

        Req->apiid      = WM_APIID_START_TESTMODE;
        Req->signal     = signal;
        Req->rate       = rate;
        Req->channel    = channel;

        result = WMi_SendCommand( WM_APIID_START_TESTMODE , 0 );
        if( result != WM_ERRCODE_SUCCESS )
        {
            return result;
        }
    }

    return WM_ERRCODE_OPERATING;
}

/*---------------------------------------------------------------------------*
  Name:         WM_StopTestMode

  Description:  Stops communication in test mode.

  Arguments:    callback    -   Callback function called when asynchronous process ends.

  Returns:      WMErrCode   -   Returns process results. WM_ERRCODE_OPERATING is returned
  						when asynchronous process started normally. After that, results
  						of asynchronous process are again passed to callback.
 *---------------------------------------------------------------------------*/
WMErrCode
WM_StopTestMode( WMCallbackFunc callback )
{
    WMErrCode   result;

    // Cannot run unless state is TESTMODE
    result = WMi_CheckState( WM_STATE_TESTMODE );
    WM_CHECK_RESULT( result );

    // Save the callback function
    WMi_SetCallbackTable( WM_APIID_STOP_TESTMODE , callback );

    // Notify ARM7 with FIFO
    result = WMi_SendCommand( WM_APIID_STOP_TESTMODE , 0 );
    WM_CHECK_RESULT( result );

    return WM_ERRCODE_OPERATING;
}
#endif

/*---------------------------------------------------------------------------*
  Name:         WM_SetWEPKey

  Description:  Sets code functions and code keys.

  Arguments:    callback    -   The callback function called when asynchronous process ends.
                wepmode     -   0: no code function
                                1: RC4(40bit) code mode
                                2: RC4(104bit) code mode
                                3: RC4(128bit) code mode
                wepkey      -   pointer to code key data ( 80 byte ).
                                Key data is composed of four data that are 20 bytes each.
                                Of each 20 bytes, the following data is used:
                                 5 bytes in 40 bit mode
                                13 bytes in 104 bit mode
                                16 bytes in 128 bit mode

                                Also, this data is forcibly cache stored.

  Returns:      WMErrCode   -   Returns process results. WM_ERRCODE_OPERATING is returned
  						when asynchronous process was started normally. After that, the results
  						of the asynchronous process is again passed to the callback.

 *---------------------------------------------------------------------------*/
WMErrCode
WM_SetWEPKey( WMCallbackFunc callback , u16 wepmode , const u16* wepkey )
{
    WMErrCode   result;

    // Confirm that wireless hardware is running
    result = WMi_CheckIdle();
    WM_CHECK_RESULT( result );

    // Check parameters
    if( wepmode > 3 )
    {
        WM_WARNING( "Parameter \"wepmode\" must be less than %d.\n" , 3 );
        return WM_ERRCODE_INVALID_PARAM;
    }

    // Save the callback function
    WMi_SetCallbackTable( WM_APIID_SET_WEPKEY , callback );

    // Notify ARM7 with FIFO
    result = WMi_SendCommand(
        WM_APIID_SET_WEPKEY , 2 ,
        (u32)wepmode ,
        (u32)wepkey
    );
    WM_CHECK_RESULT( result );

    return WM_ERRCODE_OPERATING;
}

/*---------------------------------------------------------------------------*
  Name:         WM_SetGameInfo

  Description:  Sets game information. Initial value is set by WM_SetParentParameter, so
                use when changing this.

  Arguments:    callback    -   The callback function called when asynchronous process ends.
                gameInfo    -   pointer to user game information
                gameInfoSize -  size of user game information
                ggid        -   game group ID
                tgid        -   temporary group ID
                attr        -   Flag group. Set the following flag logical sums.
                                    WM_ATTR_FLAG_ENTRY - entry permitted
                                    WM_ATTR_FLAG_MB    - multiboot reception
                                    WM_ATTR_FLAG_KS    - key sharing
                                    WM_ATTR_FLAG_CS    - consecutive transfer mode
 Returns:      WMErrCode   -   Returns process results. WM_ERRCODE_OPERATING is returned
  						when asynchronous process was started normally. After that, the results
  						of the asynchronous process is again passed to the callback.
 *---------------------------------------------------------------------------*/
WMErrCode
WM_SetGameInfo( WMCallbackFunc callback , const u16* gameInfo , u16 gameInfoSize , u32 ggid, u16 tgid, u8 attr )
{
    WMErrCode   result;

    // Confirm status as active parent
    result = WMi_CheckStateEx( 2 , WM_STATE_PARENT , WM_STATE_MP_PARENT );
    WM_CHECK_RESULT( result );

    // Check parameters
    if( gameInfo == NULL )
    {
        WM_WARNING( "Parameter \"gameInfo\" must not be NULL.\n" );
        return WM_ERRCODE_INVALID_PARAM;
    }
    if( gameInfoSize > WM_SIZE_USER_GAMEINFO )
    {
        WM_WARNING( "Parameter \"gameInfoSize\" must be less than %d.\n" , WM_SIZE_USER_GAMEINFO );
        return WM_ERRCODE_INVALID_PARAM;
    }

    // Temporarily empty the specified buffer
    MI_CpuCopy16( (void*)gameInfo , (void*)tmpUserGameInfoBuf , gameInfoSize );
    DC_StoreRange( (void*)tmpUserGameInfoBuf , gameInfoSize );

    // Save the callback function
    WMi_SetCallbackTable( WM_APIID_SET_GAMEINFO , callback );

    // Notify ARM7 with FIFO
    result = WMi_SendCommand(
        WM_APIID_SET_GAMEINFO , 5 ,
        (u32)tmpUserGameInfoBuf ,
        (u32)gameInfoSize ,
        (u32)ggid ,
        (u32)tgid ,
        (u32)attr
    );
    if( result != WM_ERRCODE_SUCCESS )
    {
        return result;
    }

    return WM_ERRCODE_OPERATING;
}

/*---------------------------------------------------------------------------*
  Name:         WM_SetBeaconIndication

  Description:  Switches beacon send/receive indicate between valid/invalid.

  Arguments:    callback    -   The callback function called when asynchronous process ends.
                flag        -   0: invalid
                                1: valid

  Returns:      WMErrCode   -   Returns process results. WM_ERRCODE_OPERATING is returned
  						when asynchronous process was started normally. After that, the results
  						of the asynchronous process is again passed to the callback.
 *---------------------------------------------------------------------------*/
WMErrCode
WM_SetBeaconIndication( WMCallbackFunc callback, u16 flag )
{
    WMErrCode   result;

    // Confirm that wireless hardware is running
    result = WMi_CheckIdle();
    WM_CHECK_RESULT( result );

    // Check parameters
    if( (0 != flag) && (1 != flag) )
    {
        WM_WARNING( "Parameter \"flag\" must be \"0\" of \"1\".\n" );
        return WM_ERRCODE_INVALID_PARAM;
    }

    // Save the callback function
    WMi_SetCallbackTable( WM_APIID_SET_BEACON_IND , callback );

    // Notify ARM7 with FIFO
    result = WMi_SendCommand( WM_APIID_SET_BEACON_IND , 1 , (u32)flag );
    WM_CHECK_RESULT( result );

    return WM_ERRCODE_OPERATING;
}

/*---------------------------------------------------------------------------*
  Name:         WM_SetLifeTime

  Description:  Sets lifetime.

  Arguments:    callback    -   The callback function called when asynchronous process ends.
                tableNumber -   CAM table number that sets lifetime (0xFFFF and all tables)
                camLifeTime -   CAM lifetime (100ms units: invalid when 0xFFFF)
                frameLifeTime - lifetime beacon period of set frame (100ms units: invalid when 0xFFFF)
                mpLifeTime  -    MP communication lifetime (100ms units: 0xFFFF to disable)

  Returns:      WMErrCode   -   Returns process results. WM_ERRCODE_OPERATING is returned
  						when asynchronous process was started normally. After that, the results
  						of the asynchronous process is again passed to the callback.
 *---------------------------------------------------------------------------*/
WMErrCode
WM_SetLifeTime( WMCallbackFunc callback , u16 tableNumber, u16 camLifeTime, u16 frameLifeTime, u16 mpLifeTime )
{
    WMErrCode   result;

    // Confirm that wireless hardware is running
    result = WMi_CheckIdle();
    WM_CHECK_RESULT( result );

    // Save the callback function
    WMi_SetCallbackTable( WM_APIID_SET_LIFETIME , callback );

    // Notify ARM7 with FIFO
    result = WMi_SendCommand(
        WM_APIID_SET_LIFETIME , 4 ,
        (u32)tableNumber ,
        (u32)camLifeTime ,
        (u32)frameLifeTime ,
        (u32)mpLifeTime
    );
    WM_CHECK_RESULT( result );

    return WM_ERRCODE_OPERATING;
}

/*---------------------------------------------------------------------------*
  Name:         WM_MeasureChannel

  Description:  Measure channel usage.

  Arguments:    callback    -   The callback function called when asynchronous process ends.
                ccaMode     -   CCA operation mode
                                0: Carrier sense only. ED threshold is ignored.
                                1: Only ED threshold is valid.
                                2: Logical product of carrier sense and ED threshold.
                                3: Logical sum of carrier sense and ED threshold.
                EDThreshold -   ED threshold (0 - 61) -60dBm to -80dBm
                channel     -   channel to check (only one channel per one MeasureChannel)
                measureTime -   time to check

  Returns:      WMErrCode   -   Returns process results. WM_ERRCODE_OPERATING is returned
  						when asynchronous process was started normally. After that, the results
  						of the asynchronous process is again passed to the callback.
 *---------------------------------------------------------------------------*/
WMErrCode
WM_MeasureChannel( WMCallbackFunc callback , u16 ccaMode, u16 edThreshold, u16 channel, u16 measureTime )
{
    WMErrCode   result;
    WMArm9Buf*  p   = WMi_GetSystemWork();

    //  Cannot run unless state is IDLE
    result = WMi_CheckState( WM_STATE_IDLE );
    WM_CHECK_RESULT( result );

    // Save the callback function
    WMi_SetCallbackTable( WM_APIID_MEASURE_CHANNEL , callback );

    // Notify ARM7 with FIFO
    {
        WMMeasureChannelReq *Req = (WMMeasureChannelReq*)( p->fifo9to7 );

        Req->apiid          = WM_APIID_MEASURE_CHANNEL;
        Req->ccaMode        = ccaMode;
        Req->edThreshold    = edThreshold;
        Req->channel        = channel;
        Req->measureTime    = measureTime;

        result = WMi_SendCommand( WM_APIID_MEASURE_CHANNEL , 0 );
        WM_CHECK_RESULT( result );
    }
    return WM_ERRCODE_OPERATING;
}

/*---------------------------------------------------------------------------*
  Name:         WM_InitWirelessCounter

  Description:  Initializes WirelessCounter.

  Arguments:    callback    -   The callback function called when asynchronous process ends.

  Returns:      WMErrCode   -   Returns process results. WM_ERRCODE_OPERATING is returned
  						when asynchronous process was started normally. After that, the results
  						of the asynchronous process is again passed to the callback.
 *---------------------------------------------------------------------------*/
WMErrCode
WM_InitWirelessCounter( WMCallbackFunc callback )
{
    WMErrCode   result;

    // Confirm that wireless hardware is running
    result = WMi_CheckIdle();
    WM_CHECK_RESULT( result );

    // Save the callback function
    WMi_SetCallbackTable( WM_APIID_INIT_W_COUNTER , callback );

    // Notify ARM7 with FIFO
    result = WMi_SendCommand( WM_APIID_INIT_W_COUNTER , 0 );
    WM_CHECK_RESULT( result );

    return WM_ERRCODE_OPERATING;
}

/*---------------------------------------------------------------------------*
  Name:         WM_GetWirelessCounter

  Description:  Gets send/receive frame count and send/receive error frame count of Wireless NIC.

  Arguments:    callback    -   The callback function called when asynchronous process ends.

  Returns:      WMErrCode   -   Returns process results. WM_ERRCODE_OPERATING is returned
  						when asynchronous process was started normally. After that, the results
  						of the asynchronous process is again passed to the callback.
 *---------------------------------------------------------------------------*/
WMErrCode
WM_GetWirelessCounter( WMCallbackFunc callback )
{
    WMErrCode   result;

    // Confirm that wireless hardware is running
    result = WMi_CheckIdle();
    WM_CHECK_RESULT( result );

    // Save the callback function
    WMi_SetCallbackTable( WM_APIID_GET_W_COUNTER , callback );

    // Notify ARM7 with FIFO
    result = WMi_SendCommand( WM_APIID_GET_W_COUNTER , 0 );
    WM_CHECK_RESULT( result );

    return WM_ERRCODE_OPERATING;
}

/*---------------------------------------------------------------------------*
  Name:         WM_SetEntry

  Description:  Switches the availability of connection reception from child as parent.

  Arguments:    callback    -   The callback function called when asynchronous process ends.
                enabled     -   Entry permitted/not permitted flag. TRUE: permitted, FALSE: not permitted.

  Returns:      WMErrCode   -   Returns process results. WM_ERRCODE_OPERATING is returned
  						when asynchronous process was started normally. After that, the results
  						of the asynchronous process is again passed to the callback.
 *---------------------------------------------------------------------------*/
WMErrCode
WM_SetEntry( WMCallbackFunc callback , BOOL enabled )
{
    WMErrCode   result;

    // not executable unless parent
    result = WMi_CheckStateEx( 2 , WM_STATE_PARENT , WM_STATE_MP_PARENT );
    WM_CHECK_RESULT( result );

    // enter callback function
    WMi_SetCallbackTable( WM_APIID_SET_ENTRY , callback );

    // Notify ARM7 with FIFO
    result = WMi_SendCommand(  WM_APIID_SET_ENTRY , 1 , (u32)enabled );
    WM_CHECK_RESULT( result );

    return WM_ERRCODE_OPERATING;
}

/*---------------------------------------------------------------------------*
  Name:         WMi_SetBeaconPeriod

  Description:  Changes Beacon interval.

  Arguments:    callback    -   The callback function called when asynchronous process ends.
                beaconPeriod - Beacon interval (10 - 1000 TU(1024 microseconds))

  Returns:      WMErrCode   -   Returns process results. WM_ERRCODE_OPERATING is returned
  						when asynchronous process was started normally. After that, the results
  						of the asynchronous process is again passed to the callback.
 *---------------------------------------------------------------------------*/
WMErrCode
WMi_SetBeaconPeriod( WMCallbackFunc callback , u16 beaconPeriod )
{
    WMErrCode   result;

    // not executable unless parent
    result = WMi_CheckStateEx( 2 , WM_STATE_PARENT , WM_STATE_MP_PARENT );
    WM_CHECK_RESULT( result );

    // enter callback function
    WMi_SetCallbackTable( WM_APIID_SET_BEACON_PERIOD , callback );

    // Notify ARM7 with FIFO
    result = WMi_SendCommand(  WM_APIID_SET_BEACON_PERIOD , 1 , (u32)beaconPeriod );
    WM_CHECK_RESULT( result );

    return WM_ERRCODE_OPERATING;
}

/*---------------------------------------------------------------------------*
    End of file
 *---------------------------------------------------------------------------*/
