/*
 * scan.h - scan related code declarations
 *
 * Copyright (C) 2020 IOPSYS Software Solutions AB. All rights reserved.
 *
 */

#ifndef SCAN_H
#define SCAN_H

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

#include "wifi.h"

struct agent;
struct scan_param_ex;
struct wifi_radio_element;
struct wifi_radio_opclass;
struct wifi_scanresults;

#define SCAN_MAX_CHANNEL 16
struct wifi_scan_request_opclass {
	uint8_t classid;
	uint8_t num_channel;
	uint8_t channel[SCAN_MAX_CHANNEL];
};

#define SCAN_MAX_OPCLASS 8
struct wifi_scan_request_radio {
	uint16_t mid;	/* message id of the request */
	uint8_t status; /* current status for the request */
	uint8_t radio[6];
	uint8_t num_opclass;
	struct wifi_scan_request_opclass opclass[SCAN_MAX_OPCLASS];
};

#define SCAN_MAX_RADIO 4
struct wifi_scan_request {
	uint8_t mode;
	uint8_t num_radio;
	struct wifi_scan_request_radio radio[SCAN_MAX_RADIO];
};

struct wifi_scanres_neighbor_element {
	uint8_t bssid[6];
	char ssid[33];
	int rssi;
	uint32_t bw;
	uint8_t utilization;
	uint32_t num_stations;
};

struct wifi_scanres_channel_element {
	timestamp_t tsp;
	uint8_t channel;
	uint8_t utilization;
	uint8_t anpi;
	uint32_t scan_duration;
	uint32_t num_neighbors;
	struct wifi_scanres_neighbor_element *nbrlist;  /* scanned AP list */
};

struct wifi_scanres_opclass_element {
	uint8_t opclass;
	uint32_t bandwidth;
	uint32_t num_channels;
	struct wifi_scanres_channel_element *channel_scanlist;
};

struct wifi_scanres_element {
	timestamp_t tsp;
	uint32_t num_opclass;
	struct wifi_scanres_opclass_element *opclass_scanlist;
};


int scan_init_scanlist(struct agent *a, struct wifi_radio_element *re);
void scan_free_scanlist(struct wifi_radio_element *re);

int scan_cache_to_scanlist(const struct agent *a,
		struct wifi_radio_element *re, bool fresh);
int scan_process_request(struct agent *a,
		struct wifi_scan_request *ch_scan_req);
int scan_radio(struct agent *a, const char *radio,
			     const char *ssid, int num_opclass,
			     uint8_t *opclass, int num_channel,
			     uint8_t *channel);
int scan_radio_all_channels(const char *radio);
int scan_radio_opclass(const char *radio, int num_opclasses, uint8_t *opclasses);
int issue_channel_scan(struct agent *a, const char *radio_name,
			struct wifi_radio_opclass *opclass,
			struct wifi_scan_request_radio *req);
int handle_wifi_radio_scan_finished(struct agent *a,
		struct wifi_radio_element *re);
int scan_get_results(struct agent *a, struct wifi_radio_element *re);
int scan_send_response(struct agent *a,
		struct wifi_radio_element *re,
		struct wifi_scan_request_radio *req);
#endif
