diff options
| -rw-r--r-- | input/Makefile.am | 2 | ||||
| -rw-r--r-- | input/device.c | 220 | ||||
| -rw-r--r-- | input/device.h | 6 | ||||
| -rw-r--r-- | input/manager.c | 133 | ||||
| -rw-r--r-- | input/storage.c | 275 | ||||
| -rw-r--r-- | input/storage.h | 37 | 
6 files changed, 207 insertions, 466 deletions
diff --git a/input/Makefile.am b/input/Makefile.am index e22f1253..1b3ab5de 100644 --- a/input/Makefile.am +++ b/input/Makefile.am @@ -6,7 +6,7 @@ plugin_LTLIBRARIES = input.la  input_la_SOURCES = main.c manager.h manager.c \  		server.h server.c device.h device.c \ -		storage.h storage.c fakehid.c fakehid.h +		fakehid.c fakehid.h  LDADD = $(top_builddir)/common/libhelper.a \  		@GDBUS_LIBS@ @GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@ diff --git a/input/device.c b/input/device.c index 44bec0d6..0283918b 100644 --- a/input/device.c +++ b/input/device.c @@ -34,21 +34,26 @@  #include <sys/socket.h>  #include <bluetooth/bluetooth.h> +#include <bluetooth/hci.h> +#include <bluetooth/hci_lib.h>  #include <bluetooth/hidp.h>  #include <bluetooth/l2cap.h>  #include <bluetooth/rfcomm.h>  #include <bluetooth/sdp.h> +#include <bluetooth/sdp_lib.h>  #include <glib.h>  #include <dbus/dbus.h>  #include <gdbus.h>  #include "logging.h" +#include "textfile.h"  #include "uinput.h" +#include "../src/storage.h" +  #include "device.h"  #include "error.h" -#include "storage.h"  #include "fakehid.h"  #include "glib-helper.h" @@ -78,6 +83,7 @@ struct input_device {  	char			*path;  	bdaddr_t		src;  	bdaddr_t		dst; +	uint32_t		handle;  	char			*name;  	GSList			*connections;  }; @@ -466,13 +472,168 @@ static int fake_hid_disconnect(struct input_conn *iconn)  	return fhid->disconnect(iconn->fake);  } -static int hidp_connadd(bdaddr_t *src, bdaddr_t *dst, -		int ctrl_sk, int intr_sk, int timeout, const char *name) +static int encrypt_link(const char *src_addr, const char *dst_addr) +{ +	char filename[PATH_MAX + 1]; +	struct hci_conn_info_req *cr; +	int dd, err, dev_id; +	char *str; + +	create_name(filename, PATH_MAX, STORAGEDIR, src_addr, "linkkeys"); + +	str = textfile_get(filename, dst_addr); +	if (!str) { +		error("Encryption link key not found"); +		return -ENOKEY; +	} + +	free(str); + +	cr = g_try_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info)); +	if (!cr) +		return -ENOMEM; + +	dev_id = hci_devid(src_addr); +	if (dev_id < 0) { +		g_free(cr); +		return -errno; +	} + +	dd = hci_open_dev(dev_id); +	if (dd < 0) { +		g_free(cr); +		return -errno; +	} + +	str2ba(dst_addr, &cr->bdaddr); +	cr->type = ACL_LINK; + +	if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) +		goto fail; + +	if (cr->conn_info->link_mode & HCI_LM_ENCRYPT) { +		/* Already encrypted */ +		goto done; +	} + +	if (hci_authenticate_link(dd, htobs(cr->conn_info->handle), 1000) < 0) { +		error("Link authentication failed: %s (%d)", +						strerror(errno), errno); +		goto fail; +	} + +	if (hci_encrypt_link(dd, htobs(cr->conn_info->handle), 1, 1000) < 0) { +		error("Link encryption failed: %s (%d)", +						strerror(errno), errno); +		goto fail; +	} + +done: +	g_free(cr); + +	hci_close_dev(dd); + +	return 0; + +fail: +	g_free(cr); + +	err = errno; +	hci_close_dev(dd); + +	return -err; +} + +static void epox_endian_quirk(unsigned char *data, int size) +{ +	/* USAGE_PAGE (Keyboard)	05 07 +	 * USAGE_MINIMUM (0)		19 00 +	 * USAGE_MAXIMUM (65280)	2A 00 FF   <= must be FF 00 +	 * LOGICAL_MINIMUM (0)		15 00 +	 * LOGICAL_MAXIMUM (65280)	26 00 FF   <= must be FF 00 +	 */ +	unsigned char pattern[] = { 0x05, 0x07, 0x19, 0x00, 0x2a, 0x00, 0xff, +						0x15, 0x00, 0x26, 0x00, 0xff }; +	int i; + +	if (!data) +		return; + +	for (i = 0; i < size - sizeof(pattern); i++) { +		if (!memcmp(data + i, pattern, sizeof(pattern))) { +			data[i + 5] = 0xff; +			data[i + 6] = 0x00; +			data[i + 10] = 0xff; +			data[i + 11] = 0x00; +		} +	} +} + +static void extract_hid_record(sdp_record_t *rec, struct hidp_connadd_req *req) +{ +	sdp_data_t *pdlist, *pdlist2; +	uint8_t attr_val; + +	pdlist = sdp_data_get(rec, 0x0101); +	pdlist2 = sdp_data_get(rec, 0x0102); +	if (pdlist) { +		if (pdlist2) { +			if (strncmp(pdlist->val.str, pdlist2->val.str, 5)) { +				strncpy(req->name, pdlist2->val.str, 127); +				strcat(req->name, " "); +			} +			strncat(req->name, pdlist->val.str, 127 - strlen(req->name)); +		} else +			strncpy(req->name, pdlist->val.str, 127); +	} else { +		pdlist2 = sdp_data_get(rec, 0x0100); +		if (pdlist2) +			strncpy(req->name, pdlist2->val.str, 127); +	} + +	pdlist = sdp_data_get(rec, SDP_ATTR_HID_PARSER_VERSION); +	req->parser = pdlist ? pdlist->val.uint16 : 0x0100; + +	pdlist = sdp_data_get(rec, SDP_ATTR_HID_DEVICE_SUBCLASS); +	req->subclass = pdlist ? pdlist->val.uint8 : 0; + +	pdlist = sdp_data_get(rec, SDP_ATTR_HID_COUNTRY_CODE); +	req->country = pdlist ? pdlist->val.uint8 : 0; + +	pdlist = sdp_data_get(rec, SDP_ATTR_HID_VIRTUAL_CABLE); +	attr_val = pdlist ? pdlist->val.uint8 : 0; +	if (attr_val) +		req->flags |= (1 << HIDP_VIRTUAL_CABLE_UNPLUG); + +	pdlist = sdp_data_get(rec, SDP_ATTR_HID_BOOT_DEVICE); +	attr_val = pdlist ? pdlist->val.uint8 : 0; +	if (attr_val) +		req->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE); + +	pdlist = sdp_data_get(rec, SDP_ATTR_HID_DESCRIPTOR_LIST); +	if (pdlist) { +		pdlist = pdlist->val.dataseq; +		pdlist = pdlist->val.dataseq; +		pdlist = pdlist->next; + +		req->rd_data = g_try_malloc0(pdlist->unitSize); +		if (req->rd_data) { +			memcpy(req->rd_data, (unsigned char *) pdlist->val.str, +								pdlist->unitSize); +			req->rd_size = pdlist->unitSize; +			epox_endian_quirk(req->rd_data, req->rd_size); +		} +	} +} + +static int hidp_connadd(const bdaddr_t *src, const bdaddr_t *dst, int ctrl_sk, +		int intr_sk, int timeout, const char *name, const uint32_t handle)  {  	struct hidp_connadd_req req;  	struct fake_hid *fake_hid;  	struct fake_input *fake; -	char addr[18]; +	sdp_record_t *rec; +	char src_addr[18], dst_addr[18];  	int ctl, err;  	memset(&req, 0, sizeof(req)); @@ -481,12 +642,19 @@ static int hidp_connadd(bdaddr_t *src, bdaddr_t *dst,  	req.flags     = 0;  	req.idle_to   = timeout; -	err = get_stored_device_info(src, dst, &req); -	if (err < 0) { -		error("Rejected connection from unknown device %s", addr); +	ba2str(src, src_addr); +	ba2str(dst, dst_addr); + +	rec = fetch_record(src_addr, dst_addr, handle); +	if (!rec) { +		error("Rejected connection from unknown device %s", dst_addr); +		err = -EPERM;  		goto cleanup;  	} +	extract_hid_record(rec, &req); +	sdp_record_free(rec); +  	fake_hid = get_fake_hid(req.vendor, req.product);  	if (fake_hid) {  		fake = g_new0(struct fake_input, 1); @@ -502,10 +670,8 @@ static int hidp_connadd(bdaddr_t *src, bdaddr_t *dst,  		return -errno;  	} -	ba2str(dst, addr); -  	if (req.subclass & 0x40) { -		err = encrypt_link(src, dst); +		err = encrypt_link(src_addr, dst_addr);  		if (err < 0 && err != -EACCES)  			goto cleanup;  	} @@ -524,7 +690,7 @@ static int hidp_connadd(bdaddr_t *src, bdaddr_t *dst,  		goto cleanup;  	} -	info("New input device %s (%s)", addr, req.name); +	info("New input device %s (%s)", dst_addr, req.name);  cleanup:  	if (req.rd_data) @@ -548,7 +714,7 @@ static void interrupt_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,  	iconn->intr_sk = g_io_channel_unix_get_fd(chan);  	err = hidp_connadd(&idev->src, &idev->dst,  				iconn->ctrl_sk, iconn->intr_sk, -					iconn->timeout, idev->name); +				iconn->timeout, idev->name, idev->handle);  	if (err < 0)  		goto failed; @@ -860,17 +1026,23 @@ static GDBusSignalTable device_signals[] = {  };  static struct input_device *input_device_new(DBusConnection *conn, -					const char *path, bdaddr_t *src, -					bdaddr_t *dst) +					const char *path, const bdaddr_t *src, +					const bdaddr_t *dst, const uint32_t handle)  {  	struct input_device *idev; +	char name[249], src_addr[18], dst_addr[18];  	idev = g_new0(struct input_device, 1);  	bacpy(&idev->src, src);  	bacpy(&idev->dst, dst);  	idev->path = g_strdup(path); -	read_device_name(src, dst, &idev->name);  	idev->conn = dbus_connection_ref(conn); +	idev->handle = handle; + +	ba2str(src, src_addr); +	ba2str(dst, dst_addr); +	if (read_device_name(src_addr, dst_addr, name) == 0) +		idev->name = g_strdup(name);  	if (g_dbus_register_interface(conn, idev->path, INPUT_DEVICE_INTERFACE,  					device_methods, device_signals, NULL, @@ -881,8 +1053,8 @@ static struct input_device *input_device_new(DBusConnection *conn,  		return NULL;  	} -	info("Registered interface %s on path %s", INPUT_DEVICE_INTERFACE, -		idev->path); +	info("Registered interface %s on path %s", +			INPUT_DEVICE_INTERFACE, idev->path);  	return idev;  } @@ -905,15 +1077,15 @@ static struct input_conn *input_conn_new(struct input_device *idev,  }  int input_device_register(DBusConnection *conn, const char *path, -			bdaddr_t *src, bdaddr_t *dst, const char *uuid, -			int timeout) +			const bdaddr_t *src, const bdaddr_t *dst, +			const char *uuid, uint32_t handle, int timeout)  {  	struct input_device *idev;  	struct input_conn *iconn;  	idev = find_device_by_path(devices, path);  	if (!idev) { -		idev = input_device_new(conn, path, src, dst); +		idev = input_device_new(conn, path, src, dst, handle);  		if (!idev)  			return -EINVAL;  		devices = g_slist_append(devices, idev); @@ -936,7 +1108,7 @@ int fake_input_register(DBusConnection *conn, const char *path, bdaddr_t *src,  	idev = find_device_by_path(devices, path);  	if (!idev) { -		idev = input_device_new(conn, path, src, dst); +		idev = input_device_new(conn, path, src, dst, 0);  		if (!idev)  			return -EINVAL;  		devices = g_slist_append(devices, idev); @@ -989,8 +1161,6 @@ int input_device_unregister(const char *path, const char *uuid)  		return -EBUSY;  	} -	del_stored_device_info(&idev->src, &idev->dst); -  	idev->connections = g_slist_remove(idev->connections, iconn);  	input_conn_free(iconn);  	if (idev->connections) @@ -1050,7 +1220,7 @@ int input_device_close_channels(const bdaddr_t *src, const bdaddr_t *dst)  	return 0;  } -int input_device_connadd(bdaddr_t *src, bdaddr_t *dst) +int input_device_connadd(const bdaddr_t *src, const bdaddr_t *dst)  {  	struct input_device *idev;  	struct input_conn *iconn; @@ -1065,7 +1235,7 @@ int input_device_connadd(bdaddr_t *src, bdaddr_t *dst)  		return -ENOENT;  	err = hidp_connadd(src, dst, iconn->ctrl_sk, iconn->intr_sk, -				iconn->timeout, idev->name); +				iconn->timeout, idev->name, idev->handle);  	if (err < 0)  		goto error; diff --git a/input/device.h b/input/device.h index cdc65171..030c75ad 100644 --- a/input/device.h +++ b/input/device.h @@ -39,12 +39,12 @@ struct fake_input {  };  int input_device_register(DBusConnection *conn, const char *path, -			bdaddr_t *src, bdaddr_t *dst, const char *uuid, -			int timeout); +			const bdaddr_t *src, const bdaddr_t *dst, const char *uuid, +			const uint32_t handle, int timeout);  int fake_input_register(DBusConnection *conn, const char *path, bdaddr_t *src,  			bdaddr_t *dst, const char *uuid, uint8_t channel);  int input_device_unregister(const char *path, const char *uuid);  int input_device_set_channel(const bdaddr_t *src, const bdaddr_t *dst, int psm, int nsk);  int input_device_close_channels(const bdaddr_t *src, const bdaddr_t *dst); -int input_device_connadd(bdaddr_t *src, bdaddr_t *dst); +int input_device_connadd(const bdaddr_t *src, const bdaddr_t *dst); diff --git a/input/manager.c b/input/manager.c index 0656b510..578d56e4 100644 --- a/input/manager.c +++ b/input/manager.c @@ -43,120 +43,11 @@  #include "device.h"  #include "server.h"  #include "manager.h" -#include "storage.h"  static int idle_timeout = 0;  static DBusConnection *connection = NULL; -static void epox_endian_quirk(unsigned char *data, int size) -{ -	/* USAGE_PAGE (Keyboard)	05 07 -	 * USAGE_MINIMUM (0)		19 00 -	 * USAGE_MAXIMUM (65280)	2A 00 FF   <= must be FF 00 -	 * LOGICAL_MINIMUM (0)		15 00 -	 * LOGICAL_MAXIMUM (65280)	26 00 FF   <= must be FF 00 -	 */ -	unsigned char pattern[] = { 0x05, 0x07, 0x19, 0x00, 0x2a, 0x00, 0xff, -						0x15, 0x00, 0x26, 0x00, 0xff }; -	int i; - -	if (!data) -		return; - -	for (i = 0; i < size - sizeof(pattern); i++) { -		if (!memcmp(data + i, pattern, sizeof(pattern))) { -			data[i + 5] = 0xff; -			data[i + 6] = 0x00; -			data[i + 10] = 0xff; -			data[i + 11] = 0x00; -		} -	} -} - -static void extract_hid_record(sdp_record_t *rec, struct hidp_connadd_req *req) -{ -	sdp_data_t *pdlist, *pdlist2; -	uint8_t attr_val; - -	pdlist = sdp_data_get(rec, 0x0101); -	pdlist2 = sdp_data_get(rec, 0x0102); -	if (pdlist) { -		if (pdlist2) { -			if (strncmp(pdlist->val.str, pdlist2->val.str, 5)) { -				strncpy(req->name, pdlist2->val.str, 127); -				strcat(req->name, " "); -			} -			strncat(req->name, pdlist->val.str, 127 - strlen(req->name)); -		} else -			strncpy(req->name, pdlist->val.str, 127); -	} else { -		pdlist2 = sdp_data_get(rec, 0x0100); -		if (pdlist2) -			strncpy(req->name, pdlist2->val.str, 127); - 	} - -	pdlist = sdp_data_get(rec, SDP_ATTR_HID_PARSER_VERSION); -	req->parser = pdlist ? pdlist->val.uint16 : 0x0100; - -	pdlist = sdp_data_get(rec, SDP_ATTR_HID_DEVICE_SUBCLASS); -	req->subclass = pdlist ? pdlist->val.uint8 : 0; - -	pdlist = sdp_data_get(rec, SDP_ATTR_HID_COUNTRY_CODE); -	req->country = pdlist ? pdlist->val.uint8 : 0; - -	pdlist = sdp_data_get(rec, SDP_ATTR_HID_VIRTUAL_CABLE); -	attr_val = pdlist ? pdlist->val.uint8 : 0; -	if (attr_val) -		req->flags |= (1 << HIDP_VIRTUAL_CABLE_UNPLUG); - -	pdlist = sdp_data_get(rec, SDP_ATTR_HID_BOOT_DEVICE); -	attr_val = pdlist ? pdlist->val.uint8 : 0; -	if (attr_val) -		req->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE); - -	pdlist = sdp_data_get(rec, SDP_ATTR_HID_DESCRIPTOR_LIST); -	if (pdlist) { -		pdlist = pdlist->val.dataseq; -		pdlist = pdlist->val.dataseq; -		pdlist = pdlist->next; - -		req->rd_data = g_try_malloc0(pdlist->unitSize); -		if (req->rd_data) { -			memcpy(req->rd_data, (unsigned char *) pdlist->val.str, -								pdlist->unitSize); -			req->rd_size = pdlist->unitSize; -			epox_endian_quirk(req->rd_data, req->rd_size); -		} -	} -} - -/* - * Stored inputs registration functions - */ - -static int load_stored(bdaddr_t *src, bdaddr_t *dst, -		       struct hidp_connadd_req *hidp) -{ -	char filename[PATH_MAX + 1]; -	char *value; -	char src_addr[18], dst_addr[18]; - -	ba2str(src, src_addr); -	ba2str(dst, dst_addr); - -	/* load the input stored */ -	create_name(filename, PATH_MAX, STORAGEDIR, src_addr, "input"); - -	value = textfile_get(filename, dst_addr); -	if (!value) -		return -EINVAL; - -	memset(&hidp, 0, sizeof(hidp)); - -	return parse_stored_device_info(value, hidp); -} -  static void input_remove(struct btd_device *device, const char *uuid)  {  	const gchar *path = device_get_path(device); @@ -170,31 +61,23 @@ static int hid_device_probe(struct btd_device *device, GSList *records)  {  	struct btd_adapter *adapter = device_get_adapter(device);  	const gchar *path = device_get_path(device); -	struct hidp_connadd_req hidp; +	sdp_record_t *rec = records->data; +	sdp_data_t *pdlist;  	bdaddr_t src, dst; +	uint32_t handle;  	DBG("path %s", path); -	memset(&hidp, 0, sizeof(hidp)); -  	adapter_get_address(adapter, &src);  	device_get_address(device, &dst); +	pdlist = sdp_data_get(rec, SDP_SERVER_RECORD_HANDLE); +	if (!pdlist) +		return -1; -	if (load_stored(&src, &dst, &hidp) == 0) -		goto done; - -	hidp.idle_to = idle_timeout * 60; - -	extract_hid_record(records->data, &hidp); - -done: -	store_device_info(&src, &dst, &hidp); - -	if (hidp.rd_data) -		g_free(hidp.rd_data); +	handle = pdlist->val.uint32;  	return input_device_register(connection, path, &src, &dst, -				HID_UUID, hidp.idle_to); +				HID_UUID, handle, idle_timeout * 60);  }  static void hid_device_remove(struct btd_device *device) diff --git a/input/storage.c b/input/storage.c deleted file mode 100644 index 680033ee..00000000 --- a/input/storage.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * - *  BlueZ - Bluetooth protocol stack for Linux - * - *  Copyright (C) 2004-2008  Marcel Holtmann <marcel@holtmann.org> - * - * - *  This program is free software; you can redistribute it and/or modify - *  it under the terms of the GNU General Public License as published by - *  the Free Software Foundation; either version 2 of the License, or - *  (at your option) any later version. - * - *  This program is distributed in the hope that it will be useful, - *  but WITHOUT ANY WARRANTY; without even the implied warranty of - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *  GNU General Public License for more details. - * - *  You should have received a copy of the GNU General Public License - *  along with this program; if not, write to the Free Software - *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#include <sys/stat.h> -#include <sys/ioctl.h> - -#include <bluetooth/bluetooth.h> -#include <bluetooth/hidp.h> -#include <bluetooth/hci.h> -#include <bluetooth/hci_lib.h> - -#include <glib.h> - -#include "logging.h" -#include "textfile.h" - -#include "storage.h" - -static inline int create_filename(char *buf, size_t size, -					bdaddr_t *bdaddr, const char *name) -{ -	char addr[18]; - -	ba2str(bdaddr, addr); - -	return create_name(buf, size, STORAGEDIR, addr, name); -} - -int parse_stored_device_info(const char *str, struct hidp_connadd_req *req) -{ -	char tmp[3]; -	const char *desc; -	unsigned int vendor, product, version, subclass, country, parser, pos; -	size_t len; -	int i; - -	sscanf(str, "%04X:%04X:%04X %02X %02X %04X %08X %n", -			&vendor, &product, &version, &subclass, &country, -			&parser, &req->flags, &pos); - -	desc  = &str[pos]; -	len = strlen(desc); -	if (len <= 0) -		return -ENOENT; - -	req->vendor   = vendor; -	req->product  = product; -	req->version  = version; -	req->subclass = subclass; -	req->country  = country; -	req->parser   = parser; - -	req->rd_size = len / 2; -	req->rd_data = g_try_malloc0(req->rd_size); -	if (!req->rd_data) { -		return -ENOMEM; -	} - -	memset(tmp, 0, sizeof(tmp)); -	for (i = 0; i < req->rd_size; i++) { -		memcpy(tmp, desc + (i * 2), 2); -		req->rd_data[i] = (uint8_t) strtol(tmp, NULL, 16); -	} - -	return 0; -} - -int get_stored_device_info(bdaddr_t *src, bdaddr_t *dst, -					struct hidp_connadd_req *req) -{ -	char filename[PATH_MAX + 1], *str; -	char peer[18]; -	int err; - -	create_filename(filename, PATH_MAX, src, "input"); - -	ba2str(dst, peer); -	str = textfile_get(filename, peer); -	if (!str) -		return -ENOENT; - -	err = parse_stored_device_info(str, req); - -	free(str); - -	return err; -} - -int del_stored_device_info(bdaddr_t *src, bdaddr_t *dst) -{ -	char filename[PATH_MAX + 1]; -	char addr[18]; - -	ba2str(dst, addr); - -	create_filename(filename, PATH_MAX, src, "hidd"); -	textfile_del(filename, addr); - -	create_filename(filename, PATH_MAX, src, "input"); -	return textfile_del(filename, addr); -} - -int store_device_info(bdaddr_t *src, bdaddr_t *dst, struct hidp_connadd_req *req) -{ -	char filename[PATH_MAX + 1], *str, *desc; -	int i, err, size; -	char addr[18]; - -	create_filename(filename, PATH_MAX, src, "input"); - -	size = 15 + 3 + 3 + 5 + (req->rd_size * 2) + 2 + 9; -	str = g_try_malloc0(size); -	if (!str) -		return -ENOMEM; - -	desc = g_try_malloc0((req->rd_size * 2) + 1); -	if (!desc) { -		g_free(str); -		return -ENOMEM; -	} - -	for (i = 0; i < req->rd_size; i++) -		sprintf(desc + (i * 2), "%2.2X", req->rd_data[i]); - -	snprintf(str, size - 1, "%04X:%04X:%04X %02X %02X %04X %08X %s", -			req->vendor, req->product, req->version, -			req->subclass, req->country, req->parser, -			req->flags, desc); - -	g_free(desc); - -	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - -	ba2str(dst, addr); - -	err = textfile_put(filename, addr, str); - -	g_free(str); - -	return err; -} - -int read_device_name(bdaddr_t *src, bdaddr_t *dst, char **name) -{ -	char filename[PATH_MAX + 1], addr[18], *str; -	int len; - -	create_filename(filename, PATH_MAX, src, "names"); - -	ba2str(dst, addr); -	str = textfile_get(filename, addr); -	if (!str) -		return -ENOENT; - -	len = strlen(str); - -	/* HID max name size is 128 chars */ -	if (len < 128) { -		*name = str; -		return 0; -	} - -	*name = g_try_malloc0(128); -	if (!*name) -		return -ENOMEM; - -	snprintf(*name, 128, "%s", str); - -	free(str); - -	return 0; -} - -int encrypt_link(bdaddr_t *src, bdaddr_t *dst) -{ -	char filename[PATH_MAX + 1]; -	struct hci_conn_info_req *cr; -	int dd, err, dev_id; -	char addr[18], *str; - -	create_filename(filename, PATH_MAX, src, "linkkeys"); - -	ba2str(dst, addr); - -	str = textfile_get(filename, addr); -	if (!str) { -		error("Encryption link key not found"); -		return -ENOKEY; -	} - -	free(str); - -	cr = g_try_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info)); -	if (!cr) -		return -ENOMEM; - -	ba2str(src, addr); - -	dev_id = hci_devid(addr); -	if (dev_id < 0) { -		g_free(cr); -		return -errno; -	} - -	dd = hci_open_dev(dev_id); -	if (dd < 0) { -		g_free(cr); -		return -errno; -	} - -	bacpy(&cr->bdaddr, dst); -	cr->type = ACL_LINK; - -	if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) -		goto fail; - -	if (cr->conn_info->link_mode & HCI_LM_ENCRYPT) { -		/* Already encrypted */ -		goto done; -	} - -	if (hci_authenticate_link(dd, htobs(cr->conn_info->handle), 1000) < 0) { -		error("Link authentication failed: %s (%d)", -						strerror(errno), errno); -		goto fail; -	} - -	if (hci_encrypt_link(dd, htobs(cr->conn_info->handle), 1, 1000) < 0) { -		error("Link encryption failed: %s (%d)", -						strerror(errno), errno); -		goto fail; -	} - -done: -	g_free(cr); - -	hci_close_dev(dd); - -	return 0; - -fail: -	g_free(cr); - -	err = errno; -	hci_close_dev(dd); - -	return -err; -} diff --git a/input/storage.h b/input/storage.h deleted file mode 100644 index 0d1f2d6f..00000000 --- a/input/storage.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * - *  BlueZ - Bluetooth protocol stack for Linux - * - *  Copyright (C) 2004-2008  Marcel Holtmann <marcel@holtmann.org> - * - * - *  This program is free software; you can redistribute it and/or modify - *  it under the terms of the GNU General Public License as published by - *  the Free Software Foundation; either version 2 of the License, or - *  (at your option) any later version. - * - *  This program is distributed in the hope that it will be useful, - *  but WITHOUT ANY WARRANTY; without even the implied warranty of - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *  GNU General Public License for more details. - * - *  You should have received a copy of the GNU General Public License - *  along with this program; if not, write to the Free Software - *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA - * - */ - -int get_stored_device_info(bdaddr_t *src, bdaddr_t *dst, -				struct hidp_connadd_req *req); - -int del_stored_device_info(bdaddr_t *src, bdaddr_t *dst); - -int store_device_info(bdaddr_t *src, bdaddr_t *dst, -				struct hidp_connadd_req *req); - -int parse_stored_device_info(const char *str, -				struct hidp_connadd_req *req); - -int read_device_name(bdaddr_t *src, bdaddr_t *dst, char **name); - -int encrypt_link(bdaddr_t *src, bdaddr_t *dst);  | 
