/*
 * WPA Supplicant - Layer2 packet handling with Microsoft NDISUIO
 * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 *
 * This implementation requires Windows specific event loop implementation,
 * i.e., eloop_win.c. In addition, the NDISUIO connection is shared with
 * driver_ndis.c, so only that driver interface can be used and
 * CONFIG_USE_NDISUIO must be defined.
 *
 * WinXP version of the code uses overlapped I/O and a single threaded design
 * with callback functions from I/O code. WinCE version uses a separate RX
 * thread that blocks on ReadFile() whenever the media status is connected.
 */

#include "includes.h"
#include <winsock2.h>
#include <ntddndis.h>

#ifdef _WIN32_WCE
#include <winioctl.h>
#include <nuiouser.h>
#endif /* _WIN32_WCE */

#include "common.h"
#include "eloop.h"
#include "l2_packet.h"

#ifndef _WIN32_WCE
/* from nuiouser.h */
#define FSCTL_NDISUIO_BASE      FILE_DEVICE_NETWORK
#define _NDISUIO_CTL_CODE(_Function, _Method, _Access) \
	CTL_CODE(FSCTL_NDISUIO_BASE, _Function, _Method, _Access)
#define IOCTL_NDISUIO_SET_ETHER_TYPE \
	_NDISUIO_CTL_CODE(0x202, METHOD_BUFFERED, \
			  FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#endif /* _WIN32_WCE */

/* From driver_ndis.c to shared the handle to NDISUIO */
HANDLE driver_ndis_get_ndisuio_handle(void);

/*
 * NDISUIO supports filtering of only one ethertype at the time, so we must
 * fake support for two (EAPOL and RSN pre-auth) by switching to pre-auth
 * whenever wpa_supplicant is trying to pre-authenticate and then switching
 * back to EAPOL when pre-authentication has been completed.
 */

struct l2_packet_data;

struct l2_packet_ndisuio_global {
	int refcount;
	unsigned short first_proto;
	struct l2_packet_data *l2[2];
#ifdef _WIN32_WCE
	HANDLE rx_thread;
	HANDLE stop_request;
	HANDLE ready_for_read;
	HANDLE rx_processed;
#endif /* _WIN32_WCE */
};

static struct l2_packet_ndisuio_global *l2_ndisuio_global = NULL;

struct l2_packet_data {
	char ifname[100];
	u8 own_addr[ETH_ALEN];
	void (*rx_callback)(void *ctx, const u8 *src_addr,
			    const u8 *buf, size_t len);
	void *rx_callback_ctx;
	int l2_hdr; /* whether to include layer 2 (Ethernet) header in calls to
		     * rx_callback and l2_packet_send() */
	HANDLE rx_avail;
#ifndef _WIN32_WCE
	OVERLAPPED rx_overlapped;
#endif /* _WIN32_WCE */
	u8 rx_buf[1514];
	DWORD rx_written;
};


int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr)
{
	os_memcpy(addr, l2->own_addr, ETH_ALEN);
	return 0;
}


int l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto,
		   const u8 *buf, size_t len)
{
	BOOL res;
	DWORD written;
	struct l2_ethhdr *eth;
#ifndef _WIN32_WCE
	OVERLAPPED overlapped;
#endif /* _WIN32_WCE */
	OVERLAPPED *o;

	if (l2 == NULL)
		return -1;

#ifdef _WIN32_WCE
	o = NULL;
#else /* _WIN32_WCE */
	os_memset(&overlapped, 0, sizeof(overlapped));
	o = &overlapped;
#endif /* _WIN32_WCE */

	if (l2->l2_hdr) {
		res = WriteFile(driver_ndis_get_ndisuio_handle(), buf, len,
				&written, o);
	} else {
		size_t mlen = sizeof(*eth) + len;
		eth = os_malloc(mlen);
		if (eth == NULL)
			return -1;

		os_memcpy(eth->h_dest, dst_addr, ETH_ALEN);
		os_memcpy(eth->h_source, l2->own_addr, ETH_ALEN);
		eth->h_proto = htons(proto);
		os_memcpy(eth + 1, buf, len);
		res = WriteFile(driver_ndis_get_ndisuio_handle(), eth, mlen,
				&written, o);
		os_free(eth);
	}

	if (!res) {
		DWORD err = GetLastError();
#ifndef _WIN32_WCE
		if (err == ERROR_IO_PENDING) {
			wpa_printf(MSG_DEBUG, "L2(NDISUIO): Wait for pending "
				   "write to complete");
			res = GetOverlappedResult(
				driver_ndis_get_ndisuio_handle(), &overlapped,
				&written, TRUE);
			if (!res) {
				wpa_printf(MSG_DEBUG, "L2(NDISUIO): "
					   "GetOverlappedResult failed: %d",
					   (int) GetLastError());
				return -1;
			}
			return 0;
		}
#endif /* _WIN32_WCE */
		wpa_printf(MSG_DEBUG, "L2(NDISUIO): WriteFile failed: %d",
			   (int) GetLastError());
		return -1;
	}

	return 0;
}


