/* 
   BlueZ - Bluetooth protocol stack for Linux
   Copyright (C) 2000-2001 Qualcomm Incorporated

   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>

   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.
*/

/*
 * $Id$
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>
#include <syslog.h>
#include <errno.h>
#include <termios.h>
#include <fcntl.h>

#include <sys/param.h>
#include <sys/uio.h>
#include <sys/poll.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <asm/types.h>

#include <bluetooth.h>
#include <hci.h>
#include <hci_lib.h>

typedef struct {
	char  *str; unsigned int val;
} hci_map;

static char * hci_uint2str(hci_map *m, unsigned int val) 
{
	static char str[50];
	char *ptr = str;

	*ptr = 0;
	while (m->str) {
		if ((unsigned int) m->val & val)
			ptr += sprintf(ptr, "%s ", m->str);
		m++;
	} 	
	return str;
}

int hci_str2uint(hci_map *map, char *str, unsigned int *val)
{
	char *t, *ptr;
	hci_map *m;
	int set;

	if (!str)
		return 0;

	str = ptr = strdup(str);
	*val = set = 0;

	while ((t=strsep(&ptr, ","))) {
		for (m=map; m->str; m++) {
			if (!strcasecmp(m->str,t)) {
				*val |= (unsigned int) m->val;
				set = 1;
			}
		}
	} 	
	free(str);

	return set;
}

char *hci_dtypetostr(int type)
{
	switch (type) {
	case HCI_VHCI:
		return "VHCI";
	case HCI_USB:
		return "USB ";
	case HCI_PCCARD:
		return "PCCARD";
	case HCI_UART:
		return "UART";
	default:
		return "UKNW";
	}
}

/* HCI dev flags mapping */
hci_map dev_flags_map[] = {
	{ "UP",      HCI_UP      },
	{ "INIT",    HCI_INIT    },
	{ "RUNNING", HCI_RUNNING },
	{ "RAW",     HCI_RAW     },
	{ "PSCAN",   HCI_PSCAN   },
	{ "ISCAN",   HCI_ISCAN   },
	{ "IQUIRY",  HCI_INQUIRY },
	{ "AUTH",    HCI_AUTH    },
	{ "ENCRYPT", HCI_ENCRYPT },
	{ NULL }
};
char *hci_dflagstostr(uint32_t flags)
{
	static char str[50]; 
	char *ptr = str;
	hci_map *m = dev_flags_map;

	*ptr = 0;

	if (!hci_test_bit(HCI_UP, &flags))
		ptr += sprintf(ptr, "DOWN ");

	while (m->str) {
		if (hci_test_bit(m->val, &flags))
			ptr += sprintf(ptr, "%s ", m->str);
		m++;
	} 	
	return str;
}

/* HCI packet type mapping */
hci_map pkt_type_map[] = {
	{ "DM1", HCI_DM1 },
	{ "DM3", HCI_DM3 },
	{ "DM5", HCI_DM5 },
	{ "DH1", HCI_DH1 },
	{ "DH3", HCI_DH3 },
	{ "DH5", HCI_DH5 },
	{ "HV1", HCI_HV1 },
	{ "HV2", HCI_HV2 },
	{ "HV3", HCI_HV3 },
	{ NULL }
};
char *hci_ptypetostr(unsigned int ptype)
{
	return hci_uint2str(pkt_type_map, ptype);
}
int hci_strtoptype(char *str, unsigned int *val)
{
	return hci_str2uint(pkt_type_map, str, val);
}

/* Link policy mapping */
hci_map link_policy_map[] = {
	{ "NONE",    0 },
	{ "RSWITCH", HCI_LP_RSWITCH },
	{ "HOLD",    HCI_LP_HOLD    },
	{ "SNIFF",   HCI_LP_SNIFF   },
	{ "PARK",    HCI_LP_PARK    },
	{ NULL }
};
char *hci_lptostr(unsigned int lp)
{
	return hci_uint2str(link_policy_map, lp);
}
int hci_strtolp(char *str, unsigned int *val)
{
	return hci_str2uint(link_policy_map, str, val);
}

