/*-
 * Copyright (c) 2015 Quantenna Communications, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id: ieee80211_qfdr.c 2759 2015-12-20 10:48:20Z Jason $
 */
#ifndef EXPORT_SYMTAB
#define	EXPORT_SYMTAB
#endif

/*
 * IEEE 802.11 sync scan result for Quantenna QFDR.
 */
#ifndef AUTOCONF_INCLUDED
#include <linux/config.h>
#endif
#include <linux/version.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/in.h>
#include <linux/workqueue.h>
#include <linux/kthread.h>
#include <net/sock.h>

#include "net80211/if_media.h"

#include "net80211/ieee80211_var.h"

#define QFDR_REP_TIMEOUT   (2 * HZ)
#define QFDR_REQ_MAX_SIZE  512

static char *local_ip = "0.0.0.0";
module_param(local_ip, charp, S_IRUGO);
MODULE_PARM_DESC(local_ip, "qfdr local ip");

static char *remote_ip = "0.0.0.0";
module_param(remote_ip, charp, S_IRUGO);
MODULE_PARM_DESC(remote_ip, "qfdr remote ip");

static unsigned short req_port = 0;
module_param(req_port, ushort, S_IRUGO);
MODULE_PARM_DESC(req_port, "qfdr port to recv req");

static unsigned short rep_port = 0;
module_param(rep_port, ushort, S_IRUGO);
MODULE_PARM_DESC(rep_port, "qfdr port to recv rep");

static struct socket *sock_send;
static struct socket *sock_recv_req;
static struct socket *sock_recv_rep;
static struct sockaddr_in sin_req;
static struct sockaddr_in sin_rep;

static struct task_struct *thread_recv_req;
static struct completion comp_recv_req_thread;

static struct socket * qfdr_create_recv_socket(unsigned int addr, unsigned short port)
{
	struct sockaddr_in sin_bind;
	struct socket *socket = NULL;

	if (sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &socket)) {
		printk(KERN_ERR "%s: Failed to create socket\n", __func__);
		return NULL;
	}

	sin_bind.sin_family = AF_INET;
	sin_bind.sin_addr.s_addr = addr;
	sin_bind.sin_port = htons(port);

	if (kernel_bind(socket, (struct sockaddr *)&sin_bind, sizeof(sin_bind))) {
		printk(KERN_ERR "%s: Failed to bind socket to port %pI4:%d\n", __func__, &addr, port);
		sock_release(socket);
		return NULL;
	}

	return socket;
}

static int qfdr_recv(struct socket *sock, char *buffer, size_t buflen)
{
	struct msghdr	msg = {NULL};
	struct kvec	iov;
	int		len;

	/* adjust the RCVBUF */
	if (buflen > sock->sk->sk_rcvbuf)
		sock->sk->sk_rcvbuf = buflen;

	iov.iov_base     = buffer;
	iov.iov_len      = buflen;

	len = kernel_recvmsg(sock, &msg, &iov, 1, buflen, 0);

	return len;
}

static int qfdr_send(struct socket *sock, char *buffer, size_t buflen, struct sockaddr_in *dest_addr)
{
	struct msghdr	msg = {.msg_flags = MSG_DONTWAIT|MSG_NOSIGNAL};
	struct kvec	iov;
	int		len;

	/* adjust the SNDBUF */
	if (buflen > sock->sk->sk_sndbuf)
		sock->sk->sk_sndbuf = buflen;

	msg.msg_name     = dest_addr;
	msg.msg_namelen  = sizeof(struct sockaddr_in);

	iov.iov_base     = buffer;
	iov.iov_len      = buflen;

	len = kernel_sendmsg(sock, &msg, &iov, 1, buflen);

	return len;
}

int qfdr_remote_giwscan(struct iwscanreq *req)
{
	struct qfdr_remote_aplist_req request;
	char *recvbuf;
	size_t recvbuf_size;
	int recvlen;
	struct qfdr_remote_aplist_rep *rep;

	request.type = QFDR_GIWSCAN;
	memcpy(&request.info, req->info, sizeof(struct iw_request_info));
	request.extra_len = req->end_buf - req->current_ev;
	strcpy(request.dev_name, req->vap->iv_dev->name);
	qfdr_send(sock_send, (char *)&request, sizeof(request), &sin_req);

	recvbuf_size = request.extra_len + sizeof(struct qfdr_remote_aplist_rep);
	recvbuf = kmalloc(recvbuf_size, GFP_KERNEL);
	if (!recvbuf) {
		printk(KERN_ERR "%s: Failed to alloc recvbuf\n", __func__);
		return 0;
	}

	recvlen = qfdr_recv(sock_recv_rep, recvbuf, recvbuf_size);
	if (recvlen < sizeof(struct qfdr_remote_aplist_rep)) {
		kfree(recvbuf);
		if (recvlen < 0)
			printk(KERN_ERR "%s: Failed to recv rep with errno %d\n", __func__, recvlen);
		else
			printk(KERN_ERR "%s: recv invalid rep\n", __func__);
		return 0;
	}

	rep = (struct qfdr_remote_aplist_rep *)recvbuf;
	if (rep->res != ENOMEM && rep->type == QFDR_GIWSCAN) {
		memcpy(req->current_ev, rep->extra, rep->length);
		req->current_ev += rep->length;
	}
	kfree(recvbuf);

	return rep->res;
}

