summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2006-09-29 16:15:41 +0000
committerMarcel Holtmann <marcel@holtmann.org>2006-09-29 16:15:41 +0000
commit6d2c7e465e4a8e3e6bb9595ccfd0f471070eda69 (patch)
treea7e13644ff92608e32c9e77661b68467dd12dd10
parent2f867d62c154c7746b97480fee121a5feb308a94 (diff)
Add framework for Celluon keyboard
-rw-r--r--hidd/fakehid.c67
-rw-r--r--hidd/fakehid.txt1
-rw-r--r--hidd/hidd.h1
-rw-r--r--hidd/main.c12
4 files changed, 79 insertions, 2 deletions
diff --git a/hidd/fakehid.c b/hidd/fakehid.c
index 3a1c0d6e..22349cbf 100644
--- a/hidd/fakehid.c
+++ b/hidd/fakehid.c
@@ -452,3 +452,70 @@ int jthree_keyboard(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel)
return 0;
}
+
+int celluon_keyboard(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel)
+{
+ unsigned char buf[16];
+ struct sigaction sa;
+ struct pollfd p;
+ sigset_t sigs;
+ char addr[18];
+ int fd, sk, len;
+
+ sk = rfcomm_connect(src, dst, channel);
+ if (sk < 0)
+ return -1;
+
+ fd = uinput_create("Celluon Keyboard", 1, 0);
+ if (fd < 0) {
+ close(sk);
+ return -1;
+ }
+
+ ba2str(dst, addr);
+
+ printf("Connected to %s on channel %d\n", addr, channel);
+ printf("Press CTRL-C for hangup\n");
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_flags = SA_NOCLDSTOP;
+ sa.sa_handler = SIG_IGN;
+ sigaction(SIGCHLD, &sa, NULL);
+ sigaction(SIGPIPE, &sa, NULL);
+
+ sa.sa_handler = sig_term;
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+
+ sa.sa_handler = sig_hup;
+ sigaction(SIGHUP, &sa, NULL);
+
+ sigfillset(&sigs);
+ sigdelset(&sigs, SIGCHLD);
+ sigdelset(&sigs, SIGPIPE);
+ sigdelset(&sigs, SIGTERM);
+ sigdelset(&sigs, SIGINT);
+ sigdelset(&sigs, SIGHUP);
+
+ p.fd = sk;
+ p.events = POLLIN | POLLERR | POLLHUP;
+
+ while (!__io_canceled) {
+ p.revents = 0;
+ if (ppoll(&p, 1, NULL, &sigs) < 1)
+ continue;
+
+ len = read(sk, buf, sizeof(buf));
+ if (len < 0)
+ break;
+ }
+
+ printf("Disconnected\n");
+
+ ioctl(fd, UI_DEV_DESTROY);
+
+ close(fd);
+ close(sk);
+
+ return 0;
+}
diff --git a/hidd/fakehid.txt b/hidd/fakehid.txt
index cfe4a296..05f5be34 100644
--- a/hidd/fakehid.txt
+++ b/hidd/fakehid.txt
@@ -90,6 +90,7 @@ Inquiring ...
# hcitool info 00:0B:24:aa:bb:cc
Requesting information ...
BD Address: 00:0B:24:aa:bb:cc
+ OUI Company: AirLogic (00-0B-24)
Device Name: CL800BT
LMP Version: 1.1 (0x1) LMP Subversion: 0x291
Manufacturer: Cambridge Silicon Radio (10)
diff --git a/hidd/hidd.h b/hidd/hidd.h
index bbbc952b..616eb5a1 100644
--- a/hidd/hidd.h
+++ b/hidd/hidd.h
@@ -31,3 +31,4 @@ int get_alternate_device_info(const bdaddr_t *src, const bdaddr_t *dst, uint16_t
int epox_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel);
int headset_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel);
int jthree_keyboard(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel);
+int celluon_keyboard(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel);
diff --git a/hidd/main.c b/hidd/main.c
index 89c79509..a825f0de 100644
--- a/hidd/main.c
+++ b/hidd/main.c
@@ -470,6 +470,13 @@ static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, uint8_t subclass,
}
break;
}
+ if (subclass == 0x02 || !strcmp(name, "Serial Port")) {
+ if (celluon_keyboard(src, dst, channel) < 0) {
+ close(ctl);
+ exit(1);
+ }
+ break;
+ }
break;
case HEADSET_SVCLASS_ID:
@@ -551,8 +558,9 @@ static void do_search(int ctl, bdaddr_t *bdaddr, uint8_t subclass, int fakehid,
for (i = 0; i < num_rsp; i++) {
memcpy(class, (info+i)->dev_class, 3);
- if (class[0] == 0x00 && class[2] == 0x00 &&
- (class[1] == 0x40 || class[1] == 0x1f)) {
+ if ((class[0] == 0x00 && class[2] == 0x00 &&
+ (class[1] == 0x40 || class[1] == 0x1f)) ||
+ (class[0] == 0x10 && class[1] == 0x02 && class[2] == 0x40)) {
bacpy(&dst, &(info+i)->bdaddr);
ba2str(&dst, addr);