diff --git a/src/fprintd.xml b/src/fprintd.xml
index d22b0ca..1efec05 100644
--- a/src/fprintd.xml
+++ b/src/fprintd.xml
@@ -11,10 +11,12 @@
+
+
diff --git a/src/main.c b/src/main.c
index 01074a5..db9fd9a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -55,9 +55,9 @@ static gboolean fprint_load_print_data(Fprint *fprint, guint32 device_id,
static gboolean fprint_unload_print_data(Fprint *fprint, guint32 device_id,
guint32 print_id, GError **error);
static gboolean fprint_claim_device(Fprint *fprint, guint32 device_id,
- GError **error);
+ DBusGMethodInvocation *minv);
static gboolean fprint_release_device(Fprint *fprint, guint32 device_id,
- GError **error);
+ DBusGMethodInvocation *minv);
static gboolean fprint_verify_start(Fprint *fprint, guint32 device_id,
guint32 finger, GError **error);
static gboolean fprint_get_verify_result(Fprint *fprint, guint32 device_id,
@@ -76,6 +76,7 @@ typedef enum {
FPRINT_ERROR_PRINT_NOT_FOUND,
FPRINT_ERROR_PRINT_LOAD,
FPRINT_ERROR_NO_SUCH_LOADED_PRINT,
+ FPRINT_ERROR_CLAIM_DEVICE,
FPRINT_ERROR_VERIFY_START,
FPRINT_ERROR_VERIFY_STOP,
FPRINT_ERROR_FAILED,
@@ -95,6 +96,12 @@ struct session_data {
/* a list of pending verify results to be returned via GetVerifyResult() */
GList *verify_results;
+ /* method invocation for async ClaimDevice() */
+ DBusGMethodInvocation *minv_claim_device;
+
+ /* method invocation for async ReleaseDevice() */
+ DBusGMethodInvocation *minv_release_device;
+
/* method invocation for async GetVerifyResult() */
DBusGMethodInvocation *minv_get_verify_result;
@@ -181,41 +188,86 @@ out:
return TRUE;
}
+static void dev_open_cb(struct fp_dev *dev, int status, void *user_data)
+{
+ struct registered_dev *rdev = user_data;
+ struct session_data *session = rdev->session;
+
+ g_message("device %d claim status %d", rdev->id, status);
+
+ if (status != 0) {
+ GError *error;
+ g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_CLAIM_DEVICE,
+ "Open failed with error %d", status);
+ dbus_g_method_return_error(session->minv_claim_device, error);
+ return;
+ }
+
+ rdev->dev = dev;
+ dbus_g_method_return(session->minv_claim_device);
+}
+
static gboolean fprint_claim_device(Fprint *fprint, guint32 device_id,
- GError **error)
+ DBusGMethodInvocation *minv)
{
struct registered_dev *rdev = find_rdev_by_id(device_id);
+ GError *error = NULL;
+ int r;
+
+ g_message("claiming device %d", device_id);
+
if (!rdev) {
- g_set_error(error, FPRINT_ERROR, FPRINT_ERROR_NO_SUCH_DEVICE,
+ g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_NO_SUCH_DEVICE,
"No such device %d", device_id);
+ dbus_g_method_return_error(minv, error);
return FALSE;
}
- /* FIXME async? */
- /* FIXME more error checking */
- rdev->dev = fp_dev_open(rdev->ddev);
rdev->session = g_slice_new0(struct session_data);
- g_message("claimed device %d", device_id);
+ rdev->session->minv_claim_device = minv;
+
+ r = fp_async_dev_open(rdev->ddev, dev_open_cb, rdev);
+ if (r < 0) {
+ g_slice_free(struct session_data, rdev->session);
+ rdev->session = NULL;
+ g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_CLAIM_DEVICE,
+ "Could not attempt device open, error %d", r);
+ dbus_g_method_return_error(minv, error);
+ return FALSE;
+ }
+
return TRUE;
}
+static void dev_close_cb(struct fp_dev *dev, void *user_data)
+{
+ struct registered_dev *rdev = user_data;
+ struct session_data *session = rdev->session;
+ DBusGMethodInvocation *minv = session->minv_release_device;
+
+ rdev->dev = NULL;
+ g_slice_free(struct session_data, session);
+ rdev->session = NULL;
+
+ g_message("released device %d", rdev->id);
+ dbus_g_method_return(minv);
+}
+
static gboolean fprint_release_device(Fprint *fprint, guint32 device_id,
- GError **error)
+ DBusGMethodInvocation *minv)
{
struct registered_dev *rdev = find_rdev_by_id(device_id);
struct session_data *session;
+ GError *error = NULL;
GSList *elem;
if (!rdev) {
- g_set_error(error, FPRINT_ERROR, FPRINT_ERROR_NO_SUCH_DEVICE,
+ g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_NO_SUCH_DEVICE,
"No such device %d", device_id);
+ dbus_g_method_return_error(minv, error);
return FALSE;
}
- /* FIXME make async? */
- fp_dev_close(rdev->dev);
- rdev->dev = NULL;
-
/* Unload any loaded prints */
session = rdev->session;
elem = session->loaded_prints;
@@ -227,9 +279,8 @@ static gboolean fprint_release_device(Fprint *fprint, guint32 device_id,
g_slist_free(session->loaded_prints);
}
- g_slice_free(struct session_data, rdev->session);
- rdev->session = NULL;
- g_message("released device %d", device_id);
+ session->minv_release_device = minv;
+ fp_async_dev_close(rdev->dev, dev_close_cb, rdev);
return TRUE;
}