int qfdr_remote_ap_scan_results(struct ap_scan_iter *iter)
{
	struct qfdr_remote_aplist_req request;
	char *recvbuf;
	size_t recvbuf_size;
	int recvlen;
	struct qfdr_remote_aplist_rep *rep;

	request.type = QFDR_AP_SCAN_RESULT;
	request.extra_len = iter->end_buf - iter->current_env;
	strcpy(request.dev_name, iter->vap->iv_dev->name);
	qfdr_send(sock_send, (char *)&request, sizeof(request), &sin_req);

	recvbuf_size = request.extra_len + sizeof(struct qfdr_remote_aplist_rep);
	recvbuf = kmalloc(recvbuf_size, GFP_KERNEL);
	if (!recvbuf) {
		printk(KERN_ERR "%s: Failed to alloc recvbuf\n", __func__);
		return 0;
	}

	recvlen = qfdr_recv(sock_recv_rep, recvbuf, recvbuf_size);
	if (recvlen < sizeof(struct qfdr_remote_aplist_rep)) {
		kfree(recvbuf);
		if (recvlen < 0)
			printk(KERN_ERR "%s: Failed to recv rep with errno %d\n", __func__, recvlen);
		else
			printk(KERN_ERR "%s: recv invalid rep\n", __func__);
		return 0;
	}

	rep = (struct qfdr_remote_aplist_rep *)recvbuf;
	if (rep->res != ENOMEM && rep->type == QFDR_AP_SCAN_RESULT) {
		memcpy(iter->current_env, rep->extra, rep->length);
		iter->current_env += rep->length;
		iter->ap_counts += rep->ap_counts;
	}
	kfree(recvbuf);

	return rep->res;
}

int qfdr_remote_siwscan(char *dev_name, struct iw_point *data)
{
	struct qfdr_remote_scan_req *request;
	int req_len = sizeof(struct qfdr_remote_scan_req);

	if (data)
		req_len += data->length;
	if (req_len > QFDR_REQ_MAX_SIZE) {
		printk(KERN_ERR "%s: qfdr peer canonly recv %d bytes req\n", __func__, QFDR_REQ_MAX_SIZE);
		return -EINVAL;
	}
	request = kmalloc(req_len, GFP_KERNEL);
	if (!request) {
		printk(KERN_ERR "%s: Failed to alloc buf\n", __func__);
		return -ENOMEM;
	}

	strcpy(request->dev_name, dev_name);
	if (data) {
		request->type = QFDR_SIWSCAN;
		request->flags = data->flags;
		request->length = data->length;
		memcpy(request->pointer, data->pointer, data->length);
	} else {
		request->type = QFDR_SIWSCAN_SIMPLE;
	}

	qfdr_send(sock_send, (char *)request, req_len, &sin_req);
	kfree(request);

	return 0;
}

static void qfdr_process_req(char *recvbuf, int recvlen)
{
	int type = *((int *)recvbuf);
	struct qfdr_remote_aplist_rep rep_nomem = {ENOMEM, 0, 0, 0};
	struct qfdr_remote_aplist_rep *rep;

	if (type == QFDR_GIWSCAN) {
		rep = qfdr_giwscan_for_remote((struct qfdr_remote_aplist_req *)recvbuf);
		if (rep) {
			qfdr_send(sock_send, (char *)rep, sizeof(struct qfdr_remote_aplist_rep) + rep->length, &sin_rep);
			kfree(rep);
		} else {
			rep = &rep_nomem;
			rep->type = QFDR_GIWSCAN;
			qfdr_send(sock_send, (char *)rep, sizeof(struct qfdr_remote_aplist_rep) + rep->length, &sin_rep);
		}
	} else if (type == QFDR_AP_SCAN_RESULT) {
		rep = qfdr_ap_scan_results_for_remote((struct qfdr_remote_aplist_req *)recvbuf);
		if (rep) {
			qfdr_send(sock_send, (char *)rep, sizeof(struct qfdr_remote_aplist_rep) + rep->length, &sin_rep);
			kfree(rep);
		} else {
			rep = &rep_nomem;
			rep->type = QFDR_AP_SCAN_RESULT;
			qfdr_send(sock_send, (char *)rep, sizeof(struct qfdr_remote_aplist_rep) + rep->length, &sin_rep);
		}
	} else if (type == QFDR_SIWSCAN_SIMPLE || type == QFDR_SIWSCAN) {
		qfdr_siwscan_for_remote((struct qfdr_remote_scan_req *)recvbuf);
	}
}

