/******************************************************************************
 * Copyright (c) 2013-2016 Realtek Semiconductor Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
  ******************************************************************************
  * @file    wifi_conf.h
  * @author
  * @version
  * @brief   This file provides user interface for Wi-Fi station and AP mode configuration 
  *             base on the functionalities provided by Realtek Wi-Fi driver.
  ******************************************************************************
  */
#ifndef __WIFI_API_H
#define __WIFI_API_H

/** @addtogroup nic NIC
 *  @ingroup    wlan
 *  @brief      NIC functions
 *  @{
 */

#include "wifi_constants.h"
#include "wifi_structures.h"
#include "wifi_util.h"
#include "wifi_ind.h"
#include <platform/platform_stdlib.h>

#ifdef __cplusplus
  extern "C" {
#endif

/******************************************************
 *                    Macros
 ******************************************************/

#define RTW_ENABLE_API_INFO

#ifdef RTW_ENABLE_API_INFO
#if defined(CONFIG_MBED_ENABLED)
    extern __u32 GlobalDebugEnable;
    #define RTW_API_INFO(...)     do {\
        if (GlobalDebugEnable) \
            printf(__VA_ARGS__);\
    }while(0)
#else
    #define RTW_API_INFO printf
#endif
#else
    #define RTW_API_INFO(args)
#endif

#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
#define CMP_MAC( a, b )  (((a[0])==(b[0]))&& \
                          ((a[1])==(b[1]))&& \
                          ((a[2])==(b[2]))&& \
                          ((a[3])==(b[3]))&& \
                          ((a[4])==(b[4]))&& \
                          ((a[5])==(b[5])))

/******************************************************
 *                    Constants
 ******************************************************/
#define SCAN_LONGEST_WAIT_TIME  (17000)


#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"

#define PSCAN_ENABLE 0x01      //enable for partial channel scan
#define PSCAN_FAST_SURVEY 0x02 //set to select scan time to FAST_SURVEY_TO, otherwise SURVEY_TO
#define PSCAN_SIMPLE_CONFIG   0x04 //set to select scan time to FAST_SURVEY_TO and resend probe request

typedef enum _WL_BAND_TYPE{
	WL_BAND_2_4G = 0,		
	WL_BAND_5G,
	WL_BAND_2_4G_5G_BOTH,
	WL_BAND_NOT_MATCH,
	WL_BANDMAX
}WL_BAND_TYPE,*PWL_BAND_TYPE;

/******************************************************
 *                 Type Definitions
 ******************************************************/

/** Scan result callback function pointer type
 *
 * @param result_ptr  : A pointer to the pointer that indicates where to put the next scan result
 * @param user_data   : User provided data
 */
typedef void (*rtw_scan_result_callback_t)( rtw_scan_result_t** result_ptr, void* user_data );
typedef rtw_result_t (*rtw_scan_result_handler_t)( rtw_scan_handler_result_t* malloced_scan_result );

/******************************************************
 *                    Structures
 ******************************************************/
typedef struct {
	char *buf;
	int buf_len;
} scan_buf_arg;

/******************************************************
 *                    Structures
 ******************************************************/
typedef struct internal_scan_handler{
	rtw_scan_result_t** pap_details;
	rtw_scan_result_t * ap_details;
	int	scan_cnt;
	rtw_bool_t	scan_complete;
	unsigned char	max_ap_size;
	rtw_scan_result_handler_t gscan_result_handler;
#if defined(SCAN_USE_SEMAPHORE) && SCAN_USE_SEMAPHORE
	void *scan_semaphore;
#else
	int 	scan_running;
#endif
	void*	user_data;
	unsigned int	scan_start_time;
} internal_scan_handler_t;

typedef struct {
    rtw_network_info_t	network_info;
    void *join_sema;
} internal_join_result_t;

/******************************************************
 *               Function Declarations
 ******************************************************/
/**
 * @brief  Initialize Realtek WiFi API System.
 * 			- Initialize the required parts of the software platform.
 *   			i.e. worker, event registering, semaphore, etc.
 * 			- Initialize the RTW API thread which handles the asynchronous event.
 * @return RTW_SUCCESS if initialization is successful, RTW_ERROR otherwise
 */
int wifi_manager_init(void);

/**
 * @brief  Join a Wi-Fi network.
 * 		Scan for, associate and authenticate with a Wi-Fi network.
 *		On successful return, the system is ready to send data packets.
 *
 * @param[in]  ssid: A null terminated string containing the SSID name of the network to join.
 * @param[in]  security_type: Authentication type:
 *                         - RTW_SECURITY_OPEN           - Open Security
 *                         - RTW_SECURITY_WEP_PSK        - WEP Security with open authentication
 *                         - RTW_SECURITY_WEP_SHARED     - WEP Security with shared authentication
 *                         - RTW_SECURITY_WPA_TKIP_PSK   - WPA Security
 *                         - RTW_SECURITY_WPA2_AES_PSK   - WPA2 Security using AES cipher
 *                         - RTW_SECURITY_WPA2_TKIP_PSK  - WPA2 Security using TKIP cipher
 *                         - RTW_SECURITY_WPA2_MIXED_PSK - WPA2 Security using AES and/or TKIP ciphers
 * @param[in]  password: A byte array containing either the cleartext security key for WPA/WPA2
 *  						 secured networks, or a pointer to an array of rtw_wep_key_t
 *  						 structures for WEP secured networks.
 * @param[in]  ssid_len: The length of the SSID in bytes.
 * @param[in]  password_len: The length of the security_key in bytes.
 * @param[in]  key_id: The index of the wep key (0, 1, 2, or 3). If not using it, leave it with value -1.
 * @param[in]  semaphore: A user provided semaphore that is flagged when the join is complete. If not using it, leave it with NULL value.
 * @return  RTW_SUCCESS: when the system is joined and ready to send data packets.
 * @return  RTW_ERROR: if an error occurred.
 * @note  Please make sure the Wi-Fi is enabled before invoking this function. (@ref wifi_on())
 */
int wifi_connect(
	char 				*ssid,
	rtw_security_t	security_type,
	char 				*password,
	int 				ssid_len,
	int 				password_len,
	int 				key_id,
	void 				*semaphore);

/**
 * @brief  Join a Wi-Fi network with specified BSSID.
 * 		Scan for, associate and authenticate with a Wi-Fi network.
 *		On successful return, the system is ready to send data packets.
 * @param[in]  bssid: The specified BSSID to connect.
 * @param[in]  ssid: A null terminated string containing the SSID name of the network to join.
 * @param[in]  security_type: Authentication type:
 *                         - RTW_SECURITY_OPEN           - Open Security
 *                         - RTW_SECURITY_WEP_PSK        - WEP Security with open authentication
 *                         - RTW_SECURITY_WEP_SHARED     - WEP Security with shared authentication
 *                         - RTW_SECURITY_WPA_TKIP_PSK   - WPA Security
 *                         - RTW_SECURITY_WPA2_AES_PSK   - WPA2 Security using AES cipher
 *                         - RTW_SECURITY_WPA2_TKIP_PSK  - WPA2 Security using TKIP cipher
 *                         - RTW_SECURITY_WPA2_MIXED_PSK - WPA2 Security using AES and/or TKIP ciphers
 * @param[in]  password: A byte array containing either the cleartext security key for WPA/WPA2
 *  						 secured networks, or a pointer to an array of rtw_wep_key_t
 *  						 structures for WEP secured networks.
 * @param[in]  ssid_len: The length of the SSID in bytes.
 * @param[in]  password_len: The length of the security_key in bytes.
 * @param[in]  key_id: The index of the wep key.
 * @param[in]  semaphore: A user provided semaphore that is flagged when the join is complete.
 * @return  RTW_SUCCESS: when the system is joined and ready to send data packets.
 * @return  RTW_ERROR: if an error occurred.
 * @note  Please make sure the Wi-Fi is enabled before invoking this function. (@ref wifi_on())
 * @note  The difference between @ref wifi_connect_bssid() and @ref wifi_connect() is that BSSID has higher priority as the basis of connection in @ref wifi_connect_bssid.
 */