static void l2_packet_callback(struct l2_packet_data *l2);

#ifdef _WIN32_WCE
static void l2_packet_rx_thread_try_read(struct l2_packet_data *l2)
{
	HANDLE handles[2];

	wpa_printf(MSG_MSGDUMP, "l2_packet_rx_thread: -> ReadFile");
	if (!ReadFile(driver_ndis_get_ndisuio_handle(), l2->rx_buf,
		      sizeof(l2->rx_buf), &l2->rx_written, NULL)) {
		DWORD err = GetLastError();
		wpa_printf(MSG_DEBUG, "l2_packet_rx_thread: ReadFile failed: "
			   "%d", (int) err);
		/*
		 * ReadFile on NDISUIO/WinCE returns ERROR_DEVICE_NOT_CONNECTED
		 * error whenever the connection is not up. Yield the thread to
		 * avoid triggering a busy loop. Connection event should stop
		 * us from looping for long, but we need to allow enough CPU
		 * for the main thread to process the media disconnection.
		 */
		Sleep(100);
		return;
	}

	wpa_printf(MSG_DEBUG, "l2_packet_rx_thread: Read %d byte packet",
		   (int) l2->rx_written);

	/*
	 * Notify the main thread about the availability of a frame and wait
	 * for the frame to be processed.
	 */
	SetEvent(l2->rx_avail);
	handles[0] = l2_ndisuio_global->stop_request;
	handles[1] = l2_ndisuio_global->rx_processed;
	WaitForMultipleObjects(2, handles, FALSE, INFINITE);
	ResetEvent(l2_ndisuio_global->rx_processed);
}


static DWORD WINAPI l2_packet_rx_thread(LPVOID arg)
{
	struct l2_packet_data *l2 = arg;
	DWORD res;
	HANDLE handles[2];
	int run = 1;

	wpa_printf(MSG_DEBUG, "L2(NDISUIO): RX thread started");
	handles[0] = l2_ndisuio_global->stop_request;
	handles[1] = l2_ndisuio_global->ready_for_read;

	/*
	 * Unfortunately, NDISUIO on WinCE does not seem to support waiting
	 * on the handle. There do not seem to be anything else that we could
	 * wait for either. If one were to modify NDISUIO to set a named event
	 * whenever packets are available, this event could be used here to
	 * avoid having to poll for new packets or we could even move to use a
	 * single threaded design.
	 *
	 * In addition, NDISUIO on WinCE is returning
	 * ERROR_DEVICE_NOT_CONNECTED whenever ReadFile() is attempted while
	 * the adapter is not in connected state. For now, we are just using a
	 * local event to allow ReadFile calls only after having received NDIS
	 * media connect event. This event could be easily converted to handle
	 * another event if the protocol driver is replaced with somewhat more
	 * useful design.
	 */

	while (l2_ndisuio_global && run) {
		res = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
		switch (res) {
		case WAIT_OBJECT_0:
			wpa_printf(MSG_DEBUG, "l2_packet_rx_thread: Received "
				   "request to stop RX thread");
			run = 0;
			break;
		case WAIT_OBJECT_0 + 1:
			l2_packet_rx_thread_try_read(l2);
			break;
		case WAIT_FAILED:
		default:
			wpa_printf(MSG_DEBUG, "l2_packet_rx_thread: "
				   "WaitForMultipleObjects failed: %d",
				   (int) GetLastError());
			run = 0;
			break;
		}
	}

	wpa_printf(MSG_DEBUG, "L2(NDISUIO): RX thread stopped");

	return 0;
}
#else /* _WIN32_WCE */
static int l2_ndisuio_start_read(struct l2_packet_data *l2, int recursive)
{
	os_memset(&l2->rx_overlapped, 0, sizeof(l2->rx_overlapped));
	l2->rx_overlapped.hEvent = l2->rx_avail;
	if (!ReadFile(driver_ndis_get_ndisuio_handle(), l2->rx_buf,
		      sizeof(l2->rx_buf), &l2->rx_written, &l2->rx_overlapped))
	{
		DWORD err = GetLastError();
		if (err != ERROR_IO_PENDING) {
			wpa_printf(MSG_DEBUG, "L2(NDISUIO): ReadFile failed: "
				   "%d", (int) err);
			return -1;
		}
		/*
		 * Once read is completed, l2_packet_rx_event() will be
		 * called.
		 */
	} else {
		wpa_printf(MSG_DEBUG, "L2(NDISUIO): ReadFile returned data "
			   "without wait for completion");
		if (!recursive)
			l2_packet_callback(l2);
	}

	return 0;
}
#endif /* _WIN32_WCE */