static int qfdr_recv_req_thread(void *data)
{
	char *recvbuf;
	int recvlen;

	recvbuf = kmalloc(QFDR_REQ_MAX_SIZE, GFP_KERNEL);
	if (!recvbuf) {
		printk(KERN_ERR "%s: Failed to alloc recvbuf\n", __func__);
		return -ENOMEM;
	}

	allow_signal(SIGTERM);

	while (!signal_pending(current)) {
		recvlen = qfdr_recv(sock_recv_req, recvbuf, QFDR_REQ_MAX_SIZE);
		if (recvlen > 0) {
			qfdr_process_req(recvbuf, recvlen);
		} else {
			printk(KERN_WARNING "%s: broken pipe on socket\n", __func__);
		}
	}

	kfree(recvbuf);
	complete(&comp_recv_req_thread);
	thread_recv_req = NULL;

	return 0;
}

/*
 * Module glue.
 */
MODULE_AUTHOR("Quantenna, Jason.Wang");
MODULE_DESCRIPTION("802.11 wireless support: Quantenna QFDR sync scan result");
#ifdef MODULE_LICENSE
MODULE_LICENSE("Dual BSD/GPL");
#endif

static int __init init_wlan_qfdr(void)
{
	unsigned int local_addr, remote_addr;

	local_addr = in_aton(local_ip);
	if (local_addr == INADDR_ANY || local_addr == INADDR_NONE) {
		printk(KERN_ERR "%s: Invalid local IP %pI4\n", __func__, &local_addr);
		return -EINVAL;
	}

	remote_addr = in_aton(remote_ip);
	if (remote_addr == INADDR_ANY || remote_addr == INADDR_NONE) {
		printk(KERN_ERR "%s: Invalid remote IP %pI4\n", __func__, &remote_addr);
		return -EINVAL;
	}

	if (req_port == 0) {
		printk(KERN_ERR "%s: Invalid req port %u, must be greater than 0\n", __func__, req_port);
		return -EINVAL;
	}

	if (rep_port == 0 || rep_port == req_port) {
		printk(KERN_ERR "%s: Invalid rep port %u, must be greater than 0 and not same as req port\n", __func__, rep_port);
		return -EINVAL;
	}

	if (sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock_send)) {
		printk(KERN_ERR "%s: Failed to create send socket\n", __func__);
		goto fail;
	}

	sock_recv_req = qfdr_create_recv_socket(local_addr, req_port);
	if (!sock_recv_req) {
		printk(KERN_ERR "%s: Failed to create req recv socket\n", __func__);
		goto fail;
	}

	sock_recv_rep = qfdr_create_recv_socket(local_addr, rep_port);
	if (!sock_recv_rep) {
		printk(KERN_ERR "%s: Failed to create rep recv socket\n", __func__);
		goto fail;
	}

	/* set the RCVTIMEO */
	sock_recv_rep->sk->sk_rcvtimeo = QFDR_REP_TIMEOUT;

	sin_req.sin_family = AF_INET;
	sin_req.sin_addr.s_addr = remote_addr;
	sin_req.sin_port = htons(req_port);

	sin_rep.sin_family = AF_INET;
	sin_rep.sin_addr.s_addr = remote_addr;
	sin_rep.sin_port = htons(rep_port);

	thread_recv_req = kthread_run(qfdr_recv_req_thread, NULL, "qfdr");
	if (IS_ERR(thread_recv_req)) {
		printk(KERN_ERR "%s: Failed to start qfdr_recv_req_thread\n", __func__);
		goto fail;
	}

	init_completion(&comp_recv_req_thread);
	ieee80211_register_qfdr_remote_siwscan_hook(qfdr_remote_siwscan);
	ieee80211_register_qfdr_remote_giwscan_hook(qfdr_remote_giwscan);
	ieee80211_register_qfdr_remote_ap_scan_results_hook(qfdr_remote_ap_scan_results);

	printk(KERN_INFO "Load qfdr module successfully, local ip:%pI4, remote ip:%pI4, req_port:%u, rep_port:%u\n", &local_addr, &remote_addr, req_port, rep_port);
	return 0;
fail:
	if (sock_send)
		sock_release(sock_send);
	if (sock_recv_req)
		sock_release(sock_recv_req);
	if (sock_recv_rep)
		sock_release(sock_recv_rep);

	return -EAGAIN;
}
module_init(init_wlan_qfdr);

static void __exit exit_wlan_qfdr(void)
{
	ieee80211_register_qfdr_remote_siwscan_hook(NULL);
	ieee80211_register_qfdr_remote_giwscan_hook(NULL);
	ieee80211_register_qfdr_remote_ap_scan_results_hook(NULL);
	if (thread_recv_req) {
		send_sig(SIGTERM, thread_recv_req, 0);
		wait_for_completion(&comp_recv_req_thread);
	}

	if (sock_send)
		sock_release(sock_send);
	if (sock_recv_req)
		sock_release(sock_recv_req);
	if (sock_recv_rep)
		sock_release(sock_recv_rep);
}
module_exit(exit_wlan_qfdr);
