diff --git a/conf/blued.conf.example b/conf/blued.conf.example index 48c8c3e57f34fbb82fedbbbe40ec210629dc7652..d023bc51ea7e2ef12af51509093d1473e0b2815f 100644 --- a/conf/blued.conf.example +++ b/conf/blued.conf.example @@ -31,9 +31,9 @@ # # Name of the netgraph HCI node. Unless you have several bluetooth # chips, you should not have to change this. -# Default: hci0ubt +# Default: ubt0hci # -#hci_node = "hci0ubt"; +#hci_node = "ubt0hci"; # # User to drop to after initialisation is done. diff --git a/daemon/src/blue_daemon.cpp b/daemon/src/blue_daemon.cpp index 221b38e4325d226cb54d6494d07c5dc4c3ebe77f..3db1021feaf435ac3ac5b60c6723d746b26daa57 100644 --- a/daemon/src/blue_daemon.cpp +++ b/daemon/src/blue_daemon.cpp @@ -108,7 +108,7 @@ static pidfh *create_pid_file(const conf_options &opts) return tmp; } -blue_daemon::blue_daemon(nodeinfo btnode, const conf_options &opts, +blue_daemon::blue_daemon(const conf_options &opts, blue::util::shared_cap_chan chan, ev::loop_ref loop) : loop(loop), rpc_watcher(loop), @@ -121,10 +121,13 @@ blue_daemon::blue_daemon(nodeinfo btnode, const conf_options &opts, { connect_socket(opts); - hci_socket.bind(btnode.name); - hci_socket.connect(btnode.name); + hci_socket.bind(opts.hci_node); + hci_socket.connect(opts.hci_node); hci_socket.register_socket_observer(this); + syslog(LOG_DEBUG, "Local HCI address: %s", + get_local_address().str().c_str()); + try { devices = db.load_devices(&hci_socket); @@ -377,6 +380,11 @@ bool blue_daemon::known(blue::bdaddr addr) const return devices.count(addr) > 0; } +blue::bdaddr blue_daemon::get_local_address() const +{ + return hci_socket.get_address(); +} + blue::rpc_op blue_daemon::pair_request(const blue::bdaddr &addr) { blue::rpc_op ret; diff --git a/daemon/src/blue_daemon.h b/daemon/src/blue_daemon.h index 9cf62dc151b58f6a680a35a15843cf35e23fbd3c..53ed35042010f8c0d9d13d58455591a46dee45d7 100644 --- a/daemon/src/blue_daemon.h +++ b/daemon/src/blue_daemon.h @@ -30,7 +30,7 @@ class blue_daemon : public blue::hci_socket_observer, public blue::device_observer, public rpc_observer { public: - blue_daemon(nodeinfo btnode, const conf_options &opts, + blue_daemon(const conf_options &opts, blue::util::shared_cap_chan chan, ev::loop_ref loop); virtual ~blue_daemon(); @@ -68,6 +68,13 @@ public: */ bool known(blue::bdaddr addr) const; + /* + * Returns the local HCI socket address. + * + * throws std::runtime_error() on error. + */ + blue::bdaddr get_local_address() const; + private: /* * Callbacks from blue::btdevice, see lib/include/btdevice.h class diff --git a/daemon/src/hid_daemon.cpp b/daemon/src/hid_daemon.cpp index 99d278c398ad7f3ac664746e37302784c1ed2473..b4210ba0f12d164f4a8936e99f4b63d3d091a5c3 100644 --- a/daemon/src/hid_daemon.cpp +++ b/daemon/src/hid_daemon.cpp @@ -61,7 +61,7 @@ void hid_daemon::connect(blue::bdaddr addr) try { std::optional<blue::hid::hid_descriptor> d = - blue::hid::get_descriptor(sdp_chan, addr); + blue::hid::get_descriptor(sdp_chan, hci->get_local_address(), addr); if (!d) { syslog(LOG_DEBUG, "No HID descriptor could be queried for %s", @@ -70,7 +70,8 @@ void hid_daemon::connect(blue::bdaddr addr) } unique_fd ctrl_fd = - cap_l2cap_connect(l2cap_chan, d->control_psm, *bdaddr); + cap_l2cap_connect(l2cap_chan, hci->get_local_address(), + d->control_psm, bdaddr); if (ctrl_fd == -1) { syslog(LOG_ERR, "Failed to open control connection to %s: %s", @@ -79,7 +80,8 @@ void hid_daemon::connect(blue::bdaddr addr) } unique_fd intr_fd = - cap_l2cap_connect(l2cap_chan, d->interrupt_psm, *bdaddr); + cap_l2cap_connect(l2cap_chan, hci->get_local_address(), + d->interrupt_psm, bdaddr); if (intr_fd == -1) { syslog(LOG_ERR, "Failed to open interrupt connection to %s: %s", @@ -87,9 +89,19 @@ void hid_daemon::connect(blue::bdaddr addr) return; } - devices.try_emplace(addr, kbd_chan, sdp_chan, this, cons, uinput, - addr, std::move(ctrl_fd), loop, - std::move(d.value())); + blue::hid::hid_device::hid_device_config config = + { + kbd_chan, + sdp_chan, + this, + cons, + uinput, + hci->get_local_address(), + addr, + std::move(ctrl_fd), + loop + }; + devices.try_emplace(addr, std::move(config), std::move(d.value())); devices.at(addr).intr_opened(std::move(intr_fd)); } catch (const std::runtime_error &e) @@ -122,8 +134,33 @@ void hid_daemon::ctrl_callback(unique_fd client_fd, blue::bdaddr remote) try { if (hci->paired(remote)) - devices.try_emplace(remote, kbd_chan, sdp_chan, this, cons, - uinput, remote, std::move(client_fd), loop); + { + std::optional<blue::hid::hid_descriptor> d = + blue::hid::get_descriptor(sdp_chan, hci->get_local_address(), + remote); + if (d) + { + blue::hid::hid_device::hid_device_config config = + { + kbd_chan, + sdp_chan, + this, + cons, + uinput, + hci->get_local_address(), + remote, + std::move(client_fd), + loop + }; + devices.try_emplace(remote, std::move(config), std::move(d.value())); + } + else + { + syslog(LOG_DEBUG, "No HID descriptor could be queried for incoming %s", + remote.str().c_str()); + return; + } + } else { syslog(LOG_NOTICE, "%s is not paired. Closing connection!", diff --git a/daemon/src/main.cpp b/daemon/src/main.cpp index 09b42e98250174fe8d5a9b2d07b3f2356ee0fa24..1c88fdd662d807e683d9701ae64f54735e053515 100644 --- a/daemon/src/main.cpp +++ b/daemon/src/main.cpp @@ -37,21 +37,6 @@ private: ev::loop_ref loop; }; -static nodeinfo get_node(const conf_options &opts) -{ - std::vector<nodeinfo> nodes; - - ev::default_loop loop; - blue::hci_socket qs(loop); - qs.bind(opts.hci_node); - nodes = qs.find_hci_nodes(); - - if (nodes.empty()) - throw std::runtime_error("Could not find any BT nodes."); - - return nodes[0]; -} - static uid_t get_uid(std::string user) { passwd *p = getpwnam(user.c_str()); @@ -83,7 +68,7 @@ static conf_options parse_config(std::string path) opts.socket_name = obj.lookup("socket_name").string_value("rpc"); opts.db_path = obj.lookup("db_path").string_value("/var/db/blued.db"); - opts.hci_node = obj.lookup("hci_node").string_value("hci0ubt"); + opts.hci_node = obj.lookup("hci_node").string_value("ubt0hci"); try { @@ -208,7 +193,6 @@ int main(int argc, char* argv[]) try { - nodeinfo n = get_node(opts); ev::default_loop loop; sig_handler int_handler(loop); ev::sig s_int(loop); @@ -223,7 +207,7 @@ int main(int argc, char* argv[]) s_term.set(SIGTERM); s_term.start(); - blue_daemon daemon(n, opts, channel, loop); + blue_daemon daemon(opts, channel, loop); drop_privileges(opts); diff --git a/lib/include/btdevice.h b/lib/include/btdevice.h index 9781d58d0148185248f911dda723921c3d14d6ab..1403065463c475bd3c5be819975fa07c81d4cf37 100644 --- a/lib/include/btdevice.h +++ b/lib/include/btdevice.h @@ -72,8 +72,8 @@ protected: * Ex: Connect to a device with address addr * * blue::hci_socket s; - * s.bind("hci0ubt"); - * hci_socket.connect("hci0ubt"); + * s.bind("ubt0hci"); + * hci_socket.connect("ubt0hci"); * blue::btdevice device(addr, &s); * device.connect(); * diff --git a/lib/include/cap_l2cap.h b/lib/include/cap_l2cap.h index 3b6b6a49ca8efa44badc4b7a8e59be2d594f6798..9c57c27bd3c09b556322b161e87af137092c20d0 100644 --- a/lib/include/cap_l2cap.h +++ b/lib/include/cap_l2cap.h @@ -27,7 +27,9 @@ namespace blue::l2cap * * returns -1 on error */ - util::unique_fd cap_l2cap_listen(util::shared_cap_chan chan, uint16_t psm); + util::unique_fd cap_l2cap_listen(util::shared_cap_chan chan, + const bdaddr_t *listen_addr, + uint16_t psm); /* * Returns an fd to an L2CAP socket connected to remote addr @@ -37,8 +39,10 @@ namespace blue::l2cap * * returns -1 on error */ - util::unique_fd cap_l2cap_connect(util::shared_cap_chan chan, uint16_t psm, - bdaddr_t addr); + util::unique_fd cap_l2cap_connect(util::shared_cap_chan chan, + const bdaddr_t *local_addr, + uint16_t psm, + const bdaddr_t *addr); } // namespace blue::l2cap diff --git a/lib/include/cap_sdp.h b/lib/include/cap_sdp.h index 53a7fe59dbe6f3ebbfa3713d339df4fde5b13272..69191d5a5d01fafd8a65a6fc9c7408d5de12c459 100644 --- a/lib/include/cap_sdp.h +++ b/lib/include/cap_sdp.h @@ -28,7 +28,8 @@ namespace blue::sdp }; /* - * Opens a SDP session to remote device with address r. + * Opens a SDP session to remote device with address r from local + * address l. * * handle is an output parameter that gives an opaque handle for * passing to cap_sdp_search(). It should be freed by @@ -39,8 +40,8 @@ namespace blue::sdp * * returns -1 on error, 0 on success */ - int cap_sdp_open(util::shared_cap_chan chan, const bdaddr_t *r, - uint64_t &handle); + int cap_sdp_open(util::shared_cap_chan chan, const bdaddr_t *l, + const bdaddr_t *r, uint64_t &handle); /* * Queries the device represented by handle acquired from diff --git a/lib/include/hci_socket.h b/lib/include/hci_socket.h index 2a670d86ee58a017cd7c66675e10dd9c1f41b2bb..3f0b1db23131753536e7cc2497e1164cc43fe710 100644 --- a/lib/include/hci_socket.h +++ b/lib/include/hci_socket.h @@ -200,8 +200,8 @@ protected: * blue::hci_socket s(loop); * observer o; * - * s.bind("hci0ubt"); - * s.connect("hci0ubt"); + * s.bind("ubt0hci"); + * s.connect("ubt0hci"); * s.register_socket_observer(&observer); * s.query_devices(); * @@ -271,6 +271,12 @@ public: * throws std::runtime_error() on error */ std::vector<nodeinfo> find_hci_nodes(); + /* + * Get the bdaddr of the HCI socket. + * + * throws std::runtime_error() on error. + */ + blue::bdaddr get_address() const; /* * Send an HCI request out on the network. diff --git a/lib/include/hid/bthid.h b/lib/include/hid/bthid.h index dba85acdf5938c7566c56ab49cf7ebee92ee4e08..ea9e495b5c717aeda8f26bf4b289acdf17be801f 100644 --- a/lib/include/hid/bthid.h +++ b/lib/include/hid/bthid.h @@ -53,7 +53,8 @@ namespace blue::hid /* * Request a Bluetooth HID descriptor from the remote device with - * address addr. + * address addr. The request is sent from local device with + * address local_addr. * * sdp_chan is a channel to blue.sdp opened using * cap_service_open() @@ -63,7 +64,7 @@ namespace blue::hid * If the device is not a HID device, the return value is empty. */ std::optional<hid_descriptor> get_descriptor(util::shared_cap_chan sdp_chan, - blue::bdaddr addr); + blue::bdaddr local_addr, blue::bdaddr addr); // Mandatory device ID fields as per the Bluetooth DeviceID_SPEC V13. constexpr uint16_t SpecificationID = 0x0200; @@ -85,7 +86,8 @@ namespace blue::hid /* * Request a Bluetooth device ID descriptor from the remote device - * with address addr. + * with address addr. The request is made from local HCI device + * with address local_addr. * * sdp_chan is a channel to blue.sdp opened using * cap_service_open() @@ -96,7 +98,7 @@ namespace blue::hid * empty. */ std::optional<device_id> get_devid(util::shared_cap_chan sdp_chan, - blue::bdaddr addr); + blue::bdaddr local_addr, blue::bdaddr addr); } // namespace blue::bthid diff --git a/lib/include/hid/hid_device.h b/lib/include/hid/hid_device.h index 9681f8d67ef8e44ce8682c020d579415d316ae94..3ab9524461f060905793846d65de69ba86aa49d7 100644 --- a/lib/include/hid/hid_device.h +++ b/lib/include/hid/hid_device.h @@ -59,34 +59,37 @@ public: * If the hid_device object is destroyed, the l2cap connection to * the HID device will be closed. * - * Arguments: - * kbd_chan - service channel to blue.kbd - * sdp_chan - service channel to blue.sdp - * parent - pointer to parent inheriting hid_watcher - * cons_fd - fd pointing to /dev/consolectl - * uinput - true if events should be passed to X via uinput - * addr - bluetooth address of the HID device - * ctrl - fd pointing to a l2cap control connection - * loop - libev event loop for IO processing - * - * optional: - * d - HID descriptor for the device, it will be queried - * if it is not supplied + * Config: + * kbd_chan - service channel to blue.kbd + * sdp_chan - service channel to blue.sdp + * parent - pointer to parent inheriting hid_watcher + * cons_fd - fd pointing to /dev/consolectl + * uinput - true if events should be passed to X via uinput + * addr - bluetooth address of the HID device + * ctrl - fd pointing to a l2cap control connection + * loop - libev event loop for IO processing + * d - HID descriptor for the device * * throws std::runtime_error() on error */ - hid_device(util::shared_cap_chan kbd_chan, util::shared_cap_chan sdp_chan, - hid_watcher *parent, int cons_fd, bool uinput, - blue::bdaddr addr, util::unique_fd ctrl, ev::loop_ref loop); - hid_device(util::shared_cap_chan kbd_chan, util::shared_cap_chan sdp_chan, - hid_watcher *parent, int cons_fd, bool uinput, - blue::bdaddr addr, util::unique_fd ctrl, ev::loop_ref loop, - blue::hid::hid_descriptor &&d); + struct hid_device_config + { + util::shared_cap_chan kbd_chan; + util::shared_cap_chan sdp_chan; + hid_watcher *parent; + int cons_fd; + bool uinput; + blue::bdaddr local_addr; + blue::bdaddr addr; + util::unique_fd ctrl; + ev::loop_ref loop; + }; + hid_device(hid_device_config &&config, blue::hid::hid_descriptor &&d); ~hid_device(); /* - * intr_opened() takes an fd pointing to an interrupt channel for - * the device. + * intr_opened() takes an kbd capability and an fd pointing to an + * interrupt channel for the device. * * The device will not be functional until the interrupt channel * has been opened. @@ -103,7 +106,8 @@ private: hid_device& operator=(hid_device &&) = delete; void init_state(); - void populate_devid(); + void populate_devid(util::shared_cap_chan sdp_chan, + blue::bdaddr local_addr); void populate_default_devid(); const blue::bdaddr &get_addr() const; @@ -132,8 +136,6 @@ private: void ctrl_callback(ev::io &watcher, int events); void intr_callback(ev::io &watcher, int events); - - util::shared_cap_chan sdp_chan; util::shared_cap_chan kbd_chan; blue::bdaddr addr; diff --git a/lib/src/cap_l2cap.cpp b/lib/src/cap_l2cap.cpp index eeb6bcc5bfaf089b9c3b888f5f33e8db93c1fb24..acc2286c6b1bd584aecdcd728c790bf2e2a408b4 100644 --- a/lib/src/cap_l2cap.cpp +++ b/lib/src/cap_l2cap.cpp @@ -17,7 +17,7 @@ extern "C" namespace blue::l2cap { -static sockaddr_l2cap create_addr(uint16_t psm, const bdaddr_t *bd_addr) +static sockaddr_l2cap create_addr(const bdaddr_t *bd_addr, uint16_t psm) { sockaddr_l2cap addr{}; @@ -31,10 +31,10 @@ static sockaddr_l2cap create_addr(uint16_t psm, const bdaddr_t *bd_addr) return addr; } -static int bind_socket(uint16_t psm) +static int bind_socket(const bdaddr_t *local_addr, uint16_t psm) { - sockaddr_l2cap addr = create_addr(psm, NG_HCI_BDADDR_ANY); + sockaddr_l2cap addr = create_addr(local_addr, psm); int fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BLUETOOTH_PROTO_L2CAP); if (fd == -1) @@ -50,11 +50,13 @@ static int bind_socket(uint16_t psm) return fd; } -util::unique_fd cap_l2cap_listen(util::shared_cap_chan chan, uint16_t psm) +util::unique_fd cap_l2cap_listen(util::shared_cap_chan chan, const bdaddr_t *listen_addr, + uint16_t psm) { nvlist_t *nvl = nvlist_create(0); nvlist_add_string(nvl, "cmd", "l2cap_listen"); + nvlist_add_binary(nvl, "listenaddr", listen_addr, sizeof(bdaddr_t)); nvlist_add_number(nvl, "psm", psm); nvl = cap_xfer_nvlist(chan.get(), nvl); @@ -82,8 +84,19 @@ static int impl_l2cap_listen(const nvlist_t *limits, { int fd = -1; uint16_t psm = static_cast<uint16_t>(nvlist_get_number(nvlin, "psm")); + size_t addr_size; + bdaddr_t listen_addr; + + const void *l = nvlist_get_binary(nvlin, "listenaddr", &addr_size); - if ((fd = bind_socket(psm)) == -1) + if (sizeof(bdaddr_t) != addr_size) + return EINVAL; + + std::copy(reinterpret_cast<const bdaddr_t *>(l), + reinterpret_cast<const bdaddr_t *>(l) + 1, + &listen_addr); + + if ((fd = bind_socket(&listen_addr, psm)) == -1) return errno; if (listen(fd, 128) == -1) @@ -99,14 +112,16 @@ static int impl_l2cap_listen(const nvlist_t *limits, return 0; } -util::unique_fd cap_l2cap_connect(util::shared_cap_chan chan, uint16_t psm, - bdaddr_t addr) +util::unique_fd cap_l2cap_connect(util::shared_cap_chan chan, + const bdaddr_t *local_addr, uint16_t psm, + const bdaddr_t *addr) { nvlist_t *nvl = nvlist_create(0); nvlist_add_string(nvl, "cmd", "l2cap_connect"); + nvlist_add_binary(nvl, "localaddr", local_addr, sizeof(bdaddr_t)); nvlist_add_number(nvl, "psm", psm); - nvlist_add_binary(nvl, "addr", &addr, sizeof(addr)); + nvlist_add_binary(nvl, "addr", addr, sizeof(bdaddr_t)); nvl = cap_xfer_nvlist(chan.get(), nvl); if (nvl == nullptr) @@ -134,17 +149,31 @@ static int impl_l2cap_connect(const nvlist_t *limits, int fd = -1; size_t addr_size; uint16_t psm = static_cast<uint16_t>(nvlist_get_number(nvlin, "psm")); - const bdaddr_t *addr = - reinterpret_cast<const bdaddr_t *>( - nvlist_get_binary(nvlin, "addr", &addr_size)); + bdaddr_t addr; + bdaddr_t local_addr; + + const void *l = nvlist_get_binary(nvlin, "localaddr", &addr_size); if (sizeof(bdaddr_t) != addr_size) return EINVAL; - if ((fd = bind_socket(0)) == -1) + std::copy(reinterpret_cast<const bdaddr_t *>(l), + reinterpret_cast<const bdaddr_t *>(l) + 1, + &local_addr); + + const void *a = nvlist_get_binary(nvlin, "addr", &addr_size); + + if (sizeof(bdaddr_t) != addr_size) + return EINVAL; + + std::copy(reinterpret_cast<const bdaddr_t *>(a), + reinterpret_cast<const bdaddr_t *>(a) + 1, + &addr); + + if ((fd = bind_socket(&local_addr, 0)) == -1) return errno; - sockaddr_l2cap sa = create_addr(psm, addr); + sockaddr_l2cap sa = create_addr(&addr, psm); const sockaddr *sp = reinterpret_cast<const sockaddr *>(&sa); if (connect(fd, sp, sizeof(sa)) == -1) { diff --git a/lib/src/cap_sdp.cpp b/lib/src/cap_sdp.cpp index aa084bf3c09fadc6883d4ab1b8bcbe046412c254..209042ea84403cced2bf9bfbf53b0d275f8bda25 100644 --- a/lib/src/cap_sdp.cpp +++ b/lib/src/cap_sdp.cpp @@ -33,12 +33,13 @@ sdp_attr::operator sdp_attr_t() return ret; } -int cap_sdp_open(util::shared_cap_chan chan, const bdaddr_t *r, - uint64_t &handle) +int cap_sdp_open(util::shared_cap_chan chan, const bdaddr_t *l, + const bdaddr_t *r, uint64_t &handle) { nvlist_t *nvl = nvlist_create(0); nvlist_add_string(nvl, "cmd", "sdp_open"); + nvlist_add_binary(nvl, "localaddr", l, sizeof(bdaddr_t)); nvlist_add_binary(nvl, "remoteaddr", r, sizeof(bdaddr_t)); nvl = cap_xfer_nvlist(chan.get(), nvl); @@ -63,8 +64,18 @@ static int impl_sdp_open(const nvlist_t *limits, nvlist_t *nvlin, nvlist_t *nvlout) { size_t addr_size; + bdaddr_t local; bdaddr_t remote; + const void *l = nvlist_get_binary(nvlin, "localaddr", &addr_size); + + if (sizeof(bdaddr_t) != addr_size) + return EINVAL; + + std::copy(reinterpret_cast<const bdaddr_t *>(l), + reinterpret_cast<const bdaddr_t *>(l) + 1, + &local); + const void *r = nvlist_get_binary(nvlin, "remoteaddr", &addr_size); if (sizeof(bdaddr_t) != addr_size) @@ -74,7 +85,7 @@ static int impl_sdp_open(const nvlist_t *limits, nvlist_t *nvlin, reinterpret_cast<const bdaddr_t *>(r) + 1, &remote); - void *h = sdp_open(NG_HCI_BDADDR_ANY, &remote); + void *h = sdp_open(&local, &remote); if (!h) return ENOMEM; diff --git a/lib/src/hci_socket.cpp b/lib/src/hci_socket.cpp index 64efafff72e402bef0a09b1509420602540301af..fb852d4e68400e64b66cc6a0715aca2a46e368b7 100644 --- a/lib/src/hci_socket.cpp +++ b/lib/src/hci_socket.cpp @@ -88,8 +88,9 @@ void hci_socket::bind(const std::string &node) addr.hci_family = AF_BLUETOOTH; strncpy(addr.hci_node, node.c_str(), sizeof(addr.hci_node)); if (::bind(fd, reinterpret_cast<sockaddr *>(&addr), sizeof(addr)) < 0) - throw std::runtime_error("Could not bind HCI socket: " + + throw std::runtime_error("Could not bind HCI socket " + node + ": " + std::string(strerror(errno))); + syslog(LOG_DEBUG, "Bound HCI node: %s", addr.hci_node); } void hci_socket::connect(const std::string &node) @@ -122,6 +123,16 @@ std::vector<nodeinfo> hci_socket::find_hci_nodes() return nodes; } +bdaddr hci_socket::get_address() const +{ + ng_btsocket_hci_raw_node_bdaddr addr; + if (ioctl(fd, SIOC_HCI_RAW_NODE_GET_BDADDR, &addr, sizeof(addr)) < 0) + throw std::runtime_error("Could not get HCI address: " + + std::string(strerror(errno))); + + return addr.bdaddr; +} + void hci_socket::set_event_filter(const std::vector<int> &filters) { ng_btsocket_hci_raw_filter filter{}; diff --git a/lib/src/hid/bthid.cpp b/lib/src/hid/bthid.cpp index 9456671d2684423dafd6e9a8e005bef81469a3ac..146b92aee5b330577034b871b54ad37f90a04953 100644 --- a/lib/src/hid/bthid.cpp +++ b/lib/src/hid/bthid.cpp @@ -263,12 +263,12 @@ hid_descriptor &hid_descriptor::operator=(hid_descriptor &&other) } std::optional<hid_descriptor> get_descriptor(util::shared_cap_chan sdp_chan, - blue::bdaddr addr) + blue::bdaddr local_addr, blue::bdaddr addr) { hid_descriptor ret; uint64_t handle; - if (blue::sdp::cap_sdp_open(sdp_chan, addr, handle) == -1) + if (blue::sdp::cap_sdp_open(sdp_chan, local_addr, addr, handle) == -1) throw std::runtime_error("Could not open SDP connection."); /* @@ -357,12 +357,12 @@ std::optional<hid_descriptor> get_descriptor(util::shared_cap_chan sdp_chan, } std::optional<device_id> get_devid(util::shared_cap_chan sdp_chan, - blue::bdaddr addr) + blue::bdaddr local_addr, blue::bdaddr addr) { device_id ret; uint64_t handle; - if (blue::sdp::cap_sdp_open(sdp_chan, addr, handle) == -1) + if (blue::sdp::cap_sdp_open(sdp_chan, local_addr, addr, handle) == -1) throw std::runtime_error("Could not open SDP connection."); std::vector<uint16_t> pp = diff --git a/lib/src/hid/hid_device.cpp b/lib/src/hid/hid_device.cpp index c5b5fb4fe4d60651da13bb0754d91fa294b04b75..3a069309757722eb827dc46808023dfae5c80b54 100644 --- a/lib/src/hid/hid_device.cpp +++ b/lib/src/hid/hid_device.cpp @@ -10,53 +10,19 @@ namespace blue::hid { -hid_device::hid_device(util::shared_cap_chan kbd_chan, - util::shared_cap_chan sdp_chan, hid_watcher *parent, - int cons_fd, bool uinput, blue::bdaddr addr, - util::unique_fd ctrl_in, ev::loop_ref loop) : - sdp_chan(sdp_chan), - kbd_chan(kbd_chan), - addr(addr), - ctrl(std::move(ctrl_in)), - ctrl_watcher(loop), - intr_watcher(loop), - parent(parent), - cons_fd(cons_fd), - uinput(uinput) -{ - - std::optional<blue::hid::hid_descriptor> d = - blue::hid::get_descriptor(sdp_chan, addr); - if (!d) - throw std::runtime_error("Could not query device HID descriptor"); - desc = std::move(d.value()); - - init_state(); - populate_devid(); - - ctrl_watcher.set<hid_device, &hid_device::ctrl_callback>(this); - ctrl_watcher.set(ctrl, ev::READ); - ctrl_watcher.start(); -} - -hid_device::hid_device(util::shared_cap_chan kbd_chan, - util::shared_cap_chan sdp_chan, hid_watcher *parent, - int cons_fd, bool uinput, blue::bdaddr addr, - util::unique_fd ctrl_in, ev::loop_ref loop, - blue::hid::hid_descriptor &&d) : - sdp_chan(sdp_chan), - kbd_chan(kbd_chan), - addr(addr), +hid_device::hid_device(hid_device_config &&config, blue::hid::hid_descriptor &&d) : + kbd_chan(config.kbd_chan), + addr(config.addr), desc(std::move(d)), - ctrl(std::move(ctrl_in)), - ctrl_watcher(loop), - intr_watcher(loop), - parent(parent), - cons_fd(cons_fd), - uinput(uinput) + ctrl(std::move(config.ctrl)), + ctrl_watcher(config.loop), + intr_watcher(config.loop), + parent(config.parent), + cons_fd(config.cons_fd), + uinput(config.uinput) { init_state(); - populate_devid(); + populate_devid(config.sdp_chan, config.local_addr); ctrl_watcher.set<hid_device, &hid_device::ctrl_callback>(this); ctrl_watcher.set(ctrl, ev::READ); @@ -82,12 +48,13 @@ void hid_device::init_state() } } -void hid_device::populate_devid() +void hid_device::populate_devid(util::shared_cap_chan sdp_chan, + blue::bdaddr local_addr) { try { std::optional<blue::hid::device_id> devid = - blue::hid::get_devid(sdp_chan, addr); + blue::hid::get_devid(sdp_chan, local_addr, addr); if (devid) { vendor_id = devid->vendor_id; diff --git a/lib/src/l2cap_socket.cpp b/lib/src/l2cap_socket.cpp index 555ce9c59ab13784625ac8456e3ffaa79cb7e893..79ff6a25918a470e3722776739f3f61f6176a0ff 100644 --- a/lib/src/l2cap_socket.cpp +++ b/lib/src/l2cap_socket.cpp @@ -19,7 +19,7 @@ namespace blue::l2cap l2cap_listen_socket::l2cap_listen_socket(util::shared_cap_chan chan, ev::loop_ref loop, l2cap_listen_observer *parent, uint16_t psm) : parent(parent), - fd(blue::l2cap::cap_l2cap_listen(chan, psm)), + fd(blue::l2cap::cap_l2cap_listen(chan, NG_HCI_BDADDR_ANY, psm)), l2cap_watcher(loop) { if (fd == -1)