#ifndef _WIFI_RADIO_OPCLASS_H_
#define _WIFI_RADIO_OPCLASS_H_

#include <stdint.h>
#include <stdbool.h>

#include "wifi_dataelements.h"

#ifdef __cplusplus
extern "C" {
#endif


const struct wifi_radio_opclass *wifi_opclass_e4(struct wifi_radio_opclass *dst);

struct wifi_radio_opclass_entry *wifi_opclass_find_entry(struct wifi_radio_opclass *opclass, uint8_t id);
struct wifi_radio_opclass_entry *wifi_opclass_new_entry(struct wifi_radio_opclass *opclass);

struct wifi_radio_opclass_channel *wifi_opclass_find_channel(struct wifi_radio_opclass_entry *entry, uint8_t chan);
struct wifi_radio_opclass_channel *wifi_opclass_new_channel(struct wifi_radio_opclass_entry *entry);

int wifi_opclass_add_channel(struct wifi_radio_opclass_entry *entry, struct wifi_radio_opclass_channel *new);
int wifi_opclass_add_entry(struct wifi_radio_opclass *opclass, struct wifi_radio_opclass_entry *new);

bool wifi_opclass_expired(struct wifi_radio_opclass *opclass, uint32_t seconds);
void wifi_opclass_reset(struct wifi_radio_opclass *opclass);
void wifi_opclass_dump(struct wifi_radio_opclass *opclass, const char *name, uint8_t *radio);
void wifi_opclass_dump_ex(struct wifi_radio_opclass *opclass, const char *name, uint8_t *radio, bool full);

uint8_t wifi_opclass_get_id(struct wifi_radio_opclass *opclass, uint8_t channel, int bandwidth);
void wifi_opclass_set_preferences(struct wifi_radio_opclass *opclass, uint8_t preference);
int wifi_opclass_get_higest_preference(struct wifi_radio_opclass *opclass, int bandwith,
				       uint8_t *opclass_id, uint8_t *channel);
uint8_t wifi_get_best_ctrl_channel(struct wifi_radio_opclass *opclass, const uint8_t *channels, int channels_num);
bool wifi_opclass_id_supported(struct wifi_radio_opclass *opclass, uint8_t id);
uint8_t wifi_opclass_num_supported(struct wifi_radio_opclass *opclass);
bool wifi_opclass_cac_required(struct wifi_radio_opclass *opclass,
			       int ctrl_channel,
			       int bandwidth,
			       uint32_t *cac_time);
bool wifi_opclass_id_all_channels_supported(struct wifi_radio_opclass *opclass, uint8_t id);
int wifi_opclass_id_num_channels_supported(struct wifi_radio_opclass *opclass, uint8_t id);
int wifi_opclass_id_num_channels_unsupported(struct wifi_radio_opclass *opclass, uint8_t id);
bool wifi_opclass_id_channel_supported(struct wifi_radio_opclass *opclass, uint8_t id, uint8_t channel);
void wifi_opclass_id_set_preferences(struct wifi_radio_opclass *opclass, uint8_t id, uint8_t preference);
void wifi_opclass_id_set_channel_preferences(struct wifi_radio_opclass *opclass, uint8_t id, uint8_t channel, uint8_t preference);
bool wifi_opclass_is_channel_supported(struct wifi_radio_opclass_channel *chan);
int wifi_opclass_get_supported_ctrl_channels(struct wifi_radio_opclass *opclass,
			       uint8_t id,
			       uint8_t ctrl_channels[],
			       int *num_channels);
bool wifi_opclass_is_dfs_channel(struct wifi_radio_opclass_channel *chan);
bool wifi_opclass_dfs_supported(struct wifi_radio_opclass *opclass);
bool wifi_opclass_id_dfs_supported(struct wifi_radio_opclass *opclass, uint8_t id);
uint8_t wifi_opclass_dfs_num(struct wifi_radio_opclass *opclass);
uint8_t wifi_opclass_id_dfs_num(struct wifi_radio_opclass *opclass, uint8_t id);
uint8_t wifi_opclass_find_id_from_channel(struct wifi_radio_opclass *opclass,
					  int ctrl_channel,
					  int bandwidth);
bool wifi_opclass_id_same_preference(struct wifi_radio_opclass *opclass, uint8_t id, uint8_t *pref);
bool wifi_opclass_same_preference(struct wifi_radio_opclass *opclass, uint8_t *preferences);
bool wifi_opclass_max_preference(uint8_t preference);
bool wifi_opclass_is_channel_dfs_available(struct wifi_radio_opclass_channel *chan);
bool wifi_opclass_is_channel_dfs_nop(struct wifi_radio_opclass_channel *chan);
bool wifi_opclass_is_channel_dfs_cac(struct wifi_radio_opclass_channel *chan);
uint32_t wifi_opclass_channel_dfs_cac_time(struct wifi_radio_opclass_channel *chan);
uint32_t wifi_opclass_channel_dfs_nop_time(struct wifi_radio_opclass_channel *chan);
void wifi_opclass_mark_unsupported(struct wifi_radio_opclass *out, struct wifi_radio_opclass *in);
enum wifi_band wifi_opclass_get_band(int opclass);
int wifi_opclass_get_bw(int op_class);
struct wifi_radio_opclass_channel *wifi_opclass_get_channel(struct wifi_radio_opclass *opclass, uint8_t id, uint8_t channel);
struct wifi_radio_opclass_channel *wifi_opclass_get_ctrl_channel(struct wifi_radio_opclass *opclass, uint8_t id, uint8_t channel);
bool wifi_opclass_has_channel(uint8_t id, uint8_t channel);
int wifi_radio_opclass_update_channel(struct wifi_radio_opclass *opclass, uint8_t band,
				      uint32_t channel, uint32_t bw, uint8_t pref);
int wifi_opclass_get_attr(struct wifi_radio_opclass *opclass,
			  uint8_t *ctrl_channel,
			  uint32_t *bw,
			  uint8_t *id,
			  uint8_t *channel);
uint32_t wifi_opclass_highest_bandwidth(struct wifi_radio_opclass *opclass, bool available_only);
void wifi_get_widest_opclass_and_channel(struct wifi_radio_element *radio, uint8_t *opclass, uint8_t *channel);
void wifi_apply_disallow_opclass(struct wifi_radio_opclass *opclass, struct wifi_radio_opclass *dis_opclass);

#ifdef __cplusplus
}
#endif

#endif /* _WIFI_RADIO_OPCLASS_H_ */