/* Link mode mapping */
hci_map link_mode_map[] = {
	{ "NONE",    0 },
	{ "ACCEPT",  HCI_LM_ACCEPT },
	{ "MASTER",  HCI_LM_MASTER },
	{ "AUTH",    HCI_LM_AUTH   },
	{ "ENCRYPT", HCI_LM_ENCRYPT},
	{ "TRUSTED", HCI_LM_TRUSTED},
	{ NULL }
};
char *hci_lmtostr(unsigned int lm)
{
	static char str[50];

	str[0] = 0;
	if (!(lm & HCI_LM_MASTER))
		strcpy(str, "SLAVE ");

	strcat(str, hci_uint2str(link_mode_map, lm));
	return str;
}
int hci_strtolm(char *str, unsigned int *val)
{
	return hci_str2uint(link_mode_map, str, val);
}

/* HCI functions that do not require open device */

int hci_devinfo(int dev_id, struct hci_dev_info *di)
{
	int s, err;

	s = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
	if (s < 0)
		return s;

	di->dev_id = dev_id;
	err = ioctl(s, HCIGETDEVINFO, (void *) di);
	close(s);

	return err;
}

inquiry_info *hci_inquiry(int dev_id, int len, int *num_rsp, uint8_t *lap, long flags)
{
	struct hci_inquiry_req *ir;
	char *buf, *ptr;
	int s, err, size;

	if (!*num_rsp)
		*num_rsp = 200; // enough ?

	size = sizeof(*ir) + (sizeof(inquiry_info) * (*num_rsp));
	if (!(buf = malloc(size)))
		return NULL;

	ir = (void *)buf;
	ir->dev_id  = dev_id;
	ir->num_rsp = *num_rsp;
	ir->length  = len;
	ir->flags   = flags;

	if (lap) {
		memcpy(ir->lap, lap, 3);
	} else {
		ir->lap[0] = 0x33;
		ir->lap[1] = 0x8b;
		ir->lap[2] = 0x9e;
	}

	if ((s = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0)
		goto failed;
	if (ioctl(s, HCIINQUIRY, (unsigned long)buf) < 0)
		goto failed;

	size = sizeof(inquiry_info) * ir->num_rsp;
	if (!(ptr = malloc(size)))
		goto failed;

	memcpy(ptr, buf + sizeof(*ir), size);
	*num_rsp = ir->num_rsp;

	free(buf);
	close(s);
	return (void *) ptr;

failed:
	err = errno;
	free(buf);
	close(s);
	errno = err;
	return NULL;
}

/* Open HCI device. 
 * Returns device descriptor (dd). */
int hci_open_dev(int dev_id)
{
	struct sockaddr_hci a;
	int dd, err;

	/* Create HCI socket */
	dd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
	if (dd < 0)
		return dd;
	
	/* Bind socket to the HCI device */
	a.hci_family = AF_BLUETOOTH;
	a.hci_dev = dev_id;
	if (bind(dd, (struct sockaddr *)&a, sizeof(a)) < 0)
		goto failed;

	return dd;

failed:
	err = errno;
	close(dd);
	errno = err;
	return -1;
}

int hci_close_dev(int dd)
{
	return close(dd);
}

/* HCI functions that require open device
 * dd - Device descriptor returned by hci_dev_open. */

int hci_send_cmd(int dd, uint16_t ogf, uint16_t ocf, uint8_t plen, void *param)
{
	uint8_t type = HCI_COMMAND_PKT;
	hci_command_hdr hc;
	struct iovec iv[3];
	int ivn;

	hc.opcode = htobs(cmd_opcode_pack(ogf, ocf));
	hc.plen= plen;

	iv[0].iov_base = &type;
	iv[0].iov_len  = 1;
	iv[1].iov_base = &hc;
	iv[1].iov_len  = HCI_COMMAND_HDR_SIZE;
	ivn = 2;

	if (plen) {
		iv[2].iov_base = param;
		iv[2].iov_len  = plen;
		ivn = 3;
	}

	while (writev(dd, iv, ivn) < 0) {
		if (errno == EAGAIN || errno == EINTR)
			continue;
		return -1;
	}
	return 0;
}

int hci_send_req(int dd, struct hci_request *r, int to)
{
	unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr;
	uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf));
	struct hci_filter nf, of;
	hci_event_hdr *hdr;
	int err, len, try;

	len = sizeof(of);
	if (getsockopt(dd, SOL_HCI, HCI_FILTER, &of, &len) < 0)
		return -1;

	hci_filter_clear(&nf);
	hci_filter_set_ptype(HCI_EVENT_PKT,  &nf);
	hci_filter_set_event(EVT_CMD_STATUS, &nf);
	hci_filter_set_event(EVT_CMD_COMPLETE, &nf);
	hci_filter_set_event(r->event, &nf);
	hci_filter_set_opcode(opcode, &nf);
	if (setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf)) < 0)
		return -1;

	if (hci_send_cmd(dd, r->ogf, r->ocf, r->clen, r->cparam) < 0)
		goto failed;

	try = 10;
	while (try--) {
		evt_cmd_complete *cc;
		evt_cmd_status   *cs;
	
		if (to) {
			struct pollfd p;
			int n;

			p.fd = dd; p.events = POLLIN;
			while ((n = poll(&p, 1, to)) < 0) {
				if (errno == EAGAIN || errno == EINTR)
					continue;
				goto failed;
			}

			if (!n) {
				errno = ETIMEDOUT;
				goto failed;
			}
			
			to -= 10;
			if (to < 0) to = 0;

		}

		while ((len = read(dd, buf, sizeof(buf))) < 0) {
			if (errno == EAGAIN || errno == EINTR)
				continue;
			goto failed;
		}

		hdr = (void *)(buf + 1);
		ptr = buf + (1 + HCI_EVENT_HDR_SIZE);
		len -= (1 + HCI_EVENT_HDR_SIZE);

		switch (hdr->evt) {
		case EVT_CMD_STATUS:
			cs = (void *)ptr;
	
			if (cs->opcode != opcode)
				continue;
			
			if (cs->status) {
				errno = EIO;
				goto failed;
			}
			break;

		case EVT_CMD_COMPLETE:
			cc = (void *)ptr;

			if (cc->opcode != opcode)
				continue;
	
			ptr += EVT_CMD_COMPLETE_SIZE;
			len -= EVT_CMD_COMPLETE_SIZE;

			r->rlen = MIN(len, r->rlen);
			memcpy(r->rparam, ptr, r->rlen);
			goto done;

		default:
			if (hdr->evt != r->event)
				break;
	
			r->rlen = MIN(len, r->rlen);
			memcpy(r->rparam, ptr, r->rlen);
			goto done;
		}
	}
	errno = ETIMEDOUT;