int wifi_connect_bssid(
	unsigned char 		bssid[ETH_ALEN],
	char 				*ssid,
	rtw_security_t	security_type,
	char 				*password,
	int 				bssid_len,
	int 				ssid_len,
	int 				password_len,
	int 				key_id,
	void 				*semaphore);

/**
  * @brief  Disassociates from current Wi-Fi network.
  * @param  None
  * @return  RTW_SUCCESS: On successful disassociation from the AP.
  * @return  RTW_ERROR: If an error occurred.
  */
int wifi_disconnect(void);

/**
* @brief  Check if Wi-Fi has connected to AP before dhcp.
* @param  None
* @return  RTW_SUCCESS: If conneced.
* @return  RTW_ERROR: If not connect.
*/
int wifi_is_connected_to_ap(void);

/**
* @brief  Set partial scan retry times when PSCAN_FAST_SURVEY is set. Default is 7.
* @param[in]  partial scan retry times
* @return  None.
*/
void wifi_set_partial_scan_retry_times(unsigned char times);

/**
  * @brief  Check if the specified interface is up.
  * @param[in]  interface: The interface can be set as RTW_STA_INTERFACE or RTW_AP_INTERFACE. (@ref rtw_interface_t)
  * @return  If the function succeeds, the return value is 1. Otherwise, return 0.
  */
int wifi_is_up(rtw_interface_t interface);

/** Determines if a particular interface is ready to transceive ethernet packets
 *
 * @param     Radio interface to check, options are 
 *  				RTW_STA_INTERFACE, RTW_AP_INTERFACE
 * @return    RTW_SUCCESS  : if the interface is ready to 
 *  		  transceive ethernet packets
 * @return    RTW_ERROR    : if the interface is not ready to 
 *  		  transceive ethernet packets
 */
int wifi_is_ready_to_transceive(rtw_interface_t interface);

/**
 * @brief  This function sets the current Media Access Control (MAC) address of the 802.11 device but don't 
 *			write to efuse or flash, it is to modify the MAC temporarily in RAM.
 *			Only call this API BEFORE connecting to a network, BEFORE fast connect and BEFORE starting SoftAP(For AP mode).
 *      Example:
 *      u8 mac[ETH_ALEN] = {0x00, 0xe0, 0x4c, 0x87, 0x12, 0x34};
 *      ret = wifi_change_mac_address_from_ram(0,mac); 
 * @param[in] idx: 0=> wlan0, 1=>wlan1.
 * @param[in] mac: Wi-Fi MAC address.
 * @return    RTW_SUCCESS or RTW_ERROR
 */
int wifi_change_mac_address_from_ram(int idx, u8 *mac);

/**
 * @brief  This function sets the current Media Access Control (MAC) address of the 802.11 device in Efuse.
 *      Example:
 *      #define MAC_VALID		"ecf00e4e751c"
 *      ret = wifi_set_mac_address((char *)MAC_VALID);
 * @param[in] mac: Wi-Fi MAC address.
 * @return    RTW_SUCCESS or RTW_ERROR
 */
int wifi_set_mac_address(char * mac);

/**
 * @brief  Retrieves from RAM space WLAN0's current Media Access Control (MAC) address
 *			(or Ethernet hardware address) of the 802.11 device.
 *      Example:
 *      char *mac;
 *      mac = (char*)malloc(18*sizeof(char));
 *      ret = wifi_get_mac_address(mac);
 *      printf("\nGet MAC address: %s\n", mac);
 *      free(mac);
 * @param[in]  mac: Pointer to the result of the mac address,it must be at least 18 bytes long.
 * @return    RTW_SUCCESS or RTW_ERROR
 */
int wifi_get_mac_address(char * mac);

/**
 * @brief  Retrieves from RAM space the selected interface's current Media Access Control (MAC) address
 *			(or Ethernet hardware address) of the 802.11 device.
  *     Example:
 *      char *mac;
 *      mac = (char*)malloc(18*sizeof(char));
 *      ret = wifi_get_interface_mac_address(0,mac);
 *      printf("\nGet MAC address of wlan0: %s\n", mac);
 *      free(mac);
 *  @param[in] idx: 0=> wlan0, 1=>wlan1.
 *  @param[in]  mac: Pointer to the result of the mac address, it must be at least 18 bytes long.
 * @return    RTW_SUCCESS or RTW_ERROR
 */
int wifi_get_interface_mac_address(int idx, char * mac);

/**
 * @brief Enable Wi-Fi powersave mode.
 * @param  None
 * @return RTW_SUCCESS or RTW_ERROR.
 */
int wifi_enable_powersave(void);

/**
 * @brief Enable Wi-Fi powersave mode for coexistence.
 * @param  None
 * @return RTW_SUCCESS or RTW_ERROR.
 */
int wifi_enable_powersave_for_coex(void);

/**
 * @brief Resume Wi-Fi powersave mode.
 * @param  None
 * @return RTW_SUCCESS or RTW_ERROR.
 */
int wifi_resume_powersave(void);

/**
 * @brief Disable Wi-Fi powersave mode.
 * @param  None
 * @return RTW_SUCCESS or RTW_ERROR.
 */
int wifi_disable_powersave(void);

/** Gets the tx power in index units
 *
 * @param dbm : The variable to receive the tx power in index.
 *
 * @return  RTW_SUCCESS : if successful
 *          RTW_ERROR   : if not successful
 */

void wifi_btcoex_set_bt_on(void);

void wifi_btcoex_set_bt_off(void);

int wifi_get_txpower(int *poweridx);

/**
 * @brief  Set the tx power in index units.
 * @param[in] poweridx: The desired tx power in index.
 * @return  RTW_SUCCESS: if tx power is successfully set
 * @return  RTW_ERROR: if tx power is not successfully set
 */
int wifi_set_txpower(int poweridx);

/**
 * @brief  Get the associated clients with SoftAP.
 * @param[out]  client_list_buffer: The location where the client list will be stored.
 * @param[in]  buffer_length: The buffer length.
 * @return  RTW_SUCCESS: The result is successfully got.
 * @return  RTW_ERROR: The result is not successfully got.
 */
int wifi_get_associated_client_list(void * client_list_buffer, unsigned short buffer_length);

