/* Function:
    void DRV_WIFI_NetworkTypeGet(uint8_t *p_networkType);

  Summary:
    Gets the WiFi network type

  Description:
    This function gets the WiFi network type.

  Parameters:
    p_networkType     - Pointer to where the network type will be written.
                        One of the following:
                          DRV_WIFI_NETWORK_TYPE_INFRASTRUCTURE
                          DRV_WIFI_NETWORK_TYPE_ADHOC
                          DRV_WIFI_NETWORK_TYPE_SOFT_AP

  Returns:
    None
*/
void DRV_WIFI_NetworkTypeGet(uint8_t *p_networkType)
{
    LowLevel_CPGetElement(WF_CP_ELEMENT_NETWORK_TYPE, /* element ID             */
                          p_networkType,              /* element data pointer   */
                          1,                          /* read one byte          */
                          true);                      /* read data, free buffer */
}
/* Function:
    void DRV_WIFI_BssidGet(uint8_t *p_bssid);

  Summary:
    Sets the the BSSID set in DRV_WIFI_BssidSet().

  Description:
    Retrieves the BSSID set in the previous call to DRV_WIFI_BssidSet().

  Parameters:
    p_context   - pointer to where BSSID will be written.

  Returns:
    None
*/
void DRV_WIFI_BssidGet(uint8_t *p_bssid)
{
    LowLevel_CPGetElement(WF_CP_ELEMENT_BSSID,    /* Element ID                        */
                          p_bssid,                /* pointer to element data           */
                          DRV_WIFI_BSSID_LENGTH,  /* number of element data bytes      */
                          true);                  /* read data, free buffer after read */
}   
/*******************************************************************************
  Function:
    void DRV_WIFI_WepKeyTypeGet(uint8_t *p_keyType)

  Summary:
    Gets the Wep Key type

  Description:
    This function gets the WEP key type:
      * DRV_WIFI_SECURITY_WEP_SHAREDKEY
      * DRV_WIFI_SECURITY_WEP_OPENKEY

  Parameters:
    p_keyType -- pointer to where key type will be written.

  Returns:
    None.
  *****************************************************************************/
void DRV_WIFI_WepKeyTypeGet(uint8_t *p_wepKeyType)
{
    LowLevel_CPGetElement(WF_CP_ELEMENT_WEPKEY_TYPE, /* element ID             */
                          p_wepKeyType,              /* element data pointer   */
                          1,                         /* read one byte          */
                          true);                     /* read data, free buffer */
}
/*******************************************************************************
  Function:	
    void WF_CPGetSsid(UINT8 CpId, UINT8 *p_ssid, UINT8 *p_ssidLength)

  Summary:
    Gets the SSID for the specified Connection Profile ID.    

  Description:
    Gets the SSID and SSID Length elements in the Connection Profile.

  Precondition:
    MACInit must be called first.

  Parameters:
    CpId - Connection Profile ID
    p_ssid - Pointer to the SSID string
    ssidLength - Pumber of bytes in the SSID

  Returns:
    None.
  	
  Remarks:
    None.
  *****************************************************************************/
void WF_CPGetSsid(UINT8 CpId, UINT8 *p_ssid, UINT8 *p_ssidLength)
{
    tCPElementResponseHdr  mgmtHdr;
    
    /* Request SSID, but don't have this function read data or free response buffer.       */
    LowLevel_CPGetElement(CpId,                   /* Connection Profile ID                 */
                          WF_CP_ELEMENT_SSID,     /* Element ID                            */
                          NULL,                   /* ptr to element data (not used here    */
                          0,                      /* num data bytes to read (not used here */ 
                          FALSE);                 /* no read, leave response mounted       */
    
    /* At this point, management response is mounted and ready to be read.                 */
    /* Set raw index to 0, read normal 4 byte header plus the next 3 bytes, these will be: */
    /*   profile id             [4]                                                        */
    /*   element id             [5]                                                        */
    /*   element data length    [6]                                                        */
    RawRead(RAW_MGMT_RX_ID, 0, sizeof(tCPElementResponseHdr), (UINT8 *)&mgmtHdr);

    /* extract SSID length and write to caller */
    *p_ssidLength = mgmtHdr.elementDataLength;
    
    /* copy SSID name to callers buffer */
    RawRead(RAW_MGMT_RX_ID, sizeof(tCPElementResponseHdr), *p_ssidLength, p_ssid);
    
    /* free management buffer */
    DeallocateMgmtRxBuffer();
}   
/*******************************************************************************
  Function:	
    void WF_CPGetAdHocBehavior(UINT8 CpId, UINT8 *p_adHocBehavior)

  Summary:
    Gets the desired Ad Hoc behavior

  Description:
    Gets the AdHoc behavior within a Connection Profile.  Allowable values are:
    * WF_ADHOC_CONNECT_THEN_START
    * WF_ADHOC_CONNECT_ONLY
    * WF_ADHOC_START_ONLY

  Precondition:
  	MACInit must be called first.

  Parameters:
    CpId - Connection Profile ID
    adHocBehavior - Pointer to location of the adhoc behavior value for this 
                     connection profile.

  Returns:
  	None.
  	
  Remarks:
  	None.
  *****************************************************************************/