static void l2_packet_callback(struct l2_packet_data *l2)
{
	const u8 *rx_buf, *rx_src;
	size_t rx_len;
	struct l2_ethhdr *ethhdr = (struct l2_ethhdr *) l2->rx_buf;

	wpa_printf(MSG_DEBUG, "L2(NDISUIO): Read %d bytes",
		   (int) l2->rx_written);

	if (l2->l2_hdr || l2->rx_written < sizeof(*ethhdr)) {
		rx_buf = (u8 *) ethhdr;
		rx_len = l2->rx_written;
	} else {
		rx_buf = (u8 *) (ethhdr + 1);
		rx_len = l2->rx_written - sizeof(*ethhdr);
	}
	rx_src = ethhdr->h_source;

	l2->rx_callback(l2->rx_callback_ctx, rx_src, rx_buf, rx_len);
#ifndef _WIN32_WCE
	l2_ndisuio_start_read(l2, 1);
#endif /* _WIN32_WCE */
}


static void l2_packet_rx_event(void *eloop_data, void *user_data)
{
	struct l2_packet_data *l2 = eloop_data;

	if (l2_ndisuio_global)
		l2 = l2_ndisuio_global->l2[l2_ndisuio_global->refcount - 1];

	ResetEvent(l2->rx_avail);

#ifndef _WIN32_WCE
	if (!GetOverlappedResult(driver_ndis_get_ndisuio_handle(),
				 &l2->rx_overlapped, &l2->rx_written, FALSE)) {
		wpa_printf(MSG_DEBUG, "L2(NDISUIO): GetOverlappedResult "
			   "failed: %d", (int) GetLastError());
		return;
	}
#endif /* _WIN32_WCE */

	l2_packet_callback(l2);

#ifdef _WIN32_WCE
	SetEvent(l2_ndisuio_global->rx_processed);
#endif /* _WIN32_WCE */
}


static int l2_ndisuio_set_ether_type(unsigned short protocol)
{
	USHORT proto = htons(protocol);
	DWORD written;

	if (!DeviceIoControl(driver_ndis_get_ndisuio_handle(),
			     IOCTL_NDISUIO_SET_ETHER_TYPE, &proto,
			     sizeof(proto), NULL, 0, &written, NULL)) {
		wpa_printf(MSG_ERROR, "L2(NDISUIO): "
			   "IOCTL_NDISUIO_SET_ETHER_TYPE failed: %d",
			   (int) GetLastError());
		return -1;
	}

	return 0;
}