/**
 * @brief  Get the SoftAP client information.
 * @param[out]  client_list_buffer: The location where the client information will be stored.
 * @param[in]  buffer_length: The buffer length.
 * @return  RTW_SUCCESS: The result is successfully got.
 * @return  RTW_ERROR: The result is not successfully got.
 */
int wifi_get_ap_client_info(void * client_list_buffer, uint16_t buffer_length);

/**
 * @brief Get connected AP's BSSID
 * @param[out] bssid : the location where the AP BSSID will be stored
 * @return RTW_SUCCESS : if result was successfully get
 * @return RTW_ERROR : if result was not successfully get
 */
int wifi_get_ap_bssid(unsigned char *bssid);

/**
 * @brief  Get the SoftAP information.
 * @param[out]  ap_info: The location where the AP info will be stored.
 * @param[out]  security: The security type.
 * @return  RTW_SUCCESS: The result is successfully got.
 * @return  RTW_ERROR: The result is not successfully got.
 */
int wifi_get_ap_info(rtw_bss_info_t * ap_info, rtw_security_t* security);

/**
 * @brief  Set the country code to driver to determine the channel set.
 * @param[in]  country_code: Specify the country code.
 * @return  RTW_SUCCESS: If result is successfully set.
 * @return  RTW_ERROR: If result is not successfully set.
 */
int wifi_set_country(rtw_country_code_t country_code);

/**
 * @brief  retrieved sta mode MAX data rate.
 * @param[out]  inidata_rate: MAX data rate.
 * @return  RTW_SUCCESS: If the INIDATA_RATE is successfully retrieved.
 * @return  RTW_ERROR: If the INIDATA_RATE is not retrieved.
 * note: inidata_rate = 2 * (data rate), you need inidata_rate/2.0 to get the real rate
 */
int wifi_get_sta_max_data_rate(__u8 * inidata_rate);

/**
 * @brief  Retrieve the latest RSSI value.
 * @param[out]  pRSSI: Points to the integer to store the RSSI value gotten from driver.
 * @return  RTW_SUCCESS: If the RSSI is succesfully retrieved.
 * @return  RTW_ERROR: If the RSSI is not retrieved.
 */
int wifi_get_rssi(int *pRSSI);

/**
 * @brief  Retrieve the latest average beacon RSSI value.
 * @param[out]  pRSSI: Points to the integer to store the RSSI value gotten from driver.
 * @return  RTW_SUCCESS: If the RSSI is succesfully retrieved.
 * @return  RTW_ERROR: If the RSSI is not retrieved.
 */
int wifi_get_bcn_rssi(int *pRSSI);

/**
 * @brief  Set the listening channel for promiscuous mode.
 * @param[in]  channel: The desired channel.
 * @return  RTW_SUCCESS: If the channel is successfully set.
 * @return  RTW_ERROR: If the channel is not successfully set.
 * @note  Do NOT need to call this function for STA mode wifi driver, since it will determine the channel from received beacon.
 */
int wifi_set_channel(int channel);

/**
 * @brief  Get the current channel on STA interface.
 * @param[out] channel: A pointer to the variable where the 
 *  				channel value will be written
 * @return  RTW_SUCCESS: If the channel is successfully read.
 * @return  RTW_ERROR: If the channel is not successfully read.
 */
int wifi_get_channel(int *channel);

/**
 * @brief  switch the current channelPlan on STA or AP interface.
 * @param[in] channel_plan: the available channelPlan Map index
 *  				        from 0x20 to 0x79
 * @return  RTW_SUCCESS: If the channel is successfully read.
 * @return  RTW_ERROR: If the channel is not successfully read.
 */
int wifi_change_channel_plan(uint8_t channel_plan);

/**
 * @brief  Register interest in a multicast address.\n
 * 		Once a multicast address has been registered, all packets detected on the
 * 		medium destined for that address are forwarded to the host.
 * 		Otherwise they are ignored.
 * @param[in] mac: Ethernet MAC address
 * @return  RTW_SUCCESS: If the address is registered successfully.
 * @return  RTW_ERROR: If the address is not registered.
 */
int wifi_register_multicast_address(rtw_mac_t *mac);

/** 
 * @brief  Unregister interest in a multicast address.\n
 * 		Once a multicast address has been unregistered, all packets detected on the
 * 		medium destined for that address are ignored.
 * @param[in] mac: Ethernet MAC address
 * @return  RTW_SUCCESS: If the address is unregistered successfully.
 * @return  RTW_ERROR: If the address is not unregistered.
 */
int wifi_unregister_multicast_address(rtw_mac_t *mac);

/**
 * @brief  Setup the adaptivity mode.
 * 		You can replace this weak function by the same name funcation to setup adaptivity mode you want.
 * @param  None
 * @return  If the function succeeds, the return value is 0.
 */
_WEAK void wifi_set_mib(void);

/**
 * @brief  Setup country code.
  * 		You can replace this weak function by the same name funcation to setup country code you want.
 * @param  None
 * @return  If the function succeeds, the return value is 0.
 */
//----------------------------------------------------------------------------//
_WEAK void wifi_set_country_code(void);

/**
 * @brief  Enable Wi-Fi RF.
 * @param  None
 * @return  If the function succeeds, the return value is 0.
 * @note  The difference between @ref wifi_rf_on() and @ref wifi_on() is that @ref wifi_rf_on() simply enable RF HAL, it does not enable the driver or allocate memory.
 */
int wifi_rf_on(void);

/**
 * @brief  Disable Wi-Fi RF.
 * @param  None
 * @return  If the function succeeds, the return value is 0.
 * @note  The difference between @ref wifi_rf_off() and @ref wifi_off() is that @ref wifi_rf_off() simply disable RF HAL, the driver and used heap memory will NOT be released.
 */
int wifi_rf_off(void);

/**
 * @brief  Enable Wi-Fi.
 * - Bring the Wireless interface "Up"
 * - Initialize the driver thread which arbitrates access
 *   to the SDIO/SPI bus
 *
 * @param[in]  mode: Decide to enable WiFi in which mode. The optional modes are enumerated in @ref rtw_mode_t.
 * @return  RTW_SUCCESS: if the WiFi chip was initialized successfully.
 * @return  RTW_ERROR: if the WiFi chip was not initialized successfully.
 */
int wifi_on(rtw_mode_t mode);

/**
 * @brief  Disable Wi-Fi.
 *  
 * @param  None
 * @return  RTW_SUCCESS: if deinitialization is successful.
 * @return  RTW_ERROR: otherwise.
 */
int wifi_off(void);

/**
 * @brief  Switch Wifi Mode
 * 
 * - Switch Wifi Mode to @param[in]
 *
 * @param[in]  mode: Decide to switch WiFi to which mode. The optional modes are RTW_MODE_STA or RTW_MODE_AP.
 * @return  RTW_SUCCESS:    if the WiFi switch mode successful.
 * @return  RTW_ERROR:      if the WiFi swithc mdoe not successful.
 */
int wifi_set_mode(rtw_mode_t mode);

/**
 * Turn off the Wi-Fi device
 *
 * - Bring the Wireless interface "Down"
 * - De-Initialises the driver thread which arbitrates access
 *   to the SDIO/SPI bus
 *
 * @return RTW_SUCCESS if deinitialization is successful, 
 *  	   RTW_ERROR otherwise
 */
int wifi_off_fastly(void);