void WF_CPGetAdHocBehavior(UINT8 CpId, UINT8 *p_adHocBehavior)
{
    LowLevel_CPGetElement(CpId,                         /* conn. profile ID       */
                          WF_CP_ELEMENT_ADHOC_BEHAVIOR, /* element ID             */
                          p_adHocBehavior,              /* element data pointer   */
                          1,                            /* read one byte          */
                          TRUE);                        /* read data, free buffer */
}    
/*******************************************************************************
  Function:	
    void WF_CPGetDefaultWepKeyIndex(UINT8 CpId, UINT8 *p_defaultWepKeyIndex)

  Summary:
    Gets the value of the active WEP keys to use.

  Description:
    Only applicable if the Connection Profile security type is either 
    WF_SECURITY_WEP_40 or WF_SECURITY_WEP_104.  Selects which of the four WEP 
    keys to use.

  Precondition:
  	MACInit must be called first.

  Parameters:
    CpId - Connection Profile ID
    p_defaultWepKeyIndex - Pointer to index of WEP key to use (0 - 3)

  Returns:
  	None.
  	
  Remarks:
  	Note that only key 0 amongst AP manufacturers is typically used.  Using any
    of the other three keys may be unpredictable from brand to brand.
  *****************************************************************************/
void WF_CPGetDefaultWepKeyIndex(UINT8 CpId, UINT8 *p_defaultWepKeyIndex)
{
    LowLevel_CPGetElement(CpId,                        /* conn. profile ID       */
                          WF_CP_ELEMENT_WEP_KEY_INDEX, /* element ID             */
                          p_defaultWepKeyIndex,        /* element data pointer   */
                          1,                           /* read one byte          */
                          TRUE);                       /* read data, free buffer */
}
/*******************************************************************************
  Function:	
    void WF_CPGetWPSCredentials(UINT8 CpId, tWFWpsCred *p_cred)

  Summary:
    Gets the WPS credentials for the specified Connection Profile ID.

  Description:
    Gets the WPS credentials after WPS completed

  Precondition:
  	MACInit must be called first.

  Parameters:
    CpId - Connection Profile ID
    p_cred - Pointer to the credentials

  Returns:
  	None.
  	
  Remarks:
  	None.
  *****************************************************************************/ 
void WF_CPGetWPSCredentials(UINT8 CpId, tWFWpsCred *p_cred)
{
    LowLevel_CPGetElement(CpId,                  /* CP ID                             */
                          WF_CP_ELEMENT_READ_WPS_CRED,   /* Element ID                        */
                          (UINT8 *)p_cred,               /* pointer to element data           */
                          sizeof(*p_cred),       /* number of element data bytes      */
                          TRUE);                 /* read data, free buffer after read */
}
/*******************************************************************************
  Function:	
    void WF_CPGetNetworkType(UINT8 CpId, UINT8 networkType)

  Summary:
    Gets the network for the specified Connection Profile ID.

  Description:
    Gets the Network Type element a Connection Profile.  Allowable values are:
    * WF_INFRASTRUCTURE
    * WF_ADHOC

  Precondition:
  	MACInit must be called first.

  Parameters:
    CpId - Connection Profile ID
    networkType - Type of network to create (infrastructure or adhoc)

  Returns:
  	None.
  	
  Remarks:
  	None.
  *****************************************************************************/ 