struct l2_packet_data * l2_packet_init(
	const char *ifname, const u8 *own_addr, unsigned short protocol,
	void (*rx_callback)(void *ctx, const u8 *src_addr,
			    const u8 *buf, size_t len),
	void *rx_callback_ctx, int l2_hdr)
{
	struct l2_packet_data *l2;

	if (l2_ndisuio_global == NULL) {
		l2_ndisuio_global = os_zalloc(sizeof(*l2_ndisuio_global));
		if (l2_ndisuio_global == NULL)
			return NULL;
		l2_ndisuio_global->first_proto = protocol;
	}
	if (l2_ndisuio_global->refcount >= 2) {
		wpa_printf(MSG_ERROR, "L2(NDISUIO): Not more than two "
			   "simultaneous connections allowed");
		return NULL;
	}
	l2_ndisuio_global->refcount++;

	l2 = os_zalloc(sizeof(struct l2_packet_data));
	if (l2 == NULL)
		return NULL;
	l2_ndisuio_global->l2[l2_ndisuio_global->refcount - 1] = l2;

	os_strlcpy(l2->ifname, ifname, sizeof(l2->ifname));
	l2->rx_callback = rx_callback;
	l2->rx_callback_ctx = rx_callback_ctx;
	l2->l2_hdr = l2_hdr;

	if (own_addr)
		os_memcpy(l2->own_addr, own_addr, ETH_ALEN);

	if (l2_ndisuio_set_ether_type(protocol) < 0) {
		os_free(l2);
		return NULL;
	}

	if (l2_ndisuio_global->refcount > 1) {
		wpa_printf(MSG_DEBUG, "L2(NDISUIO): Temporarily setting "
			   "filtering ethertype to %04x", protocol);
		if (l2_ndisuio_global->l2[0])
			l2->rx_avail = l2_ndisuio_global->l2[0]->rx_avail;
		return l2;
	}

	l2->rx_avail = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (l2->rx_avail == NULL) {
		os_free(l2);
		return NULL;
	}

	eloop_register_event(l2->rx_avail, sizeof(l2->rx_avail),
			     l2_packet_rx_event, l2, NULL);

#ifdef _WIN32_WCE
	l2_ndisuio_global->stop_request = CreateEvent(NULL, TRUE, FALSE, NULL);
	/*
	 * This event is being set based on media connect/disconnect
	 * notifications in driver_ndis.c.
	 */
	l2_ndisuio_global->ready_for_read =
		CreateEvent(NULL, TRUE, FALSE, TEXT("WpaSupplicantConnected"));
	l2_ndisuio_global->rx_processed = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (l2_ndisuio_global->stop_request == NULL ||
	    l2_ndisuio_global->ready_for_read == NULL ||
	    l2_ndisuio_global->rx_processed == NULL) {
		if (l2_ndisuio_global->stop_request) {
			CloseHandle(l2_ndisuio_global->stop_request);
			l2_ndisuio_global->stop_request = NULL;
		}
		if (l2_ndisuio_global->ready_for_read) {
			CloseHandle(l2_ndisuio_global->ready_for_read);
			l2_ndisuio_global->ready_for_read = NULL;
		}
		if (l2_ndisuio_global->rx_processed) {
			CloseHandle(l2_ndisuio_global->rx_processed);
			l2_ndisuio_global->rx_processed = NULL;
		}
		eloop_unregister_event(l2->rx_avail, sizeof(l2->rx_avail));
		os_free(l2);
		return NULL;
	}

	l2_ndisuio_global->rx_thread = CreateThread(NULL, 0,
						    l2_packet_rx_thread, l2, 0,
						    NULL);
	if (l2_ndisuio_global->rx_thread == NULL) {
		wpa_printf(MSG_INFO, "L2(NDISUIO): Failed to create RX "
			   "thread: %d", (int) GetLastError());
		eloop_unregister_event(l2->rx_avail, sizeof(l2->rx_avail));
		CloseHandle(l2_ndisuio_global->stop_request);
		l2_ndisuio_global->stop_request = NULL;
		os_free(l2);
		return NULL;
	}
#else /* _WIN32_WCE */
	l2_ndisuio_start_read(l2, 0);
#endif /* _WIN32_WCE */

	return l2;
}


void l2_packet_deinit(struct l2_packet_data *l2)
{
	if (l2 == NULL)
		return;

	if (l2_ndisuio_global) {
		l2_ndisuio_global->refcount--;
		l2_ndisuio_global->l2[l2_ndisuio_global->refcount] = NULL;
		if (l2_ndisuio_global->refcount) {
			wpa_printf(MSG_DEBUG, "L2(NDISUIO): restore filtering "
				   "ethertype to %04x",
				   l2_ndisuio_global->first_proto);
			l2_ndisuio_set_ether_type(
				l2_ndisuio_global->first_proto);
			return;
		}

#ifdef _WIN32_WCE
		wpa_printf(MSG_DEBUG, "L2(NDISUIO): Waiting for RX thread to "
			   "stop");
		SetEvent(l2_ndisuio_global->stop_request);
		/*
		 * Cancel pending ReadFile() in the RX thread (if we were still
		 * connected at this point).
		 */
		if (!DeviceIoControl(driver_ndis_get_ndisuio_handle(),
				     IOCTL_CANCEL_READ, NULL, 0, NULL, 0, NULL,
				     NULL)) {
			wpa_printf(MSG_DEBUG, "L2(NDISUIO): IOCTL_CANCEL_READ "
				   "failed: %d", (int) GetLastError());
			/* RX thread will exit blocking ReadFile once NDISUIO
			 * notices that the adapter is disconnected. */
		}
		WaitForSingleObject(l2_ndisuio_global->rx_thread, INFINITE);
		wpa_printf(MSG_DEBUG, "L2(NDISUIO): RX thread exited");
		CloseHandle(l2_ndisuio_global->rx_thread);
		CloseHandle(l2_ndisuio_global->stop_request);
		CloseHandle(l2_ndisuio_global->ready_for_read);
		CloseHandle(l2_ndisuio_global->rx_processed);
#endif /* _WIN32_WCE */

		os_free(l2_ndisuio_global);
		l2_ndisuio_global = NULL;
	}

#ifndef _WIN32_WCE
	CancelIo(driver_ndis_get_ndisuio_handle());
#endif /* _WIN32_WCE */

	eloop_unregister_event(l2->rx_avail, sizeof(l2->rx_avail));
	CloseHandle(l2->rx_avail);
	os_free(l2);
}


int l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len)
{
	return -1;
}


void l2_packet_notify_auth_start(struct l2_packet_data *l2)
{
}