/**
 * @brief  Specify wpa mode for wifi connection.
 * @param[in] wpa_mode: The desired wpa mode. It is defined as enum rtw_wpa_mode.
 * @return  RTW_SUCCESS if setting wpa mode successful.
 * @return  RTW_ERROR otherwise.
 */
int wifi_set_wpa_mode(rtw_wpa_mode wpa_mode);

/**
 * @brief  Set IPS/LPS mode.
 * @param[in] ips_mode: The desired IPS mode. It becomes effective when wlan enter ips.\n
 *		@ref ips_mode is inactive power save mode. Wi-Fi automatically turns RF off if it is not associated to AP. Set 1 to enable inactive power save mode.
 * @param[in] lps_mode: The desired LPS mode. It becomes effective when wlan enter lps.\n
 *		@ref lps_mode is leisure power save mode. Wi-Fi automatically turns RF off during the association to AP is traffic is not busy while it also automatically turns RF on to listen to beacon. Set 1 to enable leisure power save mode.
 * @return  RTW_SUCCESS if setting LPS mode successful.
 * @return  RTW_ERROR otherwise.
 */
 
int wifi_set_power_mode(unsigned char ips_mode, unsigned char lps_mode);

/**
 * Set TDMA parameters
 *
 * @param[in] slot_period  : We separate TBTT into 2 or 3 slots.
 *                           If we separate TBTT into 2 slots, then slot_period should be larger or equal to 50ms.
 *                           It means 2 slot period is
 *                               slot_period, 100-slot_period
 *                           If we separate TBTT into 3 slots, then slot_period should be less or equal to 33ms.
 *                           It means 3 slot period is
 *                               100 - 2 * slot_period, slot_period, slot_period
 * @param[in] rfon_period_len_1: rf on period of slot 1
 * @param[in] rfon_period_len_2: rf on period of slot 2
 * @param[in] rfon_period_len_3: rf on period of slot 3
 *
 * @return RTW_SUCCESS if setting TDMA parameters successful
 *         RTW_ERROR otherwise
 */
int wifi_set_tdma_param(unsigned char slot_period, unsigned char rfon_period_len_1, unsigned char rfon_period_len_2, unsigned char rfon_period_len_3);

/**
 * @brief Set LPS DTIM.
 * @param[in] dtim: In LPS, the package can be buffered at AP side.
 *                    STA leave LPS until dtim count of packages buffered at AP side.
 * @return  RTW_SUCCESS if setting LPS dtim successful.
 * @return  RTW_ERROR otherwise
 */
int wifi_set_lps_dtim(unsigned char dtim);

/**
 * @brief  Get LPS DTIM.
 * @param[out] dtim: In LPS, the package can be buffered at AP side.
 *                    STA leave LPS until dtim count of packages buffered at AP side.
 * @return  RTW_SUCCESS if getting LPS dtim successful.
 * @return  RTW_ERROR otherwise.
 */
int wifi_get_lps_dtim(unsigned char *dtim);

enum {
	LPS_THRESH_PKT_COUNT = 0,
	LPS_THRESH_DIRECT_ENTER,
	LPS_THRESH_TP,
};
typedef unsigned char rtw_lps_thresh_t;

/**
 * @brief  Set LPS threshold.
 * @param[in] mode: LPS threshold mode LPS_THRESH_PKT_COUNT/LPS_THRESH_DIRECT_ENTER/LPS_THRESH_TP
 * @return  RTW_SUCCESS if set LPS threshold successful.
 * @return  RTW_ERROR otherwise.
 */
int wifi_set_lps_thresh(rtw_lps_thresh_t mode); 

/**
 * @brief Set LPS LEVEL
 * @param[in] lps_level: 0 is LPS_NORMAL, 1 is LPS_LCLK, 2 is LPS_PG
 *
 * @return  RTW_SUCCESS if setting LPS level successful.
 * @return  RTW_ERROR otherwise
 */
int wifi_set_lps_level(unsigned char lps_level);

#ifdef LONG_PERIOD_TICKLESS
/**
 * @brief Set Smart PS
 * @param[in] smartps: 0 is issue NULL data, 2 is issue PS-Poll
 *
 * @return  RTW_SUCCESS if setting Smart PS successful.
 * @return  RTW_ERROR otherwise
 */
int wifi_set_lps_smartps(unsigned char smartps);
#endif
/**
 * @brief  Set Management Frame Protection Support.
 * @param[in] value: 
 *				- NO_MGMT_FRAME_PROTECTION 		- not support
 *				- MGMT_FRAME_PROTECTION_OPTIONAL 	- capable
 *				- MGMT_FRAME_PROTECTION_REQUIRED 	- required
 * @return  RTW_SUCCESS if setting Management Frame Protection Support successful.
 * @return  RTW_ERROR otherwise.
 */
int wifi_set_mfp_support(unsigned char value);

/**
 * @brief  Trigger Wi-Fi driver to start an infrastructure Wi-Fi network.
 * @warning If a STA interface is active when this function is called, the softAP will
 *          start on the same channel as the STA. It will NOT use the channel provided!
 * @param[in]  ssid: A null terminated string containing the SSID name of the network.
 * @param[in]  security_type: 
 *                         - RTW_SECURITY_OPEN           - Open Security
 *                         - RTW_SECURITY_WPA_TKIP_PSK   - WPA Security
 *                         - RTW_SECURITY_WPA2_AES_PSK   - WPA2 Security using AES cipher
 *                         - RTW_SECURITY_WPA2_MIXED_PSK - WPA2 Security using AES and/or TKIP ciphers
 *                         - WEP security is NOT IMPLEMENTED. It is NOT SECURE!
 * @param[in]  password: A byte array containing the cleartext security key for the network.
 * @param[in]  ssid_len: The length of the SSID in bytes.
 * @param[in]  password_len: The length of the security_key in bytes.
 * @param[in]  channel: 802.11 channel number.
 * @return  RTW_SUCCESS: If successfully creates an AP.
 * @return  RTW_ERROR: If an error occurred.
 * @note  Please make sure the Wi-Fi is enabled before invoking this function. (@ref wifi_on())
 */
int wifi_start_ap(
	char 				*ssid,
	rtw_security_t		security_type,
	char 				*password,
	int 				ssid_len,
	int 				password_len,
	int					channel);

/**
 * @brief  Start an infrastructure Wi-Fi network with hidden SSID.
 * @warning If a STA interface is active when this function is called, the softAP will
 *          start on the same channel as the STA. It will NOT use the channel provided!
 *
 * @param[in]  ssid: A null terminated string containing
 *  	 the SSID name of the network to join.
 * @param[in]  security_type: Authentication type: \n
 *                         - RTW_SECURITY_OPEN           - Open Security
 *                         - RTW_SECURITY_WPA_TKIP_PSK   - WPA Security
 *                         - RTW_SECURITY_WPA2_AES_PSK   - WPA2 Security using AES cipher
 *                         - RTW_SECURITY_WPA2_MIXED_PSK - WPA2 Security using AES and/or TKIP ciphers
 *                         - WEP security is NOT IMPLEMENTED. It is NOT SECURE!
 * @param[in]  password: A byte array containing the cleartext
 *  	 security key for the network.
 * @param[in]  ssid_len: The length of the SSID in bytes.
 * @param[in]  password_len: The length of the security_key in bytes.
 * @param[in]  channel: 802.11 channel number
 *
 * @return  RTW_SUCCESS: If successfully creates an AP.
 * @return  RTW_ERROR: If an error occurred.
 */