void WF_CPGetNetworkType(UINT8 CpId, UINT8 *p_networkType)
{
    LowLevel_CPGetElement(CpId,                       /* conn. profile ID       */
                          WF_CP_ELEMENT_NETWORK_TYPE, /* element ID             */
                          p_networkType,              /* element data pointer   */
                          1,                          /* read one byte          */
                          TRUE);                      /* read data, free buffer */
}
/*******************************************************************************
  Function:	
    void WF_CPGetWepKeyType(UINT8 CpId, UINT8 *p_keyType)

  Summary:
    Gets the Wep Key type for the specified Connection Profile ID.

  Description:
    Gets the Network Type element a Connection Profile.  Allowable values are:
    * WF_SECURITY_WEP_SHAREDKEY
    * WF_SECURITY_WEP_OPENKEY

  Precondition:
    MACInit must be called first.

  Parameters:
    CpId -- Connection Profile ID
    networkType -- type of key for Wep security (shared key or open key)

  Returns:
    None.
  	
  Remarks:
    None.
  *****************************************************************************/
void WF_CPGetWepKeyType(UINT8 CpId, UINT8 *p_wepKeyType)
{
    LowLevel_CPGetElement(CpId,                       /* conn. profile ID       */
                          WF_CP_ELEMENT_WEPKEY_TYPE, /* element ID             */
                          p_wepKeyType,              /* element data pointer   */
                          1,                          /* read one byte          */
                          TRUE);                      /* read data, free buffer */
}   
/*******************************************************************************
  Function:	
    void WF_CPGetElements(UINT8 CpId, tWFCPElements *p_elements)

  Summary:
    Reads the Connection Profile elements for the specified ID.

  Description:
    Gets all Connection Profile elements for the specified CP ID.  If the Host 
    CPU does not have enough memory to create a structure of this size then call 
    the individual get functions.

  Precondition:
    MACInit must be called first.

  Parameters:
    CpId - Connectino Profile ID.
    p_elements - Pointer to Connection Profile elements structure.

  Returns:
    None.
  	
  Remarks:
    None.
  *****************************************************************************/
void WF_CPGetElements(UINT8 CpId, tWFCPElements *p_elements)
{
    LowLevel_CPGetElement(CpId,                   /* CP ID                        */
                          WF_CP_ELEMENT_ALL,      /* Element ID                   */
                         (UINT8 *)p_elements,     /* pointer to element data      */
                          sizeof(tWFCPElements),  /* number of element data bytes */
                          TRUE);                  /* read data and free buffer    */
}
/*******************************************************************************
  Function:	
    void WF_CPGetBssid(UINT8 CpId, UINT8 *p_bssid)

  Summary:
    Gets the BSSID for the specified Connection Profile ID.

  Description:
    Gets the BSSID element in a Connection Profile.

  Precondition:
    MACInit must be called first.

  Parameters:
    CpId - Connection Profile ID
    p_bssid - Pointer to the BSSID 

  Returns:
    None.
  	
  Remarks:
    None.
  *****************************************************************************/
void WF_CPGetBssid(UINT8 CpId, UINT8 *p_bssid)
{
    LowLevel_CPGetElement(CpId,                  /* CP ID                             */
                          WF_CP_ELEMENT_BSSID,   /* Element ID                        */
                          p_bssid,               /* pointer to element data           */
                          WF_BSSID_LENGTH,       /* number of element data bytes      */
                          TRUE);                 /* read data, free buffer after read */
}
/*******************************************************************************
  Function:	
    void WF_CPGetSsidType(UINT8 CpId, UINT8 *hidden)

  Summary:
    Gets the SSID type for the specified Connection Profile ID.    

  Description:
    Gets the SSID type element in the Connection Profile.

  Precondition:
    MACInit must be called first.

  Parameters:
    CpId - Connection Profile ID
    hidden - Pointer to the SSID type

  Returns:
    None.
  	
  Remarks:
    None.
  *****************************************************************************/
