/*
 * btscanner - Displays the output of Bluetooth scans
 * Copyright (C) 2003 Pentest Limited
 * 
 * Written 2003 by Tim Hurman <timh at pentest.co.uk>
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
 * RIGHTS.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE
 * FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY
 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 * 
 * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
 * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE
 * IS DISCLAIMED.
 */

/*
 * ll.h: The linked list handlers
 */

#ifndef LL_H
#define LL_H

/* sorting */
#define LL_SORT_NONE 0x00
#define LL_SORT_BD 0x01 /* bdaddr */
#define LL_SORT_FS 0x02 /* first seen */
#define LL_SORT_LS 0x04 /* last seen */
#define LL_SORT_REV 0x80 /* reverse sort */

/* the linked list to hold the address info. before anything can be
 * changed in here, the whole list much be locked */
struct device
{
	struct device *next;
	/* locking: although locking may seem odd, because another process may
	 * be accessing the device, we will lock so that different scanning
	 * threads will not all start querying a device when it is seem. that
	 * would get messy
	 */
	uint8_t locked;
	pthread_t locked_by;

	/* when we see a device, we try and get the previous state, if
	 * none exists we make a new device entry and lock it ourselves.
	 * if one exists and is unlocked, get a lock and return the pointer.
	 * The screen code will not update any locked item.
	 */
	uint8_t updated;
	/* this will tell if the device info has been updated since the last
	 * screen refresh, if so then we know to re-display it. This is only
	 * a optimisation for the screen code
	 */

	/* basic info */
	bdaddr_t bdaddr;
	uint16_t clk_off;

	uint8_t got_class;
	uint32_t class;
	uint8_t got_name;
	char *name;

	uint8_t got_oui;
	const char *oui;

	/* advanced info */
	struct hci_version version;
	uint8_t got_version;
	unsigned char features[8];
	uint8_t got_features;

	int8_t rssi;
	uint8_t rssi_status;

	uint8_t lq;
	uint8_t lq_status;

	uint8_t txpwr_status;
	uint8_t txpwr_type;
	int8_t txpwr_level;

	char *sdp;

	/* when and where was it scanned */
	bdaddr_t bd_scan;
	unsigned int scan_count;
	time_t last_scanned;
	time_t first_scanned;
};
typedef struct device device_t;

int ll_init(void);
int ll_free(void);

int ll_lock_list(void);
int ll_unlock_list(void);

device_t * ll_lock_device(bdaddr_t *);
int ll_unlock_device(device_t *);

/* screen functions */
int ll_ischanged(void);
int ll_print_dev_line(device_t *, uint64_t *, char *, int);
int ll_print_dev_info(uint64_t, cbuf_t *);
int ll_print_timestamp(device_t *, cbuf_t *);
int ll_copy_name(device_t *, char *);

device_t *ll_first(void);
device_t *ll_next(device_t *);

uint8_t ll_check_got_name(device_t *);
uint8_t ll_check_got_version(device_t *);
uint8_t ll_check_got_features(device_t *);
uint8_t ll_check_got_oui(device_t *);
uint8_t ll_check_got_sdp(device_t *);

size_t ll_dev_count(void);
int ll_get_last_update_time(uint64_t, time_t *);
device_t *ll_find_device(uint64_t);

int ll_save_summary(const char *);
int ll_sortlist(int);

#endif /* LL_H */