int wifi_start_ap_with_hidden_ssid(
	char 				*ssid,
	rtw_security_t		security_type,
	char 				*password,
	int 				ssid_len,
	int 				password_len,
	int					channel);

/**
 * @brief  Initiate a scan to search for 802.11 networks.
 *
 * @param[in]  scan_type: Specifies whether the scan should 
 *                             be Active, Passive or scan 
 *                             Prohibited channels
 * @param[in]  bss_type: Specifies whether the scan should 
 *                             search for Infrastructure
 *                             networks (those using an Access
 *                             Point), Ad-hoc networks, or both
 *                             types.
 * @param[in]  result_ptr: Scan specific ssid. The first 4 
 *                             bytes is ssid lenth, and ssid name
 *                             append after it.
 *                             If no specific ssid need to scan,
 *                             PLEASE CLEAN result_ptr before pass
 *                             it into parameter.
 * @param[out]  result_ptr: a pointer to a pointer to a result 
 *                             storage structure.
 * @return  RTW_SUCCESS or RTW_ERROR
 * @note  The scan progressively accumulates results over time, and
 *  			may take between 1 and 3 seconds to complete. The results of
 *  			the scan will be individually provided to the callback
 *  			function. Note: The callback function will be executed in
 *  			the context of the RTW thread.
 * @note  When scanning specific channels, devices with a 
 *  	 strong signal strength on nearby channels may be
 *  	 detected
 */
int wifi_scan(rtw_scan_type_t                    scan_type,
				  rtw_bss_type_t                     bss_type,
				  void*                result_ptr);

/**
 * @brief  Initiate a scan to search for 802.11 networks, a higher level API based on wifi_scan
 *			to simplify the scan operation.
 * @param[in]  results_handler: The callback function which will receive and process the result data.
 * @param[in]  user_data: User specified data that will be passed directly to the callback function.
 * @return  RTW_SUCCESS or RTW_ERROR
 * @note  Callback must not use blocking functions, since it is called from the context of the RTW thread. 
 *			The callback, user_data variables will be referenced after the function returns. 
 *			Those variables must remain valid until the scan is completed.
 *			The usage of this api can reference ATWS in atcmd_wifi.c.
 */
int wifi_scan_networks(rtw_scan_result_handler_t results_handler, void* user_data);

/**
 * @brief  Initiate a scan to search for 802.11 networks, a higher level API based on wifi_scan
 *			to simplify the scan operation. This API separate full scan channel to partial scan
 *			each channel for concurrent mode. MCC means Multi-channel concurrent.
 * @param[in]  results_handler: The callback function which will receive and process the result data.
 * @param[in]  user_data: User specified data that will be passed directly to the callback function.
 * @return  RTW_SUCCESS or RTW_ERROR
 * @note  Callback must not use blocking functions, since it is called from the context of the RTW thread.
 *			The callback, user_data variables will be referenced after the function returns.
 *			Those variables must remain valid until the scan is completed.
 *			The usage of this api can reference ATWS in atcmd_wifi.c.
 */
int wifi_scan_networks_mcc(rtw_scan_result_handler_t results_handler, void* user_data);

/**
 * @brief  Initiate a scan to search for 802.11 networks with specified SSID.
 * @param[in]  results_handler: The callback function which will receive and process the result data.
 * @param[in]  user_data: User specified data that will be passed directly to the callback function.
 * @param[in]  scan_buflen: The length of the result storage structure.
 * @param[in]  ssid: The SSID of target network.
 * @param[in]  ssid_len: The length of the target network SSID.
 * @return  RTW_SUCCESS or RTW_ERROR
 * @note  Callback must not use blocking functions, since it is called from the context of the RTW thread. 
 *			The callback, user_data variables will be referenced after the function returns. 
 *			Those variables must remain valid until the scan is completed.
 */
int wifi_scan_networks_with_ssid(int (results_handler)(char*, int, char *, void *), void* user_data, int scan_buflen, char* ssid, int ssid_len);

/**
 * @brief  Initiate a scan to search for 802.11 networks with specified SSID.
 * @param[in]  results_handler: The callback function which will receive and process the result data.
 * @param[in]  user_data: User specified data that will be passed directly to the callback function.
 * @param[in]  scan_buflen: The length of the result storage structure.
 * @param[in]  ssid: The SSID of target network.
 * @param[in]  ssid_len: The length of the target network SSID.
 * @return  RTW_SUCCESS or RTW_ERROR
 * @note  Callback must not use blocking functions, since it is called from the context of the RTW thread. 
 *			The callback, user_data variables will be referenced after the function returns. 
 *			Those variables must remain valid until the scan is completed.
 */
int wifi_scan_networks_with_ssid_by_extended_security(int (results_handler)(char*, int, char *, void *), void* user_data, int scan_buflen, char* ssid, int ssid_len);

/**
* @brief  Set the channel used to be partial scanned.
* @param[in]  channel_list: An array stores the channel list.
* @param[in]  pscan_config: the pscan_config of the channel set.
* @param[in]  length: The length of the channel_list.
* @return  RTW_SUCCESS or RTW_ERROR.
* @note  This function should be used with wifi_scan function. First, use @ref wifi_set_pscan_chan to
*			indicate which channel will be scanned, and then use @ref wifi_scan to get scanned results.
*/
int wifi_set_pscan_chan(__u8 * channel_list,__u8 * pscan_config, __u8 length);

/**
 * @brief  Get current Wi-Fi setting from driver.
 * @param[in]  ifname: the wlan interface name, can be WLAN0_NAME or WLAN1_NAME.
 * @param[out]  pSetting: Points to the rtw_wifi_setting_t structure to store the WIFI setting gotten from driver.
 * @return  RTW_SUCCESS or RTW_ERROR.
 */
int wifi_get_setting(const char *ifname,rtw_wifi_setting_t *pSetting);

/**
 * @brief  Show the network information stored in a rtw_wifi_setting_t structure.
 * @param[in]  ifname: the wlan interface name, can be WLAN0_NAME or WLAN1_NAME.
 * @param[in]  pSetting: Points to the rtw_wifi_setting_t structure which information is gotten by @ref wifi_get_setting().
 * @return  RTW_SUCCESS or RTW_ERROR.
 */
int wifi_show_setting(const char *ifname,rtw_wifi_setting_t *pSetting);

/**
 * @brief  
Set the network mode according to the data rate its supported. 
 *			Driver works in BGN mode in default after driver initialization. This function is used to
 *			change wireless network mode for station mode before connecting to AP.
 * @param[in]  mode: Network mode to set. The value can be RTW_NETWORK_B/RTW_NETWORK_BG/RTW_NETWORK_BGN.
 * @return  RTW_SUCCESS or RTW_ERROR.
 */
int wifi_set_network_mode(rtw_network_mode_t mode);

/**
 * @brief	Get the network mode. 
 *			Driver works in BGN mode in default after driver initialization. This function is used to
 *			get the current wireless network mode for station mode.
 * @param[in]  pmode: Network mode to get.
 * @return  RTW_SUCCESS or RTW_ERROR.
 */