void WF_CPGetSsidType(UINT8 CpId, UINT8 *hidden)
{
	 LowLevel_CPGetElement(CpId,                       /* conn. profile ID       */
                          WF_CP_ELEMENT_SSID_TYPE, /* element ID             */
                          hidden,              /* element data pointer   */
                          1,                          /* read one byte          */
                          TRUE);                      /* read data, free buffer */
}
/*******************************************************************************
  Function:	
    void WF_CPGetSecurity(UINT8 CpId, 
                          UINT8 securityType,
                          UINT8 wepKeyIndex,
                          UINT8 *p_securityKey,
                          UINT8 securityKeyLength)

  Summary:
    Gets the security for the specified Connection Profile.

  Description:
    Configures security for a Connection Profile.

    <table>
    Security                                Key         Length
    --------                                ---         ------
    WF_SECURITY_OPEN                        N/A         N/A
    WF_SECURITY_WEP_40                      hex         4, 5 byte keys
    WF_SECURITY_WEP_104                     hex         4, 13 byte keys
    WF_SECURITY_WPA_WITH_KEY                hex         32 bytes
    WF_SECURITY_WPA_WITH_PASS_PHRASE        ascii       8-63 ascii characters
    WF_SECURITY_WPA2_WITH_KEY               hex         32 bytes
    WF_SECURITY_WPA2_WITH_PASS_PHRASE       ascii       8-63 ascii characters
    WF_SECURITY_WPA_AUTO_WITH_KEY           hex         32 bytes
    WF_SECURITY_WPA_AUTO_WITH_PASS_PHRASE   ascii       8-63 ascii characters
    </table>

  Precondition:
  	MACInit must be called first.

  Parameters:
    CpId - Connection Profile ID
    securityType - Value corresponding to the security type desired.
    wepKeyIndex - 0 thru 3 (only used if security type is WF_SECURITY_WEP_40 or
                   WF_SECURITY_WEP_104)
    p_securityKey - Binary key or passphrase (not used if security is 
                     WF_SECURITY_OPEN)
    securityKeyLength - Number of bytes in p_securityKey (not used if security
                         is WF_SECURITY_OPEN)

  Returns:
  	None.
  	
  Remarks:
  	None.
  *****************************************************************************/
void WF_CPGetSecurity(UINT8 CpId, 
                      UINT8 *p_securityType,
                      UINT8 *p_wepKeyIndex,
                      UINT8 *p_securityKey,
                      UINT8 *p_securityKeyLength)
{
    tCPElementResponseHdr mgmtHdr;
    UINT8 keyLength;
    
    /* send request, wait for mgmt response, do not read and do not free up response buffer */
     LowLevel_CPGetElement(CpId,
                           WF_CP_ELEMENT_SECURITY,        /* Element ID      */
                           NULL,                          /* do not read     */
                           0,                             /* do not read     */
                           FALSE);                        /* do not read, do not free mgmt buffer */

    /* at this point, management response is mounted and ready to be read */  

        /* At this point, management response is mounted and ready to be read.                 */
    /* Set raw index to 0, read normal 4 byte header plus the next 3 bytes, these will be: */
    /*   profile id             [4]                                                        */
    /*   element id             [5]                                                        */
    /*   element data length    [6]                                                        */
    RawRead(RAW_MGMT_RX_ID, 0, sizeof(tCPElementResponseHdr), (UINT8 *)&mgmtHdr);
    
    RawRead(RAW_MGMT_RX_ID,                     /* raw Id                     */
            sizeof(tCPElementResponseHdr) + 0,  /* index of security type [7] */
            1,                                  /* read one byte              */
            p_securityType);                    /* copy that byte here        */

    RawRead(RAW_MGMT_RX_ID,                     /* raw Id                     */
            sizeof(tCPElementResponseHdr) + 1 , /* index of WEP key index [8] */
            1,                                  /* read one byte              */
            p_wepKeyIndex);                     /* copy that byte here        */

    /* determine security key length and read if it is present */
    keyLength = mgmtHdr.elementDataLength - 2;
    if (keyLength > 0)
    {
        *p_securityKeyLength = keyLength;
        
        RawRead(RAW_MGMT_RX_ID,                     /* raw Id                  */
                sizeof(tCPElementResponseHdr) + 2,  /* index of first key byte */
                keyLength,                          /* number of bytes to read */
                p_securityKey);                     /* copy bytes here         */
        
    }
    /* no security key, so set key length param to 0 */
    else
    {
        *p_securityKeyLength = 0;
    }       
    
    /* free management buffer */
    DeallocateMgmtRxBuffer();
 
}    
uint8_t GetAdHocMode(void)
{
    uint8_t adhocMode;
    LowLevel_CPGetElement(WF_CP_ELEMENT_ADHOC_BEHAVIOR, /* element ID             */
                          &adhocMode,                   /* element data pointer   */
                          1,                            /* read one byte          */
                          true);                        /* read data, free buffer */
    return adhocMode;
}
uint8_t GetHiddenSsid(void)
{
    uint8_t hidden;

    LowLevel_CPGetElement(WF_CP_ELEMENT_SSID_TYPE, /* element ID             */
                          &hidden,                 /* element data pointer   */
                          1,                       /* read one byte          */
                          true);                   /* read data, free buffer */
     return hidden;
}
/*******************************************************************************
  Function:
    void DRV_WIFI_WPSCredentialsGet(DRV_WIFI_WPS_CREDENTIAL *p_cred);

  Summary:
    Gets the WPS credentials

  Description:
    This function gets the WPS credentials from the MRF24WG

  Parameters:
    p_cred -- pointer to where WPS credentials will be written.

  Returns:
    None.
  *****************************************************************************/
