summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2005-11-14 12:18:09 +0000
committerMarcel Holtmann <marcel@holtmann.org>2005-11-14 12:18:09 +0000
commit3e9d510274d6560e026c76dc3ecf415db0dd7e68 (patch)
tree79556a17a276df18b7b7e4909fdcb3ea9d556c88
parent9c4ddbfafab6fe96480edeb8c5fee1b76e103300 (diff)
Add initial fake HID support
-rw-r--r--hidd/Makefile.am2
-rw-r--r--hidd/fakehid.c49
-rw-r--r--hidd/hidd.h4
-rw-r--r--hidd/main.c52
-rw-r--r--hidd/sdp.c19
5 files changed, 118 insertions, 8 deletions
diff --git a/hidd/Makefile.am b/hidd/Makefile.am
index 4dfbb56e..cc043457 100644
--- a/hidd/Makefile.am
+++ b/hidd/Makefile.am
@@ -1,7 +1,7 @@
bin_PROGRAMS = hidd
-hidd_SOURCES = main.c hidd.h sdp.c
+hidd_SOURCES = main.c hidd.h sdp.c fakehid.c
hidd_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a
AM_CFLAGS = @BLUEZ_CFLAGS@
diff --git a/hidd/fakehid.c b/hidd/fakehid.c
new file mode 100644
index 00000000..1483f022
--- /dev/null
+++ b/hidd/fakehid.c
@@ -0,0 +1,49 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2003-2005 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 <sys/socket.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/rfcomm.h>
+#include <bluetooth/hidp.h>
+
+#include "hidd.h"
+
+#include <X11/Xlib.h>
+#include <X11/extensions/XTest.h>
+
+#include <math.h>
+
+void epox_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel)
+{
+}
+
+void headset_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel)
+{
+}
diff --git a/hidd/hidd.h b/hidd/hidd.h
index c8103281..ca9712aa 100644
--- a/hidd/hidd.h
+++ b/hidd/hidd.h
@@ -26,3 +26,7 @@
int get_stored_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_connadd_req *req);
int get_sdp_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_connadd_req *req);
+int get_alternate_device_info(const bdaddr_t *src, const bdaddr_t *dst, uint16_t *uuid, uint8_t *channel);
+
+void epox_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel);
+void headset_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel);
diff --git a/hidd/main.c b/hidd/main.c
index be50bf7a..ebb9b745 100644
--- a/hidd/main.c
+++ b/hidd/main.c
@@ -406,19 +406,42 @@ static void do_show(int ctl)
}
}
-static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, uint8_t subclass, int nosdp, int encrypt, int timeout)
+static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, uint8_t subclass, int fakehid, int encrypt, int timeout)
{
struct hidp_connadd_req req;
+ uint16_t uuid = HID_SVCLASS_ID;
+ uint8_t channel = 0;
int csk, isk, err;
memset(&req, 0, sizeof(req));
- if (get_sdp_device_info(src, dst, &req) < 0) {
+ err = get_sdp_device_info(src, dst, &req);
+ if (err < 0 && fakehid)
+ err = get_alternate_device_info(src, dst, &uuid, &channel);
+
+ if (err < 0) {
perror("Can't get device information");
close(ctl);
exit(1);
}
+ switch (uuid) {
+ case HID_SVCLASS_ID:
+ goto connect;
+
+ case SERIAL_PORT_SVCLASS_ID:
+ epox_presenter(src, dst, channel);
+ break;
+
+ case HEADSET_SVCLASS_ID:
+ case HANDSFREE_SVCLASS_ID:
+ headset_presenter(src, dst, channel);
+ break;
+ }
+
+ return;
+
+connect:
csk = l2cap_connect(src, dst, L2CAP_PSM_HIDP_CTRL);
if (csk < 0) {
perror("Can't create HID control channel");
@@ -446,7 +469,7 @@ static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, uint8_t subclass,
}
}
-static void do_search(int ctl, bdaddr_t *bdaddr, uint8_t subclass, int nosdp, int encrypt, int timeout)
+static void do_search(int ctl, bdaddr_t *bdaddr, uint8_t subclass, int fakehid, int encrypt, int timeout)
{
inquiry_info *info = NULL;
bdaddr_t src, dst;
@@ -477,10 +500,25 @@ static void do_search(int ctl, bdaddr_t *bdaddr, uint8_t subclass, int nosdp, in
ba2str(&dst, addr);
printf("\tConnecting to device %s\n", addr);
- do_connect(ctl, &src, &dst, subclass, nosdp, encrypt, timeout);
+ do_connect(ctl, &src, &dst, subclass, fakehid, encrypt, timeout);
+ }
+ }
+
+ if (!fakehid)
+ goto done;
+
+ for (i = 0; i < num_rsp; i++) {
+ memcpy(class, (info+i)->dev_class, 3);
+ if (class[0] == 0x00 && class[1] == 0x40 && class[2] == 0x00) {
+ bacpy(&dst, &(info+i)->bdaddr);
+ ba2str(&dst, addr);
+
+ printf("\tConnecting to device %s\n", addr);
+ do_connect(ctl, &src, &dst, subclass, 1, 0, timeout);
}
}
+done:
bt_free(info);
if (!num_rsp) {
@@ -591,7 +629,7 @@ int main(int argc, char *argv[])
char addr[18];
int log_option = LOG_NDELAY | LOG_PID;
int opt, fd, ctl, csk, isk;
- int mode = SHOW, daemon = 1, nosdp = 0, encrypt = 0, timeout = 30, lm = 0;
+ int mode = SHOW, daemon = 1, nosdp = 0, fakehid = 1, encrypt = 0, timeout = 30, lm = 0;
bacpy(&bdaddr, BDADDR_ANY);
@@ -685,12 +723,12 @@ int main(int argc, char *argv[])
break;
case SEARCH:
- do_search(ctl, &bdaddr, subclass, nosdp, encrypt, timeout);
+ do_search(ctl, &bdaddr, subclass, fakehid, encrypt, timeout);
close(ctl);
exit(0);
case CONNECT:
- do_connect(ctl, &bdaddr, &dev, subclass, nosdp, encrypt, timeout);
+ do_connect(ctl, &bdaddr, &dev, subclass, fakehid, encrypt, timeout);
close(ctl);
exit(0);
diff --git a/hidd/sdp.c b/hidd/sdp.c
index 6ed5d2dc..285438e8 100644
--- a/hidd/sdp.c
+++ b/hidd/sdp.c
@@ -267,3 +267,22 @@ int get_sdp_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_co
return 0;
}
+
+int get_alternate_device_info(const bdaddr_t *src, const bdaddr_t *dst, uint16_t *uuid, uint8_t *channel)
+{
+ sdp_session_t *s;
+
+ s = sdp_connect(src, dst, SDP_RETRY_IF_BUSY | SDP_WAIT_ON_CLOSE);
+ if (!s)
+ return -1;
+
+ sdp_close(s);
+
+ if (uuid)
+ *uuid = 0x0000;
+
+ if (channel)
+ *channel = 0;
+
+ return 0;
+}