/*
 * wifi_dataelements.h
 * WiFi DataElements-v3.0 definitions header.
 *
 * Copyright (C) 2019-2025 IOPSYS Software Solutions AB.
 *
 */

#ifndef WIFI_DATAELEMENTS_H
#define WIFI_DATAELEMENTS_H

#include <libubox/list.h>
#include <easy/easy.h>
#include <wifidefs.h>

#include <stdint.h>
#include <stdbool.h>
#include <sys/time.h>

#ifdef __cplusplus
extern "C" {
#endif

#define WIFI_DATAELEMENTS_VER_1_0	"1.0"
#define WIFI_DATAELEMENTS_VER_2_0	"2.0"
#define WIFI_DATAELEMENTS_VER_3_0	"3.0"


typedef char timestamp_t[32];
typedef uint8_t guid_t[16];
typedef uint8_t macaddr_t[6], node_id_t[6];

enum wifi_bsstype {
	WIFI_BSSTYPE_FBSS,
	WIFI_BSSTYPE_BBSS,
	WIFI_BSSTYPE_COMBINED,
};

#define WIFI_RADIO_OPCLASS_MOST_PREFERRED    15 << 4
#define WIFI_RADIO_OPCLASS_NON_OPERABLE      0

enum wifi_radio_opclass_dfs {
	WIFI_RADIO_OPCLASS_CHANNEL_DFS_NONE,        /**< CAC not required */
	WIFI_RADIO_OPCLASS_CHANNEL_DFS_USABLE,      /**< CAC required but not done yet */
	WIFI_RADIO_OPCLASS_CHANNEL_DFS_AVAILABLE,   /**< CAC required and done; channel is available */
	WIFI_RADIO_OPCLASS_CHANNEL_DFS_NOP,         /**< channel unavailable; in NOP state after radar hit */
	WIFI_RADIO_OPCLASS_CHANNEL_DFS_CAC,         /**< Pre-ISM CAC ongoing */
};

struct wifi_radio_opclass_channel {
	uint8_t channel;
	uint8_t preference;               /**< preference value */
	enum wifi_radio_opclass_dfs dfs;  /**< DFS channel state */
	uint32_t cac_time;                /**< CAC time needed */
	uint32_t nop_time;                /**< remaining nop time */
	uint32_t cac_methods;		  /**< bitmap of wifi_cac_method */
	uint8_t ctrl_channels[32];
};

struct wifi_radio_opclass_entry {
	uint8_t id;                       /**< opclass id */
	int bandwidth;
	int band;
	int max_txpower;                  /**< max allowed Tx power in dBm */
	int num_channel;
	struct wifi_radio_opclass_channel channel[64];  /**< channel list */
};

struct wifi_radio_opclass {
	struct timespec entry_time;
	int num_opclass;
	struct wifi_radio_opclass_entry opclass[64];
};

struct wifi_sta_meas_report {
	struct list_head list;

	uint8_t agent_macaddr[6]; /* AL-macaddr of sender */
	time_t rpt_time;          /* time when this report is logged */

	/* Measurement report for Beacon report follows */
	uint8_t opclass;
	uint8_t channel;
	uint64_t meas_start_time; /* STA's TSF timer */
	uint16_t meas_duration;
	uint8_t rfi;              /* Reported Frame Information */
	uint8_t rcpi;
	uint8_t rsni;
	uint8_t bssid[6];
	uint8_t antena_id;
	uint32_t parent_tsf;
	uint8_t optional[];       /* optional subelements */
};

struct unassoc_sta_metrics {
	uint8_t agent_macaddr[6];
	uint8_t bssid[6];
	uint8_t channel;
	uint32_t time_delta;
	uint8_t ul_rcpi;
	time_t rpt_time;          /* time when this report is logged */
	struct list_head list;
};

struct wifi_cac_available_channel {
	uint8_t opclass;
	uint8_t channel;
	uint32_t cleared;	/* in minutes since available; 0 for non-dfs */
	struct list_head list;
};

struct wifi_cac_nop_channel {
	uint8_t opclass;
	uint8_t channel;
	uint32_t remaining;	/* in secs for NOP to finish */
	struct list_head list;
};

struct wifi_cac_active_channel {
	uint8_t opclass;
	uint8_t channel;
	uint32_t remaining;	/* in secs to complete CAC */
	struct list_head list;
};

struct wifi_cac_status {
	timestamp_t tsp;
	struct list_head available_chlist;	/* list of wifi_cac_available_channel */
	struct list_head nop_chlist;		/* list of wifi_cac_nop_channel */
	struct list_head cac_chlist;		/* list of wifi_cac_active_channel */
	struct list_head list;
};

struct wifi_tid_queuesize {
	uint8_t tid;
	uint32_t size;
	struct list_head list;
};

struct wifi_akm_suite {
	uint8_t oui[3];
	uint8_t type;
};

struct wifi_wifi6_capabilities {
	bool he160;
	bool he8080;
	uint8_t mcs_nss_len;
	union {
		uint8_t mcs_nss_4[4];
		uint8_t mcs_nss_8[8];
		uint8_t mcs_nss_12[12];
	};
	bool su_beamformer;
	bool su_beamformee;
	bool mu_beamformer;
	bool beamformee_le80;
	bool beamformee_gt80;
	bool ul_mumimo;
	bool ul_ofdma;
	bool dl_ofdma;
	uint8_t max_dl_mumimo;
	uint8_t max_ul_mumimo;
	uint8_t max_dl_ofdma;
	uint8_t max_ul_ofdma;
	bool rts;
	bool mu_rts;
	bool multi_bssid;
	bool mu_edca;
	bool twt_requester;
	bool twt_responder;
	bool spatial_reuse;
	bool anticipated_ch_usage;
};

struct wifi7_mlo_freqsep {
	uint8_t ruid[6];
	uint8_t sep;
};

struct wifi_wifi7_capabilities {
	bool emlmr;
	bool emlsr;
	bool str;
	bool nstr;
	bool tidlinkmap;
	uint32_t num_freqsep_str;
	uint32_t num_freqsep_emlsr;
	uint32_t num_freqsep_emlmr;
#define MAX_NUM_MLO_FREQ_SEP	4
	struct wifi7_mlo_freqsep str_freqsep[MAX_NUM_MLO_FREQ_SEP];
	struct wifi7_mlo_freqsep emlsr_freqsep[MAX_NUM_MLO_FREQ_SEP];
	struct wifi7_mlo_freqsep emlmr_freqsep[MAX_NUM_MLO_FREQ_SEP];
};

/* maps to capability bytes in respective TLVs */
struct wifi_caps_element {
#define HT_CAP_VALID           0x4
#define VHT_CAP_VALID          0x8
#define HE_CAP_VALID           0x20
#define EHT_CAP_VALID          0x40
#define WIFI6_AP_CAP_VALID     0x80
#define WIFI6_BSTA_CAP_VALID   0x100
	uint8_t ht;
	uint8_t vht[6];
	uint8_t he[15];		/* 1 (supp-mcs-len), 12 (Tx Rx mcs), 2 (others) */
	uint32_t valid;		/* bitmap of *_CAP_VALID */
};

struct wifi_opclass_supported_element {
	uint8_t id;                     /* class number */
	int8_t max_txpower;
	uint32_t num_exclude_channels;
	uint8_t *exclude_chanlist;      /* list of non-operable channels */
	uint32_t num_channels;
	uint8_t *chanlist;
	struct list_head list;
};

struct wifi_opclass_current_element {
	timestamp_t tsp;
	uint8_t id;
	uint8_t channel;
	int8_t txpower;
};

struct wifi_opclass_disallowed_element {
	bool enabled;
	uint8_t opclass;
	uint32_t num_channels;
	uint8_t *chanlist;
};

#define STEER_STATS_NO_DATA	UINT64_MAX

struct wifi_steer_summary {
	uint64_t no_candidate_cnt;        /* num times STA couldn't be steered due to no suitable target AP */
	uint64_t blacklist_attempt_cnt;   /* num times assoc-control based STA steering attempted */
	uint64_t blacklist_success_cnt;   /* num times STA successfully steered via assoc-control */
	uint64_t blacklist_failure_cnt;   /* num times assoc-control failed to steer STA */
	uint64_t btm_attempt_cnt;         /* num times BTM based STA steering attempted */
	uint64_t btm_success_cnt;         /* num times STA successfully steered via BTM */
	uint64_t btm_failure_cnt;         /* num times BTM failed to steer STA */
	uint64_t btm_query_resp_cnt;      /* num times BTM-requests sent upon receiving BTM-queries */
	struct timespec last_attempt_tsp; /* Time when STA steering was last attempted */
	struct timespec last_steer_tsp;   /* Time when STA was last steered succesfully */
};

enum steer_trigger {
	STEER_TRIGGER_UNKNOWN,
	STEER_TRIGGER_UTIL,
	STEER_TRIGGER_LINK_QUALITY,
	STEER_TRIGGER_THPUT,
	STEER_TRIGGER_BK_UTIL
};

enum steer_method {
	STEER_METHOD_ASSOC_CTL,		/* STA association-control */
	STEER_METHOD_BTM_REQ,		/* BTM Request */
	STEER_METHOD_ASYNC_BTM,		/* BTM Query */
};

/* history entry of a steering attempt */
struct wifi_steer_history {
	struct timespec time;
	time_t steer_time;
	uint8_t src_bssid[6];
	enum steer_trigger trigger;
	enum steer_method method;
	uint8_t dst_bssid[6];	/* zero macaddr for failed attempt */
	uint32_t duration;	/* 0s for failed attempt */

	int complete;		/* not an ongoing attempt */

	uint8_t src_rcpi;
	uint8_t dst_rcpi;
};

#define MAX_STEER_HISTORY	10

struct wifi_multiap_sta {
	struct wifi_steer_summary steer_summary;
	uint8_t num_steer_hist;
	struct wifi_steer_history steer_history[MAX_STEER_HISTORY];
	int first, next;	/* indices in steer_history */

	//int pending_btm_resp_num;
	//int latest_assoc_cntrl_mid;
};

struct wifi_sta_element {
	int invalidate;
	time_t tsp;                   /* when the last STA-Link metrics response received */
	uint32_t time_delta;          /* tsp - time_delta (in ms) = when STA's metrics actually collected */
	uint8_t macaddr[6];
	uint8_t bssid[6];
	struct wifi_caps_element caps;
	struct wifi_wifi6_capabilities wifi6caps;
	uint32_t dl_rate;             /* latest data rate in Kbps: ap -> sta */
	uint32_t ul_rate;             /* latest data rate in Kbps: sta -> ap */
	unsigned long ul_utilization; /* time in msecs for receive from sta */
	unsigned long dl_utilization; /* time in msecs for transmit to sta */
	uint32_t dl_est_thput;        /* in Mbps */
	uint32_t ul_est_thput;        /* in Mbps */
	uint8_t rcpi;
	uint32_t conn_time;           /* in secs since last associated */
	uint64_t tx_bytes;            /* transmit bytes count: ap -> sta */
	uint64_t rx_bytes;            /* receive bytes count: sta -> ap */
	uint32_t tx_pkts;
	uint32_t rx_pkts;
	uint32_t tx_errors;
	uint32_t rx_errors;
	uint32_t rtx_pkts;            /* total retransmitted packets */
	struct ip_address ipv4_addr;
	struct ip_address ipv6_addr;
	char hostname[256];
	uint8_t num_meas_reports;
	struct list_head meas_reportlist;   /* list of wifi_sta_meas_report */

	struct list_head umetriclist;       /* list of struct unassoc_sta_metrics */

	size_t reassoc_framelen;
	uint8_t *reassoc_frame;
	struct list_head tid_qsizelist;     /* list of wifi_tid_queuesize */
	struct wifi_multiap_sta mapsta;
};

struct wifi_multiap_steering {
	uint64_t blacklist_attempt_cnt;
	uint64_t btm_attempt_cnt;
	uint64_t btm_query_resp_cnt;
};

enum wifi_sta_event_pending {
	WIFI_STA_EV_NONE,
	WIFI_STA_EV_ASSOC    = 1 << 0,
	WIFI_STA_EV_DISASSOC = 1 << 1,
	WIFI_STA_EV_FAIL     = 1 << 2,
};

struct wifi_sta_events {
	uint32_t pending;	/* bitmap of WIFI_STA_EV_* */
	uint32_t num_assoc;
	uint32_t num_disassoc;
	uint32_t num_fail;
	struct list_head assoclist;     /* list of wifi_sta_element */
	struct list_head disassoclist;  /* list of wifi_sta_element */
	struct list_head failconnlist;  /* list of wifi_sta_element */
};


enum counter_unit { COUNTER_UNIT_KB = 1, COUNTER_UNIT_MB = 2 };

/* Estimated Service Parameters bitflags */
#define ESP_AC_BE	0x80
#define ESP_AC_BK	0x40
#define ESP_AC_VO	0x20
#define ESP_AC_VI	0x10

struct wifi_bss_element {
	struct list_head list;
	int invalidate;
	time_t tsp;
	uint8_t bssid[6];
	uint8_t ruid[6];
	uint8_t ssidlen;
	char ssid[33];
	bool enabled;
	uint32_t uptime; /* 'LastChange' in TR-181 */
	uint64_t tx_ucast_bytes;
	uint64_t rx_ucast_bytes;
	uint64_t tx_mcast_bytes;
	uint64_t rx_mcast_bytes;
	uint64_t tx_bcast_bytes;
	uint64_t rx_bcast_bytes;
	enum counter_unit unit;

	/** Estimated Service Parameters Information */
	uint8_t esp_ac;			/* bitmap of ESP_AC_* */
	uint8_t est_wmm_be[3];
	uint8_t est_wmm_bk[3];
	uint8_t est_wmm_vi[3];
	uint8_t est_wmm_vo[3];
	uint32_t num_stations;

	bool p1_bsta_disallowed;
	bool p2_bsta_disallowed;
	bool sta_assoc_allowed;
	bool is_bbss;
	bool is_fbss;
	bool r1_disallowed;
	bool r2_disallowed;
	bool multi_bssid;
	bool transmitted_bssid;

	struct wifi_multiap_steering steer_stats;

	uint8_t ch_util;
};

struct wifi_affiliated_ap_element {
	struct list_head list;
	int invalidate;
	uint8_t ruid[6];
	uint8_t bssid[6];
	uint8_t linkid;
	uint8_t punct_bitmap[2];

	uint64_t tx_packets;
	uint64_t rx_packets;
	uint64_t tx_errors;
	uint64_t tx_ucast_bytes;
	uint64_t rx_ucast_bytes;
	uint64_t tx_mcast_bytes;
	uint64_t rx_mcast_bytes;
	uint64_t tx_bcast_bytes;
	uint64_t rx_bcast_bytes;

	uint8_t esp_ac;			/* bitmap of ESP_AC_* */
	uint8_t est_wmm_be[3];
	uint8_t est_wmm_bk[3];
	uint8_t est_wmm_vi[3];
	uint8_t est_wmm_vo[3];
};

struct wifi_affiliated_sta_element {
	struct list_head list;
	uint8_t macaddr[6];
	uint8_t bssid[6];
	uint8_t ruid[6];              /* radio-id hosting the affiliated-bSTA */
	uint64_t tx_bytes;            /* total bytes tx'd to this affiliated STA */
	uint64_t rx_bytes;            /* total bytes rx'd to this affiliated STA */
	uint64_t tx_packets;
	uint64_t rx_packets;
	uint64_t tx_errors;
	uint64_t rx_errors;
	uint8_t rcpi;
	uint32_t dl_rate;             /* latest data rate in Kbps: ap -> sta */
	uint32_t ul_rate;             /* latest data rate in Kbps: sta -> ap */
	unsigned long ul_utilization; /* time in msecs for receive from sta */
	unsigned long dl_utilization; /* time in msecs for transmit to sta */
	uint32_t time_delta;          /* tsp - time_delta => when dl/ul_est_thput measured */
	uint32_t dl_est_thput;        /* in Mbps */
	uint32_t ul_est_thput;        /* in Mbps */
};

struct wifi_ttlm_element {
	struct list_head list;
	uint8_t tid;
	uint8_t dir;
	uint8_t linkid;
};

struct wifi_stamld_element {
	struct list_head list;
	uint8_t mld_macaddr[6];
	int invalidate;
	time_t last_updated;

	bool emlmr_supported;
	bool emlsr_supported;
	bool str_supported;
	bool nstr_supported;
	bool ttlm_supported;

	bool emlmr_enabled;
	bool emlsr_enabled;
	bool str_enabled;
	bool nstr_enabled;
	bool ttlm_enabled;

	struct ip_address ipv4_addr;
	struct ip_address ipv6_addr;
	char hostname[256];
	bool is_bsta;
	uint32_t conn_time;           /* in secs since last associated */
	uint64_t tx_bytes;            /* transmit bytes count: ap -> sta */
	uint64_t rx_bytes;            /* receive bytes count: sta -> ap */
	uint32_t tx_packets;
	uint32_t rx_packets;
	uint32_t tx_errors;
	uint32_t rx_errors;
	uint32_t rtx_packets;         /* total retransmitted packets */

	uint8_t num_sta;              /* number of affiliated STAs */
	uint8_t num_ttlm;

	struct list_head stalist;     /* list of wifi_affiliated_sta_element */
	struct list_head ttlmlist;    /* list of wifi_ttlm_element */
};

struct wifi_bstamld_element {
	uint8_t mld_macaddr[6];
	uint8_t bssid[6];

	bool emlmr_enabled;
	bool emlsr_enabled;
	bool str_enabled;
	bool nstr_enabled;
	bool ttlm_enabled;

	uint8_t num_aff_bsta;
	struct list_head affbstalist;     /* list of wifi_affiliated_sta_element */
};

struct wifi_apmld_element {
	struct list_head list;
	uint8_t mld_macaddr[6];
	uint8_t ssidlen;
	char ssid[33];
	bool enabled;
	int invalidate;
	timestamp_t tsp;

	bool emlmr_enabled;
	bool emlsr_enabled;
	bool str_enabled;
	bool nstr_enabled;
	bool ttlm_enabled;

	uint8_t num_ap;			/* number of affiliated AP */
	uint32_t num_sta;		/* number of associated STA(MLD) */
	uint32_t num_ttlm;
	struct list_head aplist;	/* list of wifi_affiliated_ap_element */
	struct list_head stamldlist;	/* list of wifi_stamld_element */
	struct list_head ttlmlist;	/* list of wifi_ttlm_element */
};

struct wifi_radio_spatial_reuse_report {
	uint32_t partial_bss_color;
	uint32_t bss_color;
	bool hesiga_val15_allowed;
	bool srg_info_valid;
	bool non_srg_offset_valid;
	bool psr_disallowed;
	uint32_t non_srg_obsspd_max_offset;
	uint32_t srg_obsspd_min_offset;
	uint32_t srg_obsspd_max_offset;
	uint8_t srg_bss_color_bitmap[8];
	uint8_t srg_partial_bssid_bitmap[8];
	uint8_t neighbor_bss_color_in_use_bitmap[8];
};

struct wifi_radio_scan_capabilities {
	bool boot_only;
	uint8_t impact;
	uint32_t interval;
	struct wifi_radio_opclass opclass;
};

struct wifi_radio_cac_capabilities {
	enum wifi_cac_method method;
	uint32_t num_seconds;
	size_t num_opclass;
	struct list_head supp_opclasslist;
};

/* represents a scanned AP entry */
struct wifi_scanres_neighbor_element {
	struct list_head list;
	uint8_t bssid[6];
	char ssid[33];
	int rssi;                /* normalized as RCPI */
	uint32_t bw;
	uint8_t mld_macaddr[6];

	/* 0 = not part of Multi-BSSID, 1 = Tx-MBSSID, 2 = NonTX-MBSSID */
	uint8_t multibss_type;
	uint8_t rpt_bssid[6];	/* reporting-bssid */

	uint8_t bss_color;
	bool bss_color_disabled;

	bool bssload_present;
	uint8_t utilization;
	uint32_t num_stations;
};

struct wifi_scanres_channel_element {
	struct list_head list;
	timestamp_t tsp;
	uint8_t channel;
	uint8_t utilization;
	uint8_t anpi;
	uint32_t num_neighbors;
	struct list_head nbrlist;	/* list of wifi_scanres_neighbor_element */
	bool report_independent_scan;
	uint8_t scan_status;		/* one of CH_SCAN_STATUS_* from easymesh.h */
};

struct wifi_scanres_opclass_element {
	struct list_head list;
	uint8_t opclass;
	uint32_t num_channels_scanned;
	struct list_head channel_scanlist;	/* list of wifi_scanres_channel_element */
};

struct wifi_scanres_element {
	struct list_head list;
	struct timeval tv;
	timestamp_t tsp;
	uint32_t num_opclass_scanned;
	struct list_head opclass_scanlist;	/* list of wifi_scanres_opclass_element */
};

struct wifi_backhaul_element {
	uint8_t macaddr[6];
};

struct wifi_unassoc_sta_element {
	struct list_head list;
	uint8_t macaddr[6];
	uint8_t rcpi;
	uint8_t opclass;
	uint8_t channel;
	//struct wifi_sta_measurement meas;
};

struct wifi_radio_element {
	struct list_head list;
	enum wifi_band band;
	int invalidate;
	uint8_t macaddr[6];
	bool enabled;
	struct wifi_radio_element_report {
		uint8_t sta_rcpi_threshold;       /* 0 = disable; else 1..220 */
		uint8_t sta_rcpi_margin_override; /* 0 = disable; else value */
		uint8_t channel_util_threshold;   /* 0 = disable; else value */
		bool include_sta_stats;           /* bit7 = include stats */
		bool include_sta_metrics;         /* bit6 = include link metrics */
		bool include_wifi6_metrics;
	} report;

	uint8_t steer_policy;                     /* 0, 1 or 2 */
	uint8_t channel_util_threshold;           /* 0..220 */
	uint8_t rcpi_steer_threshold;             /* 0..220 */
	uint8_t anpi;                             /* avg noise to power indicator */
	uint8_t total_utilization;                /** in %age, linearly scaled 0..255 */
	uint8_t tx_utilization;
	uint8_t rx_utilization;
	uint8_t other_utilization;

	uint8_t tx_streams;
	uint8_t rx_streams;
	char country_code[4];

	uint8_t max_bssnum;
	uint32_t num_bss;
	uint32_t num_unassoc_sta;
	uint32_t num_scanresult;

	struct wifi_backhaul_element bsta;

	struct wifi_caps_element caps;
	struct wifi_wifi6_capabilities wifi6caps_ap;
	struct wifi_wifi6_capabilities wifi6caps_bsta;

	struct wifi_wifi7_capabilities wifi7caps_ap;
	struct wifi_wifi7_capabilities wifi7caps_bsta;
	bool wifi7caps_ap_support_nmlo_sta;	/* supports association of non-MLO STAs */

	struct wifi_radio_opclass supp_opclass; /* supported opclasses reported by device */
	struct wifi_radio_opclass pref_opclass;	/* preferred opclasses reported by device */
	struct wifi_radio_opclass cur_opclass;	/* current opclasses reported by device */

	struct list_head bsslist;		/* list of wifi_bss_element */
	struct list_head unassoc_stalist;	/* list of wifi_unassoc_sta_element */
	struct list_head scanlist;		/* list of wifi_scanres_element */

	int ts_combined_fronthaul;
	int ts_combined_backhaul;

	char vendor[64];			/* chipset vendor */
	struct wifi_radio_scan_capabilities scan_caps;
	struct wifi_radio_cac_capabilities cac_caps;

	struct list_head fbss_akmlist;		/* fBSS AKM list */
	struct list_head bbss_akmlist;		/* bBSS AKM list */

	bool bgcac_supported;
	void *acs;
};

struct wifi_default_8021q {
	uint8_t pvid;
	uint8_t pcp;
	struct list_head list;
};

struct ieee1905_security_caps {
	bool caps_valid;
	uint8_t onboarding_protocol;
	uint8_t integrity;
	uint8_t encryption;
};

struct wifi_sp_rule {
	uint32_t id;
	uint8_t priority;
	uint8_t output;
	bool always_match;
	struct list_head list;
};

struct anticipated_ch_usage_entry {
	struct list_head list;
	uint32_t burst_start_time;
	uint32_t burst_length;
	uint32_t repetitions;
	uint32_t burst_interval;
	uint8_t ru_bitmask_length;
#define MAX_RU_BITMASK_LENGTH 10
	uint8_t ru_bitmask[MAX_RU_BITMASK_LENGTH];
	uint8_t transmitter_id[6];
	uint8_t power_level;
	uint8_t ch_usage_reason;
};

struct anticipated_ch_usage {
	struct list_head list;
	uint8_t op_class;
	uint8_t channel;
	uint8_t ref_bssid[6];
	uint8_t num_of_usage_entries;
	struct list_head entry_list;	/* list of struct anticipated_ch_usage_entry */
};

struct wifi_backhaul_stats {
	timestamp_t tsp;
	uint64_t tx_bytes;
	uint64_t rx_bytes;
	uint32_t tx_pkts;
	uint32_t rx_pkts;
	uint32_t tx_errors;
	uint32_t rx_errors;
	uint8_t link_utilization;	/* in %age */
	uint8_t rcpi;
	uint32_t dl_rate;             /* latest data rate in Kbps: ap -> bsta */
	uint32_t ul_rate;             /* latest data rate in Kbps: bsta -> ap */
	uint32_t phyrate;             /* latest PHysical Layer (PHY) rate in Mbps */
};

enum network_link_type {
	LINK_TYPE_NONE = 0,
	LINK_TYPE_WIFI = 1,
	LINK_TYPE_ETH = 2,
	LINK_TYPE_MOCA = 3,
	LINK_TYPE_GHN = 4,
	LINK_TYPE_HPNA = 5,
	LINK_TYPE_HOME = 6,
	LINK_TYPE_UPA = 7,
};

struct wifi_network_device_backhaul {
	enum network_link_type linktype;
	uint8_t bsta_macaddr[6];		/* own local mac */
	uint8_t upstream_device_macaddr[6];	/* upstream al mac */
	uint8_t upstream_bbss_macaddr[6];	/* upstream local mac */
	uint32_t num_curr_opclass;
	struct list_head curr_opclasslist;	/* list of wifi_opclass_current_element */

	struct wifi_backhaul_stats stats;
};

enum operation_mode {
	NOT_SUPPORTED = 0,
	SUPPORTED = 1,
	RUNNING = 2,
};

struct wifi_multi_ap_device {
	uint8_t oui[3];
	timestamp_t last_contacttime;
	struct wifi_network_device *dev_ref;
	enum operation_mode controller_opmode;
	enum operation_mode agent_opmode;
	struct wifi_network_device_backhaul backhaul;
};

struct mac_address_element {
	macaddr_t macaddr;
	struct list_head list;
};

struct wifi_network_device {
	void *priv;		/* application private opaque context data */
	bool invalid;
	uint8_t macaddr[6];        /* unique device-id: eui-48 address */
	uint8_t multiap_caps;      /* from ap-capability tlv */
	uint32_t collect_int;      /* data collection interval in msecs */
	struct wifi_network_device_report {
		uint8_t ap_metrics_int;       /* 0 = disable; 1-255 in seconds */
		uint8_t sta_metrics_int;       /* 0 = disable; 1-255 in seconds */
		bool independent_scans;
		uint32_t sta_assoc_fails;    /* 0 = disable; max-rate/minute */
		bool include_wifi6_metrics;
	} report;

	uint32_t map_profile;		/* MAP-Profile; 1, 2, 3 etc. */
	uint32_t num_radios;
	struct list_head radiolist;	/* list of wifi_radio_element */

	struct wifi_sta_events ev;

	time_t last_contacttime;
	char manufacturer[65];
	uint8_t oui[3];
	char serial[33];
	char model[33];
	char swversion[65];            /* Indentfier of SW (firmware) version installed on device */
	char execenv[65];              /* Identifier of operating system */

	uint32_t num_cacstatus;
	uint32_t num_sprules;

	struct list_head sta_steer_disallowlist;        /* list of mac_address_element */
	struct list_head sta_btmsteer_disallowlist;     /* list of mac_address_element */
	struct list_head default_8021qlist;		/* list of wifi_default_8021q */
#define MAX_CAC_STATUS_HISTORY 3
	struct list_head cac_statuslist;		/* list of wifi_cac_status */
	struct list_head sp_rulelist;			/* list of wifi_sp_rule */

	struct wifi_multi_ap_device multi_ap_device;

	uint8_t dscp_mapping[64];
	uint8_t max_prules;		/* max number of SP rules supported */
	bool support_sp;
	bool support_dpp;
	bool support_ts;
	size_t max_vids;
	struct ieee1905_security_caps i1905_seccap;
	char country_code[4];
	bool dfs_enabled;
	bool sta_steering_state;	/* Controller initiated STA steering allowed */
	bool ts_allowed;
	bool sp_allowed;
	bool coordinated_cac_allowed;

	uint32_t num_anticipated_channels;
	//anticipated_chanlist
	uint32_t num_anticipated_channel_usage;
	struct list_head anticipated_channel_usagelist;	/* list of struct anticipated_ch_usage */

	uint8_t has_easymesh_controller;	/* 0, 1 or 2 */
	uint8_t has_easymesh_agent;		/* 0, 1 or 2 */

	uint8_t max_mlds;
	uint8_t max_apmld_links;		/* 0-14 */
	uint8_t max_bstamld_links;		/* 0-14 */
	uint8_t ttlm_cap;			/* 0, 1 or 2 */

	uint8_t num_apmld;
	struct list_head apmldlist;		/* list of struct wifi_apmld_element */

	struct wifi_bstamld_element bstamld;

	struct list_head list;
};

/* ssids in the multiap network */
struct wifi_network_ssid {
	bool enabled;
	size_t ssidlen;
	uint8_t ssid[32];
	uint32_t band;
	uint32_t security;
	uint16_t vid;
	uint8_t multi_ap;
	enum wifi_bsstype type;
	bool hidden;
	uint8_t mfp;
	uint16_t mobility_domain;
	uint8_t mld_id;
	struct list_head list;
};

/* ap-mlds in the multiap network */
struct wifi_network_mld {
	bool enabled;
	uint8_t id;
	size_t ssidlen;
	char ssid[33];
	uint32_t band;
	uint32_t security;
	uint8_t multi_ap;
	enum wifi_bsstype type;
	bool hidden;
	struct list_head list;
};

#define MAX_NUM_STA_BLOCK_BSSID         12
#define MAX_NUM_STA_BLOCK_SCHEDULE      7

/* STA block through association control */
struct wifi_sta_block {
	struct list_head list;
	uint8_t macaddr[6];
	int num_bssid;
	uint8_t bssid[MAX_NUM_STA_BLOCK_BSSID * 6];
	int num_schedule;
	struct wifi_sta_block_schedule {
		uint8_t dow;
		time_t starttime;
		uint32_t duration;
	} schedule[MAX_NUM_STA_BLOCK_SCHEDULE];
};

struct wifi_network {
	void *priv;		/* application private opaque context data */
	timestamp_t tsp;
	char id[16];               /* network id (guid) */
	uint8_t cntlr_id[6];       /* controller id (macaddress) */
	uint8_t coagent_id[6];     /* colocated agent id (macaddress) */

	uint32_t num_ssid;
	struct list_head ssidlist; /* list of wifi_network_ssid */

	uint32_t num_mld;
	struct list_head mldlist;  /* list of wifi_network_mld */

	uint32_t num_sta_block;
	struct list_head blocklist;	/* list of wifi_sta_block */

	uint16_t primary_vid;
	uint16_t default_pcp;
	macaddr_t *disallow_scslist;
	macaddr_t *disallow_mscslist;
	uint32_t num_devices;
	struct wifi_steer_summary steer_summary;
	struct list_head devicelist;	/* list of wifi_network_device */
};

struct wifi_data_element {
	timestamp_t tsp;
	char version[32];
	struct wifi_network network;
};

struct wifi_assoc_event {
	timestamp_t tsp;
	time_t tm;
	uint8_t macaddr[6];
	uint8_t bssid[6];
	uint16_t status_code;
	struct wifi_caps_element caps;
	struct list_head list;
};

struct wifi_disassoc_event {
	timestamp_t tsp;
	time_t tm;
	uint8_t macaddr[6];
	uint8_t bssid[6];
	uint16_t reason_code;
	struct wifi_sta_element sta;
#define MAX_NUM_MLO_LINKS 3
	int num_affiliated_sta;
	struct wifi_affiliated_sta_element affsta[MAX_NUM_MLO_LINKS];
	struct list_head list;
};

struct wifi_channel_data {
	uint8_t channel;
	uint8_t utilization;
	uint8_t anpi;
};

struct radio_event_data {
	uint8_t macaddr[6];
	uint32_t num_cdata;
	struct wifi_channel_data *cdata;
};

struct wifi_radio_events {
	uint32_t num_radios;
	struct radio_event_data *rdata;
};

#ifdef __cplusplus
}
#endif
#endif /* WIFI_DATAELEMENTS_H */
