#ifndef WIFI_H
#define WIFI_H

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <easy/utils.h>
#include <easy/if_utils.h>
#include <wifidefs.h>

struct netif_ap;
struct netif_bk;
struct wifi_radio_opclass;

#define WIFI_REASON_DISASSOC_STA_HAS_LEFT 8
#define WIFI_REASON_BSS_TRANSITION_DISASSOC 12
#define WIFI_REASON_SERVICE_NOT_AUTHORIZED_IN_THIS_LOCATION 30
#define WIFI_REASON_AP_INITIATED 47

#define WIFI_BEACON_PERIOD_MS 100

typedef char timestamp_t[32];

/* Extra - try to remove it ... */
struct supp_channel {
	uint8_t channel;
	uint8_t pref;
	uint8_t dfs;
	char dfs_state[32];
	uint32_t cac_time;
	uint32_t nop_time;
	uint8_t ctrl_channels[32];
};

struct wifi_opclass_supported_element {
	uint8_t id;                     /* class number */
	int8_t max_txpower;
	uint32_t bandwidth;
	uint32_t num_exclude_channels;
	uint8_t *exclude_chanlist;      /* list of non-operable channels */
	uint32_t num_supported_channels;
	struct supp_channel supp_chanlist[64];         /*list of supporting channels for each class*/
};

struct wifi_radio_status {
	struct wifi_radio info;

	uint8_t opclass;
	uint8_t channel;
	uint32_t bandwidth;
};

enum nbr_param_bcn_mode {
	NBR_PARAM_BCN_ACTIVE  = 1 << 0,
	NBR_PARAM_BCN_PASSIVE = 1 << 1,
	NBR_PARAM_BCN_TABLE   = 1 << 2,
};

struct wifi_request_neighbor_param {
	uint8_t opclass;
	uint8_t channel;
	uint8_t *bssid;
	uint8_t rrm_mode;
	uint8_t reporting_detail;
	uint8_t ssid_len;
	char *ssid;
	uint8_t num_report;
	uint8_t *report;
	uint8_t num_element;
	uint8_t *element;
};

struct wifi_ap_status {
	struct wifi_ap ap;
};

struct wifi_bsta_status {
	struct wifi_sta sta;

	uint8_t ssid[33];
	enum wifi_band band;
	enum wifi_bw bandwidth;
	uint32_t channel;
	uint32_t frequency;
	bool mode4addr;
};

/* WiFi radio APIs */
int wifi_radio_status(const char *name, struct wifi_radio_status *status);
int wifi_scan(const char *name, struct scan_param_ex *p,
	      int num_opclass, uint8_t *opclass,
	      int num_channel, uint8_t *channel);
int wifi_get_scan_results(const char *name, struct wifi_bss *bsss, int *num, bool cache);
int wifi_get_channels_info(const char *name, struct chan_entry *ch_entry, int *num);
int wifi_start_cac(const char *name, int channel, enum wifi_bw bw,
		   enum wifi_cac_method method);
int wifi_stop_cac(const char *name, int channel, enum wifi_bw bw);
int wifi_opclass_preferences(const char *radio,
			     struct wifi_radio_opclass *opclass);

/** WiFi interface APIs */
int wifi_subscribe_frame(const char *ifname, uint8_t type, uint8_t stype);
int wifi_unsubscribe_frame(const char *ifname, uint8_t type, uint8_t stype);
int wifi_set_4addr(const char *ifname, bool enable);
int wifi_get_4addr(struct netif_bk *bk, bool *enabled);


/* WiFi AP interface specific APIs */
int wifi_ap_status(const char *name, struct wifi_ap_status *ap_status);
int wifi_ap_stats(const char *ifname, struct wifi_ap_stats *stats);
int wifi_get_assoclist(struct netif_ap *ap, uint8_t *stas, int *num_stas);
int wifi_get_stations(struct netif_ap *ap, struct wifi_sta *sta, int *num);
int wifi_get_station(struct netif_ap *ap, uint8_t *sta_addr, struct wifi_sta *sta);
#if (EASYMESH_VERSION >= 6)
int wifi_get_mld_stations(struct netif_ap *ap, struct wifi_mlsta *mlsta, int *num);
int wifi_get_mld_station(struct netif_ap *ap, uint8_t *mld_addr, uint8_t *link_addr, struct wifi_mlsta *link);
#endif
int wifi_disconnect_sta(const char *ifname, uint8_t *sta, uint16_t reason);
int wifi_restrict_sta(struct netif_ap *ap, uint8_t *sta, bool block_sta);
int wifi_get_restricted_stas(struct netif_ap *ap, uint8_t *stas, int *num);
int wifi_monitor_sta(const char *ifname, uint8_t *sta, struct wifi_monsta_config *cfg);
int wifi_monitor_sta_add(const char *ifname, uint8_t *sta);
int wifi_monitor_sta_del(const char *ifname, uint8_t *sta);
int wifi_get_monitor_sta(const char *ifname, uint8_t *sta, struct wifi_monsta *mon);

int wifi_add_neighbor(const char *ifname, struct nbr *nbr);
int wifi_del_neighbor(const char *ifname, unsigned char *bssid);
int wifi_get_neighbor_list(const char *ifname, struct nbr *nbrs, int *nr);
int wifi_req_btm(const char *ifname, uint8_t *sta, uint8_t pref_num, struct nbr *pref,
		 struct wifi_btmreq *req);
int wifi_chan_switch(const char *ifname, struct chan_switch_param *param);
int wifi_ap_set_state(const char *ifname, bool up);
int wifi_add_vendor_ie(const char *ifname, int mgmt, char *oui, char *data);
int wifi_del_vendor_ie(const char *ifname, int mgmt, char *oui, char *data);
int wifi_req_neighbor(const char *ifname, uint8_t *sta,
		      struct wifi_request_neighbor_param *param);

int wifi_bsta_status(const char *ifname, struct wifi_bsta_status *bsta_status);
int wifi_set_qos_map(const char *ifname, uint8_t *qos_map, size_t qos_map_len);
int wifi_send_qos_map_conf(const char *ifname, uint8_t *macaddr);

/* WiFi STA interface APIs */
int wifi_sta_info(const char *ifname, struct wifi_sta *sta);
int wifi_bsta_disconnect(struct netif_bk *bk, uint32_t reason);

int wifi_set_ap_mbo_association_mode(const char *ifname, bool disallow);

/* WiFi send managment action frame*/
int wifi_send_action(const char *ifname, uint8_t *dst_mac,
				uint8_t *src_mac, uint32_t wait, uint32_t freq, const uint8_t *bytes, int len);

/* WiFi WPS APIs */
int wifi_initiate_wpspbc(const char *ifname, bool is_bsta);

int c2f(int chan);
int f2c(int freq);
int c2f_band(int chan, enum wifi_band band);
uint32_t wifi_bw_to_bw(enum wifi_bw bw);
enum wifi_bw bw_to_wifi_bw(uint32_t bandwidth);

#endif /* WIFI_H */


