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); |