void DRV_WIFI_WPSCredentialsGet(DRV_WIFI_WPS_CREDENTIAL *p_cred)
{
    LowLevel_CPGetElement(WF_CP_ELEMENT_READ_WPS_CRED,   /* Element ID                        */
                          (uint8_t *)p_cred,             /* pointer to element data           */
                          sizeof(*p_cred),               /* number of element data bytes      */
                          true);                         /* read data, free buffer after read */

    // fix 16-bit endianness
    p_cred->encType  = TCPIP_Helper_ntohs(p_cred->encType);
    p_cred->authType = TCPIP_Helper_ntohs(p_cred->authType);
}   
//============================================================================
void WF_BssidSet(uint8_t *p_bssid)
{
#if defined(WF_ERROR_CHECKING)
    uint32_t errorCode = UdSetBssid(p_bssid);
    if (errorCode != UD_SUCCESS)
    {
        return;
    }

#endif
    LowLevel_CPGetElement(WF_CP_ELEMENT_BSSID,   // Element ID
                          p_bssid,               // pointer to element data
                          WF_BSSID_LENGTH,       // number of element data bytes
                          true);                 // read data, free buffer after read
}
void WF_WpsCredentialsGet(t_wpsCredentials *p_cred)
{
#if defined(WF_ERROR_CHECKING)
    uint32_t errorCode = UdGetWpsCredentials();
    if (errorCode != UD_SUCCESS)
    {
        EventEnqueue(WF_EVENT_ERROR, errorCode);
        return;
    }
#endif
    LowLevel_CPGetElement(WF_CP_ELEMENT_READ_WPS_CRED,    // Element ID
                          (uint8_t *)p_cred,              // pointer to element data
                          sizeof(*p_cred),                // number of element data bytes
                          true);                          // read data, free buffer after read
}
/*******************************************************************************
  Function:
    void DRV_WIFI_SecurityGet(uint8_t *p_securityType,
                              uint8_t *p_securityKey,
                              uint8_t *p_securityKeyLength)

  Summary:
    Gets the current WiFi security setting

  Description:
    This function gets the current WiFi security setting.

    <table>
    Security                                      Key         Length
    --------                                      ---         ------
    DRV_WIFI_SECURITY_OPEN                        N/A         N/A
    DRV_WIFI_SECURITY_WEP_40                      binary      4 keys, 5 bytes each (total of 20 bytes)
    DRV_WIFI_SECURITY_WEP_104                     binary      4 keys, 13 bytes each (total of 52 bytes)
    DRV_WIFI_SECURITY_WPA_WITH_KEY                binary      32 bytes
    DRV_WIFI_SECURITY_WPA_WITH_PASS_PHRASE        ascii       8-63 ascii characters
    DRV_WIFI_SECURITY_WPA2_WITH_KEY               binary      32 bytes
    DRV_WIFI_SECURITY_WPA2_WITH_PASS_PHRASE       ascii       8-63 ascii characters
    DRV_WIFI_SECURITY_WPA_AUTO_WITH_KEY           binary      32 bytes
    DRV_WIFI_SECURITY_WPA_AUTO_WITH_PASS_PHRASE   ascii       8-63 ascii characters
    </table>

  Precondition:
    WiFi initialization must be complete.

  Parameters:
    p_securityType      - Value corresponding to the security type desired.
    p_securityKey       - Binary key or passphrase (not used if security is DRV_WIFI_SECURITY_OPEN)
    p_securityKeyLength - Number of bytes in p_securityKey (not used if security is DRV_WIFI_SECURITY_OPEN)

  Returns:
    None.

   Example:
    <code>
        uint8_t securityType;
        uint8_t securityKey[DRV_WIFI_MAX_SECURITY_KEY_LENGTH];
        uint8_t keyLength;

        DRV_WIFI_SecurityGet(&securityType, securityKey, &keyLength);
    </code>

  Remarks:
    If security was initially set with a passphrase that the MRF24WG used to generate
    a binary key, this function returns the binary key, not the passphrase.
*/
void DRV_WIFI_SecurityGet(uint8_t *p_securityType,
                          uint8_t *p_securityKey,
                          uint8_t *p_securityKeyLength)
{
    tCPElementResponseHdr mgmtHdr;
    uint8_t keyLength;
    uint8_t wepKeyIndex;
    
    /* send request, wait for mgmt response, do not read and do not free up response buffer */
     LowLevel_CPGetElement(WF_CP_ELEMENT_SECURITY,        /* Element ID      */
                           NULL,                          /* do not read     */
                           0,                             /* do not read     */
                           false);                        /* do not read, do not free mgmt buffer */

    /* at this point, management response is mounted and ready to be read */

    /* At this point, management response is mounted and ready to be read.                 */
    /* Set raw index to 0, read normal 4 byte header plus the next 3 bytes, these will be: */
    /*   profile id             [4]                                                        */
    /*   element id             [5]                                                        */
    /*   element data length    [6]                                                        */
    RawRead(RAW_SCRATCH_ID, MGMT_RX_BASE, sizeof(tCPElementResponseHdr), (uint8_t *)&mgmtHdr);

    // security type
    RawReadRelative(RAW_SCRATCH_ID, 1, p_securityType);

    // read wep key index to increment pointer in raw buffer, but throw away, it is always 0
    RawReadRelative(RAW_SCRATCH_ID, 1, &wepKeyIndex);

    /* determine security key length and read if it is present */
    keyLength = mgmtHdr.elementDataLength - 2;
    if (keyLength > 0)
    {
        *p_securityKeyLength = keyLength;
        RawReadRelative(RAW_SCRATCH_ID, keyLength, p_securityKey);
    }
    /* no security key, so set key length param to 0 */
    else
    {
        *p_securityKeyLength = 0;
    }       
}    
/* Function:
    void DRV_WIFI_SsidGet(uint8_t *p_ssid, uint8_t *p_ssidLength);

  Summary:
    Sets the SSID

  Description:
    Gets the SSID and SSID Length.

 Parameters:
    p_ssid      - Pointer to buffer where SSID will be written
    ssidLength  - number of bytes in SSID

  Returns:
 */
void DRV_WIFI_SsidGet(uint8_t *p_ssid, uint8_t *p_ssidLength)
{
    tCPElementResponseHdr  mgmtHdr;
    
    /* Request SSID, but don't have this function read data or free response buffer.       */
    LowLevel_CPGetElement(WF_CP_ELEMENT_SSID,     /* Element ID                            */
                          NULL,                   /* ptr to element data (not used here    */
                          0,                      /* num data bytes to read (not used here */ 
                          false);                 /* no read, leave response mounted       */

    /* At this point, management response is mounted and ready to be read.                 */
    /* Set raw index to 0, read normal 4 byte header plus the next 3 bytes, these will be: */
    /*   profile id             [4]                                                        */
    /*   element id             [5]                                                        */
    /*   element data length    [6]                                                        */
    RawRead(RAW_SCRATCH_ID, MGMT_RX_BASE, sizeof(tCPElementResponseHdr), (uint8_t *)&mgmtHdr);

    /* extract SSID length and write to caller */
    *p_ssidLength = mgmtHdr.elementDataLength;
    
    /* copy SSID name to callers buffer */
    RawReadRelative(RAW_SCRATCH_ID, *p_ssidLength, p_ssid);
}