int wifi_get_network_mode(rtw_network_mode_t *pmode);

/**
 * @brief	Get the current network mode the network interface is using against the wireless AP.
 *			Driver will match its supported network mode with AP's supported network mode when connecting
 *			and choose the best network mode. This function will get the network mode used to connect to AP.
 * @param[in]  pmode: Current network mode to get.
 * @return  the current network mode used.
 * 	1) WIRELESS_11B: using 802.11b.
 * 	2) WIRELESS_11G: using 802.11g.
 * 	8) WIRELESS_11_24N: using 802.11n.
 * 	40) WIRELESS_11AC: using 802.11ac.
 * 	-1) RTW_ERROR: get fails.
 */
int wifi_get_cur_network_mode(void);

/**
 * @brief  Set the chip to start or stop the promiscuous mode.
 * @param[in]  enabled: enabled can be set 0, 1, 2, 3 and 4. if enabled is zero, disable the promisc, else enable the promisc.
 *                    - 0 means disable the promisc.
 *                    - 1 means enable the promisc special for all ethernet frames.
 *                    - 2 means enable the promisc special for Broadcast/Multicast ethernet frames.
 *                    - 3 means enable the promisc special for all 802.11 frames.
 *                    - 4 means enable the promisc special for Broadcast/Multicast 802.11 frames.
 * @param[in]  callback: the callback function which will 
 *  			  receive and process the netowork data.
 * @param[in]  len_used: specify if the the promisc data length is used.
 *				If len_used set to 1, packet(frame data) length will be saved and transferred to callback function.
 *
 * @return  RTW_SUCCESS or RTW_ERROR
 * @note  This function can be used to implement vendor specified simple configure.
 * @note  To fetch Ethernet frames, the len_used should be set to 1
 */
int wifi_set_promisc(rtw_rcr_level_t enabled, void (*callback)(unsigned char*, unsigned int, void*), unsigned char len_used);

/**
 * @brief  Let Wi-Fi enter promiscuous mode.
 * @param[in]  None
 * @return  None
 */
void wifi_enter_promisc_mode(void);

/** Set the wps phase
 *  
 * @param is_trigger_wps[in]   : to trigger wps function or not
 *
 * @return    RTW_SUCCESS or RTW_ERROR
 */
int wifi_set_wps_phase(unsigned char is_trigger_wps);

/**
 * @brief  Trigger Wi-Fi driver to restart an infrastructure Wi-Fi network.
 * @warning If a STA interface is active when this function is called, the softAP will
 *          start on the same channel as the STA. It will NOT use the channel provided!
 * @param[in]  ssid: A null terminated string containing the SSID name of the network.
 * @param[in]  security_type: 
 *                         - RTW_SECURITY_OPEN           - Open Security
 *                         - RTW_SECURITY_WPA_TKIP_PSK   - WPA Security
 *                         - RTW_SECURITY_WPA2_AES_PSK   - WPA2 Security using AES cipher
 *                         - RTW_SECURITY_WPA2_MIXED_PSK - WPA2 Security using AES and/or TKIP ciphers
 *                         - WEP security is NOT IMPLEMENTED. It is NOT SECURE!
 * @param[in]  password: A byte array containing the cleartext security key for the network.
 * @param[in]  ssid_len: The length of the SSID in bytes.
 * @param[in]  password_len: The length of the security_key in bytes.
 * @param[in]  channel: 802.11 channel number.
 * @return  RTW_SUCCESS: If successfully creates an AP.
 * @return  RTW_ERROR: If an error occurred.
 * @note  Please make sure the Wi-Fi is enabled before invoking this function. (@ref wifi_on())
 */
int wifi_restart_ap(
	unsigned char 		*ssid,
	rtw_security_t		security_type,
	unsigned char 		*password,
	int 				ssid_len,
	int 				password_len,
	int					channel);

/**
 * @brief  Set reconnection mode with configuration.
 * @param[in]  mode: Set 1/0 to enalbe/disable the reconnection mode.
 * @param[in]  retry_times: The number of retry limit.
 * @param[in]  timeout: The timeout value (in seconds).
 * @return  0 if success, otherwise return -1.
 * @note  Defining CONFIG_AUTO_RECONNECT in "autoconf.h" needs to be done before compiling,
 *			or this API won't be effective.
 * @note  The difference between @ref wifi_config_autoreconnect() and @ref wifi_set_autoreconnect() is that 
 *			user can specify the retry times and timeout value in @ref wifi_config_autoreconnect().
 *			But in @ref wifi_set_autoreconnect() these values are set with 3 retry limit and 5 seconds timeout as default.
 */
int wifi_config_autoreconnect(__u8 mode, __u8 retry_times, __u16 timeout);

/**
  * @brief  Set reconnection mode with 3 retry limit and 5 seconds timeout as default.
  * @param[in]  mode: Set 1/0 to enalbe/disable the reconnection mode.
  * @return  0 if success, otherwise return -1.
  * @note  Defining CONFIG_AUTO_RECONNECT in "autoconf.h" needs to be done before compiling,
  *			or this API won't be effective.
  * @note  The difference between @ref wifi_config_autoreconnect() and @ref wifi_set_autoreconnect() is that 
  *			user can specify the retry times and timeout value in @ref wifi_config_autoreconnect().
  *			But in @ref wifi_set_autoreconnect() these values are set with 3 retry limit and 5 seconds timeout as default.
  */
int wifi_set_autoreconnect(__u8 mode);

/**
  * @brief  Get the result of setting reconnection mode.
  * @param[out]  mode: Point to the result of setting reconnection mode.
  * @return  0 if success, otherwise return -1.
  * @note  Defining CONFIG_AUTO_RECONNECT in "autoconf.h" needs to be done before compiling,
  *			or this API won't be effective.
  */
int wifi_get_autoreconnect(__u8 *mode);

/**
 * @brief      Present the device disconnect reason while connecting.
 * @param      None
 * @return     The error code while connecting. (@ref rtw_connect_error_flag_t)
 *               - RTW_NO_ERROR
 *               - RTW_NONE_NETWORK
 *               - RTW_CONNECT_FAIL
 *               - RTW_WRONG_PASSWORD
 *               - RTW_4WAY_HANDSHAKE_TIMEOUT
 *               - RTW_DHCP_FAIL
 *               - RTW_AUTH_FAIL
 *               - RTW_ASSOC_FAIL
 *               - RTW_DEAUTH_DEASSOC
 *               - RTW_UNKNOWN (initial status)
 */
int wifi_get_last_error(void);


#ifdef CONFIG_CUSTOM_IE
#ifndef BIT
#define BIT(x)	((__u32)1 << (x))
#endif

#ifndef _CUSTOM_IE_TYPE_
#define _CUSTOM_IE_TYPE_
/**
  * @brief  The enumeration is transmission type for wifi custom ie.
  */
enum CUSTOM_IE_TYPE{
	PROBE_REQ = BIT(0),
	PROBE_RSP = BIT(1),
	BEACON	  = BIT(2),
	ASSOC_REQ =BIT(3),
};
typedef __u32 rtw_custom_ie_type_t;
#endif /* _CUSTOM_IE_TYPE_ */