failed:
	err = errno;
	setsockopt(dd, SOL_HCI, HCI_FILTER, &of, sizeof(of));
	errno = err;
	return -1;

done:
	setsockopt(dd, SOL_HCI, HCI_FILTER, &of, sizeof(of));
	return 0;
}

int hci_create_connection(int dd, bdaddr_t *ba, int ptype, int rswitch, int to)
{
        evt_conn_complete rp;
        create_conn_cp cp;
        struct hci_request rq;

        memset(&cp, 0, sizeof(cp));
        bacpy(&cp.bdaddr, ba);
        cp.pkt_type    = ptype;
	cp.role_switch = rswitch;

        rq.ogf    = OGF_LINK_CTL;
        rq.ocf    = OCF_CREATE_CONN;
        rq.event  = EVT_CONN_COMPLETE;
        rq.cparam = &cp;
        rq.clen   = CREATE_CONN_CP_SIZE;
        rq.rparam = &rp;
        rq.rlen   = EVT_CONN_COMPLETE_SIZE;

        if (hci_send_req(dd, &rq, to) < 0)
                return -1;

        if (rp.status) {
                errno = EIO;
                return -1;
        }

        return rp.handle;
}

int hci_disconnect(int dd, int hndl, int res, int to)
{
        evt_disconn_complete rp;
        disconnect_cp cp;
        struct hci_request rq;

        memset(&cp, 0, sizeof(cp));
        cp.handle = hndl;
        cp.reason = res;

        rq.ogf    = OGF_LINK_CTL;
        rq.ocf    = OCF_DISCONNECT;
        rq.event  = EVT_DISCONN_COMPLETE;
        rq.cparam = &cp;
        rq.clen   = DISCONNECT_CP_SIZE;
        rq.rparam = &rp;
        rq.rlen   = EVT_DISCONN_COMPLETE_SIZE;

        if (hci_send_req(dd, &rq, to) < 0)
                return -1;

        if (rp.status) {
                errno = EIO;
                return -1;
        }
        return 0;
}

