diff options
author | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2007-02-23 18:22:03 +0000 |
---|---|---|
committer | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2007-02-23 18:22:03 +0000 |
commit | 2957490728208811926b2d548ef77432564fc916 (patch) | |
tree | 1c4810d4b5f5637027670ba76fe3f28a10ba3b8b | |
parent | 0f08988e53758147e3394bbc24c751f186392b06 (diff) |
Fake input: added function to create the D-Bus fake input path
-rw-r--r-- | input/device.c | 177 |
1 files changed, 119 insertions, 58 deletions
diff --git a/input/device.c b/input/device.c index 2c44750e..495886bd 100644 --- a/input/device.c +++ b/input/device.c @@ -65,9 +65,17 @@ const char *pnp_uuid = "00001200-0000-1000-8000-00805f9b34fb"; const char *hid_uuid = "00001124-0000-1000-8000-00805f9b34fb"; const char *headset_uuid = "00001108-0000-1000-8000-00805f9b34fb"; +struct fake_input { + uint8_t ch; +}; + struct input_device { bdaddr_t dst; - struct hidp_connadd_req hidp; + uint8_t major; + uint8_t minor; + struct hidp_connadd_req hidp; /* FIXME: Use dynamic alloc? */ + struct fake_input *fake; + }; struct input_manager { @@ -92,7 +100,7 @@ struct pending_connect { DBusMessage *msg; }; -static struct input_device *input_device_new(bdaddr_t *dst) +static struct input_device *input_device_new(bdaddr_t *dst, uint32_t cls) { struct input_device *idev; @@ -104,6 +112,9 @@ static struct input_device *input_device_new(bdaddr_t *dst) bacpy(&idev->dst, dst); + idev->major = (cls >> 8) & 0x1f; + idev->minor = (cls >> 2) & 0x3f; + return idev; } @@ -317,54 +328,76 @@ static void extract_pnp_record(sdp_record_t *rec, struct hidp_connadd_req *req) req->version = pdlist ? pdlist->val.uint16 : 0x0000; } -static const char *create_input_path(uint8_t minor) +static const char *create_input_path(uint8_t major, uint8_t minor) { static char path[48]; char subpath[32]; static int next_id = 0; - switch (minor & 0xc0) { - case 0x40: - strcpy(subpath, "keyboard"); - break; - case 0x80: - strcpy(subpath, "pointing"); - break; - case 0xc0: - strcpy(subpath, "combo"); - break; - default: - subpath[0] = '\0'; + switch (major) { + case 0x04: /* Audio */ + switch (minor) { + /* FIXME: Testing required */ + case 0x01: /* Wearable Headset Device */ + strcpy(subpath, "wearable"); + break; + case 0x02: /* Hands-free */ + strcpy(subpath, "handsfree"); + break; + case 0x06: /* Headphone */ + strcpy(subpath, "headphone"); + break; + default: + return NULL; + } break; - } + case 0x05: /* Peripheral */ + switch (minor & 0x30) { + case 0x10: + strcpy(subpath, "keyboard"); + break; + case 0x20: + strcpy(subpath, "pointing"); + break; + case 0x30: + strcpy(subpath, "combo"); + break; + default: + subpath[0] = '\0'; + break; + } - if ((minor & 0x3f) && (strlen(subpath) > 0)) - strcat(subpath, "/"); + if ((minor & 0x0f) && (strlen(subpath) > 0)) + strcat(subpath, "/"); - switch (minor & 0x3f) { - case 0x00: - break; - case 0x01: - strcat(subpath, "joystick"); - break; - case 0x02: - strcat(subpath, "gamepad"); - break; - case 0x03: - strcat(subpath, "remotecontrol"); - break; - case 0x04: - strcat(subpath, "sensing"); - break; - case 0x05: - strcat(subpath, "digitizertablet"); - break; - case 0x06: - strcat(subpath, "cardreader"); + switch (minor & 0x0f) { + case 0x00: + break; + case 0x01: + strcat(subpath, "joystick"); + break; + case 0x02: + strcat(subpath, "gamepad"); + break; + case 0x03: + strcat(subpath, "remotecontrol"); + break; + case 0x04: + strcat(subpath, "sensing"); + break; + case 0x05: + strcat(subpath, "digitizertablet"); + break; + case 0x06: + strcat(subpath, "cardreader"); + break; + default: + strcat(subpath, "reserved"); + break; + } break; default: - strcat(subpath, "reserved"); - break; + return NULL; } snprintf(path, 48, "%s/%s%d", INPUT_PATH, subpath, next_id++); @@ -995,6 +1028,7 @@ static void hid_record_reply(DBusPendingCall *call, void *data) uint8_t *rec_bin; const char *path; int len, scanned; + uint32_t cls; dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { @@ -1023,13 +1057,19 @@ static void hid_record_reply(DBusPendingCall *call, void *data) goto fail; } - idev = input_device_new(&pr->dst); + if (get_class(&pr->src, &pr->dst, &cls) < 0) { + err_not_supported(pr->conn, pr->msg); + error("Device class not available"); + goto fail; + } + + idev = input_device_new(&pr->dst, cls); extract_hid_record(pr->hid_rec, &idev->hidp); if (pr->pnp_rec) extract_pnp_record(pr->pnp_rec, &idev->hidp); - path = create_input_path(idev->hidp.subclass); + path = create_input_path(idev->major, idev->minor); if (register_input_device(pr->conn, idev, path) < 0) { err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); @@ -1203,9 +1243,10 @@ static void headset_record_reply(DBusPendingCall *call, void *data) uint8_t *rec_bin; sdp_record_t *rec; sdp_list_t *protos; + const char *path; int len, scanned; + uint32_t cls; uint8_t ch; - const char *path = "/org/bluez/input/headset0"; dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { @@ -1250,14 +1291,28 @@ static void headset_record_reply(DBusPendingCall *call, void *data) goto fail; } - idev = input_device_new(&pr->dst); + if (get_class(&pr->src, &pr->dst, &cls) < 0) { + err_not_supported(pr->conn, pr->msg); + error("Device class not available"); + goto fail; + } + + idev = input_device_new(&pr->dst, cls); if (!idev) { error("Out of memory when allocating new input"); goto fail; } - /* FIXME: Store the ch and create the fake input path */ + idev->fake = malloc(sizeof(struct fake_input)); + if (!idev->fake) { + error("Out of memory when allocating new fake input"); + input_device_free(idev); + goto fail; + } + memset(idev->fake, 0, sizeof(struct fake_input)); + idev->fake->ch = ch; + path = create_input_path(idev->major, idev->minor); if (register_input_device(pr->conn, idev, path) < 0) { error("D-Bus path registration failed:%s", path); err_failed(pr->conn, pr->msg, "Path registration failed"); @@ -1355,13 +1410,15 @@ static DBusHandlerResult manager_create_device(DBusConnection *conn, dev_id = hci_devid(adapter); snprintf(adapter_path, 32, "/org/bluez/hci%d", dev_id); - idev = input_device_new(&dst); + if (get_class(&mgr->src, &dst, &cls) < 0) { + error("Device class not available"); + return err_not_supported(conn, msg); + } + + idev = input_device_new(&dst, cls); if (!idev) return DBUS_HANDLER_RESULT_NEED_MEMORY; - if (get_class(&mgr->src, &dst, &cls) < 0) - return err_not_supported(conn, msg); - if (get_stored_device_info(&mgr->src, &idev->dst, &idev->hidp) < 0) { struct pending_req *pr; /* Data not found: create the input device later */ @@ -1393,8 +1450,7 @@ static DBusHandlerResult manager_create_device(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } - /* FIXME: Stored data found, create a fake input or a standard HID */ - path = create_input_path(idev->hidp.subclass); + path = create_input_path(idev->major, idev->minor); if (register_input_device(conn, idev, path) < 0) { input_device_free(idev); return err_failed(conn, msg, "D-Bus path registration failed"); @@ -1530,31 +1586,36 @@ static const DBusObjectPathVTable manager_table = { static void stored_input(char *key, char *value, void *data) { - DBusConnection *conn = data; + bdaddr_t *src = data; struct input_device *idev; const char *path; bdaddr_t dst; + uint32_t cls; str2ba(key, &dst); - idev = input_device_new(&dst); + + if (get_class(src, &dst, &cls) < 0) + return; + + idev = input_device_new(&dst, cls); if (parse_stored_device_info(value, &idev->hidp) < 0) { input_device_free(idev); return; } - path = create_input_path(idev->hidp.subclass); - if (register_input_device(conn, idev, path) < 0) + path = create_input_path(idev->major, idev->minor); + if (register_input_device(connection, idev, path) < 0) input_device_free(idev); } -static int register_stored_inputs(DBusConnection *conn, bdaddr_t *src) +static int register_stored_inputs(bdaddr_t *src) { char filename[PATH_MAX + 1]; char addr[18]; ba2str(src, addr); create_name(filename, PATH_MAX, STORAGEDIR, addr, "hidd"); - textfile_foreach(filename, stored_input, conn); + textfile_foreach(filename, stored_input, src); return 0; } @@ -1597,7 +1658,7 @@ int input_dbus_init(void) bacpy(&mgr->src, &src); /* Register well known HID devices */ - register_stored_inputs(connection, &src); + register_stored_inputs(&src); return 0; |