/* ie format
 * +-----------+--------+-----------------------+
 * |element ID | length | content in length byte|
 * +-----------+--------+-----------------------+
 *
 * type: refer to CUSTOM_IE_TYPE
 */
#ifndef _CUS_IE_
#define _CUS_IE_
/**
  * @brief  The structure is used to set WIFI custom ie list, and type match CUSTOM_IE_TYPE.\n
  *			The ie will be transmitted according to the type.
  */
typedef struct _cus_ie{
	__u8 *ie;
	__u8 type;
}rtw_custom_ie_t, *p_rtw_custom_ie_t;
#endif /* _CUS_IE_ */

/**
  * @brief  Setup custom ie list.
  * @warning  This API can't be executed twice before deleting the previous custom ie list.
  * @param[in]  cus_ie: Pointer to WIFI CUSTOM IE list.
  * @param[in]  ie_num: The number of WIFI CUSTOM IE list.
  * @return  0 if success, otherwise return -1.
  * @note  Defininig CONFIG_CUSTOM_IE in "autoconf.h" needs to be done before compiling,
  *			or this API won't be effective.
  */
int wifi_add_custom_ie(void *cus_ie, int ie_num);

/**
  * @brief  Update the item in WIFI CUSTOM IE list.
  * @param[in]  cus_ie: Pointer to WIFI CUSTOM IE address.
  * @param[in]  ie_index: Index of WIFI CUSTOM IE list.
  * @return  0 if success, otherwise return -1.
  * @note  Defininig CONFIG_CUSTOM_IE in "autoconf.h" needs to be done before compiling,
  *			or this API won't be effective.
  */
int wifi_update_custom_ie(void *cus_ie, int ie_index);

/**
  * @brief  Delete WIFI CUSTOM IE list.
  * @param  None
  * @return  0 if success, otherwise return -1.
  * @note  Defininig CONFIG_CUSTOM_IE in "autoconf.h" needs to be done before compiling,
  *			or this API won't be effective.
  */
int wifi_del_custom_ie(void);
#endif

#ifdef CONFIG_PROMISC

/**
  * @brief  Initialize packet filter related data.
  * @param  None
  * @return  None
  */
void wifi_init_packet_filter(void);

/**
  * @brief  Add packet filter.
  * @param[in]  filter_id: The filter id.
  * @param[in]  patt: Point to the filter pattern.
  * @param[in]  rule: Point to the filter rule.
  * @return  0 if success, otherwise return -1.
  * @note  For now, the maximum number of filters is 5.
  */
int wifi_add_packet_filter(unsigned char filter_id, rtw_packet_filter_pattern_t *patt, rtw_packet_filter_rule_t rule);

/**
  * @brief  Enable the packet filter.
  * @param[in]  filter_id: The filter id.
  * @return  0 if success, otherwise return -1.
  * @note  The filter can be used only if it has been enabled.
  */
int wifi_enable_packet_filter(unsigned char filter_id);

/**
  * @brief  Disable the packet filter.
  * @param[in]  filter_id: The filter id.
  * @return  0 if success, otherwise return -1.
  */
int wifi_disable_packet_filter(unsigned char filter_id);

/**
  * @brief  Remove the packet filter.
  * @param[in]  filter_id: The filter id.
  * @return  0 if success, otherwise return -1.
  */
int wifi_remove_packet_filter(unsigned char filter_id);

/**
  * @brief: Only receive the packets sent by the specified ap and phone in promisc mode.
  * @param[in]  enable: set 1 to enable filter, set 0 to disable this filter function.
  * @param[in]  ap_mac: if 'enable' equals 0, it's useless; if 'enable' equals 1, this value is the ap's mac address.
  * @param[in]  phone_mac: if 'enable' equals 0, it's useless; if 'enable' equals 1, this value is the phone's mac address.
  * @return  None.
  * @note  Please invoke this function as "wifi_filter_by_ap_and_phone_mac(0,NULL,NULL)" before exiting promisc mode if you enabled it during the promisc mode.
  */
void wifi_filter_by_ap_and_phone_mac(u8 enable, void *ap_mac, void *phone_mac);
#endif

/**
  * @brief  Get antenna infomation.
  * @param[in]  antenna: Points to store the antenna value gotten from driver, 0: main, 1: aux.
  * @return  0 if success, otherwise return -1.
  */
#ifdef CONFIG_ANTENNA_DIVERSITY
int wifi_get_antenna_info(unsigned char *antenna);
#endif // #ifdef CONFIG_ANTENNA_DIVERSITY

/**
 * @brief      SW reporting mgnt packets to wifi_indication() during wifi_connect().
 * @param[in]  enable:
 *                - 0: disable mode(default), SW doesn't report
 *                - 1: enable mode, SW reports mgnt packets
 * @return     None
 * @note       Please make sure the Wi-Fi is enabled before invoking this function. (@ref wifi_on())
 */
void wifi_connect_monitor_mgnt(int enable);

/**
  * @brief:	config mode of HW indicating packets(mgnt and data) and SW reporting packets to wifi_indication().
  * @param[in]	
  *		0: disable mode(default), HW only indicate bssid-matched pkts and SW don't report.
  *		1: normal mode, HW only indicate bssid-matched pkts and SW report.
  *		2: wild mode, HW indicate all pkts and SW report.
  * 
  * @return	None
  * @note None
  */
void wifi_set_indicate_mgnt(int enable);


/**
 * @brief  Get the information of MP driver
 * @param[out]  ability : 0x1 stand for mp driver, and 0x0 stand for normal driver
 * @return  RTW_SUCCESS
 */
int wifi_get_drv_ability(uint32_t *ability);

/**
 * @brief  Set channel plan into flash/efuse, must reboot after setting channel plan
 * @param[in]  channel_plan : the value of channel plan, define in wifi_constants.h
 * @return  RTW_SUCCESS or RTW_ERROR
 */
int wifi_set_channel_plan(uint8_t channel_plan);

/**
 * @brief  Get channel plan from calibration section
 * @param[out]  channel_plan : point to the value of channel plan, define in wifi_constants.h
 * @return  RTW_SUCCESS or RTW_ERROR
 */
int wifi_get_channel_plan(uint8_t *channel_plan);

#ifdef CONFIG_AP_MODE
/**
 * @brief  Enable packets forwarding in ap mode
 * @return  RTW_SUCCESS
 */
int wifi_enable_forwarding(void);

/**
 * @brief  Disable packets forwarding in ap mode
 * @return  RTW_SUCCESS
 */
int wifi_disable_forwarding(void);
#endif

#ifdef CONFIG_CONCURRENT_MODE
/**
 * @brief  Set flag for concurrent mode wlan1 issue_deauth when channel switched by wlan0
 *          usage: wifi_set_ch_deauth(0) -> wlan0 wifi_connect -> wifi_set_ch_deauth(1)
 * @param[in]  enable : 0 for disable and 1 for enable
 * @return  RTW_SUCCESS
 */
int wifi_set_ch_deauth(__u8 enable);
#endif

///@name Ameba1 Only 
///@{
/**
 * @brief enable AP sending QoS Null0 Data to poll Sta be alive
 * @param[in]  enabled: enabled can be set to 0,1.
 *			- 0	means enable.
 *			- 1	means disable.									
 * @return  None
 */