int hci_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to)
{
	evt_remote_name_req_complete rn;
	remote_name_req_cp cp;
	struct hci_request rq;

	memset(&cp, 0, sizeof(cp));
	bacpy(&cp.bdaddr, ba);

	rq.ogf = OGF_LINK_CTL;
	rq.ocf = OCF_REMOTE_NAME_REQ;
	rq.cparam = &cp;
	rq.clen   = REMOTE_NAME_REQ_CP_SIZE;
	rq.event  = EVT_REMOTE_NAME_REQ_COMPLETE;
	rq.rparam = &rn;
	rq.rlen   = EVT_REMOTE_NAME_REQ_COMPLETE_SIZE;

	if (hci_send_req(dd, &rq, to) < 0)
		return -1;

	if (rn.status) {
		errno = EIO;
		return -1;
	}

	rn.name[247] = '\0';
	strncpy(name, rn.name, len);
	return 0;
}

int hci_read_remote_features(int dd, int hndl, uint8_t *features, int to)
{
	evt_read_remote_features_complete rp;
	read_remote_features_cp cp;
	struct hci_request rq;
	
	memset(&cp, 0, sizeof(cp));
	cp.handle = hndl;
	
	rq.ogf    = OGF_LINK_CTL;
	rq.ocf    = OCF_READ_REMOTE_FEATURES;
	rq.event  = EVT_READ_REMOTE_FEATURES_COMPLETE;
	rq.cparam = &cp;
	rq.clen   = READ_REMOTE_FEATURES_CP_SIZE;
	rq.rparam = &rp;
	rq.rlen   = EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE;
	
	if (hci_send_req(dd, &rq, to) < 0)
	        return -1;
	
	if (rp.status) {
	        errno = EIO;
	        return -1;
	}
	
	memcpy(features, rp.features, 8);
	return 0;
}

int hci_read_remote_version(int dd, int hndl, struct hci_version *ver, int to)
{
	evt_read_remote_version_complete rp;
	read_remote_version_cp cp;
	struct hci_request rq;
	
	memset(&cp, 0, sizeof(cp));
	cp.handle = hndl;
	
	rq.ogf    = OGF_LINK_CTL;
	rq.ocf    = OCF_READ_REMOTE_VERSION;
	rq.event  = EVT_READ_REMOTE_VERSION_COMPLETE;
	rq.cparam = &cp;
	rq.clen   = READ_REMOTE_VERSION_CP_SIZE;
	rq.rparam = &rp;
	rq.rlen   = EVT_READ_REMOTE_VERSION_COMPLETE_SIZE;
	
	if (hci_send_req(dd, &rq, to) < 0)
		return -1;
	
	if (rp.status) {
		errno = EIO;
		return -1;
	}
	
	ver->manufacturer = btohs(rp.manufacturer);
	ver->lmp_ver      = rp.lmp_ver;
	ver->lmp_subver   = btohs(rp.lmp_subver);
	return 0;
}

int hci_read_local_version(int dd, struct hci_version *ver, int to)
{
	read_local_version_rp rp;
	struct hci_request rq;

	memset(&rq, 0, sizeof(rq));
	rq.ogf = OGF_INFO_PARAM;
	rq.ocf = OCF_READ_LOCAL_VERSION;
	rq.cparam = NULL;
	rq.clen = 0;
	rq.rparam = &rp;
	rq.rlen = READ_LOCAL_VERSION_RP_SIZE;

	if (hci_send_req(dd, &rq, 1000) < 0)
		return -1;

	if (rp.status) {
		errno = EIO;
		return -1;
	}

	ver->manufacturer = btohs(rp.manufacturer);
	ver->hci_ver    = rp.lmp_ver;
	ver->hci_rev    = btohs(rp.hci_rev);
	ver->lmp_ver    = rp.lmp_ver;
	ver->lmp_subver = btohs(rp.lmp_subver);

	return 0;
}