void wifi_set_ap_polling_sta(__u8 enabled);
///@}

#ifdef CONFIG_SW_MAILBOX_EN
/**
 * @brief  interface for bt to set mailbox info to wifi, mostly for coexistence usage
 * @param[in]  data : pointer of mailbox data
 * @param[in]  len : length of mailbox data
 * @return  0 if success, otherwise return -1
 */
int mailbox_to_wifi(u8 *data, u8 len);
#else
#define mailbox_to_wifi(data, len)
#endif

#ifdef CONFIG_WOWLAN_TCP_KEEP_ALIVE
/**
 * @brief  construct a tcp packet that offload to wlan. wlan would keep sending this packet to tcp server.
 *
 * @param[in]  socket_fd : tcp socket
 * @param[in]  content : tcp payload
 * @param[in]  len : tcp payload size
 * @param[in]  interval_ms : send this packeter every interval_ms milliseconds
 * @return  RTW_SUCCESS
 */
int wifi_set_tcp_keep_alive_offload(int socket_fd, uint8_t *content, size_t len, uint32_t interval_ms);
#endif

// WoWlan related
//-------------------------------------------------------------//
#ifdef CONFIG_WOWLAN
typedef struct {
	unsigned int filter_id;
	unsigned int polarity;
	unsigned int type;
	unsigned int offset;	
	unsigned char *bitmask;
	unsigned char *pattern;
} wowlan_pattern_param_t;

int wifi_wowlan_ctrl(int enable);
int wifi_wowlan_set_pattern(wowlan_pattern_t pattern);
#endif
//-------------------------------------------------------------//
#ifdef CONFIG_APP_CTRL_RF_ONOFF
extern void rtw_rf_cmd(u32 Status);
extern u32 rtw_get_tsf(u32 Port);
#endif

/*
 *@brief get WIFI band type
 *@retval  the support band type.
 *	WL_BAND_2_4G: only support 2.4G
 *	WL_BAND_5G: only support 5G
 *	WL_BAND_2_4G_5G_BOTH: support both 2.4G and 5G
 *	WL_BAND_NOT_MATCH: channel plan is not match with chip band type
 */
WL_BAND_TYPE wifi_get_band_type(void);


#ifdef LOW_POWER_WIFI_CONNECT
int wifi_set_psk_eap_interval(uint16_t psk_interval, uint16_t eap_interval);
int wifi_set_null1_param(uint8_t check_period, uint8_t pkt_num, uint8_t limit, uint8_t interval);
#endif

/**
 * @brief  Switch channel of softap and inform connected stations to keep wifi connection.
 * @param[in]  new_channel: The channel number that softap will switch to.
 * @return  RTW_SUCCESS: If switching channel is successful.
 * @return  RTW_ERROR: If switching channel is failed.
 */
int wifi_ap_switch_chl_and_inform(unsigned char new_channel);

/**
 * @brief  Set initial gain index.
 * @param[in]  igi: the new initial gain index value.
 * @param[in]  enable: 1, fixed igi; 0, dynamic igi.
 * @return 0: success.
 * @return -1: fail.
 */
int wifi_set_igi(uint8_t igi, uint8_t enable);

/**
 * @brief  Set softap uapsd feature.
 * @param[in]  enable: 1, enable uapsd; 0, disable uapsd.
 * @return 0: success.
 */
int wifi_set_ap_uapsd(uint8_t enable);

/**
 * @brief  Set softap bcn period, need do wifi off and on again to write the new value into register.
 * @param[in]  period: default 100ms.
 * @return 0: success.
 */
int wifi_set_bcn_period(uint16_t period);

/**
* @brief  Set tx power percentage.
* @param[in] power percentage idx 0 to 4.
* 0, 100%, default target output power.
* 1, 75% 
* 2, 50%
* 3, 25%
* 4, 12.5%
* @return 0: success.
*/
int wifi_set_tx_power_percentage(unsigned long power_percentage_idx);

/**
* @brief  Set interval for SoftAP group key rotation.
*         Can be used to adjust interval while SoftAP is running and connected to STA.
* @param[in] interval: time interval in minutes, 1 min to 1440 min(1 day)
* @return RTW_SUCCESS or RTW_ERROR
*/
int wifi_set_softap_gkey_interval(uint32_t interval);

/**
* @brief  Set slient softap. No beacon will be sent untill client assoc success
*         Support AP mode and CONCURRENT mode
*         When no client connect need to restart softap to resume no beacon
 * @param[in]  enable: 1, enable slient; 0, disable slient.
 * @return 0: success.
*/
int wifi_set_slient_softap(rtw_bool_t enable);

/**
* @brief  Between each scan channel, switch back to softap channel and stay on it for custom_beacon_period.
*		  The "custom_beacon_period" is set through "wifi_set_bcn_period", default 100ms.
*         Support only if client is associated with softap in CONCURRENT mode
 * @param[in]  enable: 1, enable tune window time to custom_beacon_period; 0, default window time 30ms.
 * @return 0: success.
*/
int wifi_tune_ap_chn_en(int enable);

typedef struct {
    char country_code[2];
    int count;
} CountryCodeCount;

/**
* @brief  Call "wifi_scan_networks_with_extended_countryinfo" to scan the country code of surronding APs
*         then call "wifi_set_channel_plan_by_country_code" to set the channel plan based on scanned country code
*         Enable "wext_auto_set_adaptivity"
* @param[in] 
* @return 
*/
void wifi_scan_country_code_and_set_channel_plan(void);

/**
* @brief  Call "wifi_set_country" and set channel plan accordingly
* @param[in] country_code_get: char that saved the country code.
* @return 
*/
void wifi_set_channel_plan_by_country_code(unsigned char* country_code);

/**
* @brief  Call "wifi_scan_networks_with_extended_countryinfo" and memcpy the country code. Set channel plan accordingly
* @param[in] country_code_get: char that saved the country code which follows the logic of WiFi NIC.
* @return 
*/
void wifi_get_country_code(unsigned char* country_code_get);

/**
* @brief  Full scan on the APs in the environment to read the country code from the beacon and saved.
*         This API will cause a 4 seconds waiting time to finish the full scan.
* @param
* @return 
*/
void wifi_scan_networks_with_extended_countryinfo(void);

/**
* @brief  Save the frequency of different country code from the environment.
* @param[in] CountryCodeCount *country_code_counts: struct that saves the country code and its corresponding frequency
* @param[in] int *num_codes: number of different country codes from the environment.
* @param[in] char *code: current country code from the AP.
* @return 
*/
void wifi_add_country_code(CountryCodeCount *country_code_counts, int *num_codes, char *code);

/**
* @brief  Copy the country code that been processed based on the logic of WiFi NIC.
* @param[in] CountryCodeCount *country_code_counts: struct that saves the country code and its corresponding frequency
* @param[in] int *num_codes: number of different country codes from the environment.
* @return 
*/
void wifi_return_country_code(CountryCodeCount *country_code_counts, int *num_codes);

/**
 * @brief  Get station security type
 * @return  Station security type
 */
int wifi_get_sta_security_type(void);

#ifdef __cplusplus
}
#endif

#endif // __WIFI_API_H

