2 * Asynchronous I/O functionality
3 * Copyright (C) 2008 Daniel Drake <dsd@gentoo.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 #define FP_COMPONENT "async"
26 #include "fp_internal.h"
28 /* Drivers call this when device initialisation has completed */
29 void fpi_drvcb_open_complete(struct fp_dev
*dev
, int status
)
31 fp_dbg("status %d", status
);
32 BUG_ON(dev
->state
!= DEV_STATE_INITIALIZING
);
33 dev
->state
= (status
) ? DEV_STATE_ERROR
: DEV_STATE_INITIALIZED
;
34 opened_devices
= g_slist_prepend(opened_devices
, dev
);
36 dev
->open_cb(dev
, status
, dev
->open_cb_data
);
39 API_EXPORTED
int fp_async_dev_open(struct fp_dscv_dev
*ddev
, fp_dev_open_cb cb
,
42 struct fp_driver
*drv
= ddev
->drv
;
44 libusb_device_handle
*udevh
;
48 r
= libusb_open(ddev
->udev
, &udevh
);
50 fp_err("usb_open failed, error %d", r
);
54 dev
= g_malloc0(sizeof(*dev
));
57 dev
->__enroll_stage
= -1;
58 dev
->state
= DEV_STATE_INITIALIZING
;
60 dev
->open_cb_data
= user_data
;
63 fpi_drvcb_open_complete(dev
, 0);
67 dev
->state
= DEV_STATE_INITIALIZING
;
68 r
= drv
->open(dev
, ddev
->driver_data
);
70 fp_err("device initialisation failed, driver=%s", drv
->name
);
78 /* Drivers call this when device deinitialisation has completed */
79 void fpi_drvcb_close_complete(struct fp_dev
*dev
)
82 BUG_ON(dev
->state
!= DEV_STATE_DEINITIALIZING
);
83 dev
->state
= DEV_STATE_DEINITIALIZED
;
84 libusb_close(dev
->udev
);
86 dev
->close_cb(dev
, dev
->close_cb_data
);
90 API_EXPORTED
void fp_async_dev_close(struct fp_dev
*dev
,
91 fp_dev_close_cb callback
, void *user_data
)
93 struct fp_driver
*drv
= dev
->drv
;
95 if (g_slist_index(opened_devices
, (gconstpointer
) dev
) == -1)
96 fp_err("device %p not in opened list!", dev
);
97 opened_devices
= g_slist_remove(opened_devices
, (gconstpointer
) dev
);
99 dev
->close_cb
= callback
;
100 dev
->close_cb_data
= user_data
;
103 fpi_drvcb_close_complete(dev
);
107 dev
->state
= DEV_STATE_DEINITIALIZING
;
111 /* Drivers call this when enrollment has started */
112 void fpi_drvcb_enroll_started(struct fp_dev
*dev
, int status
)
114 fp_dbg("status %d", status
);
115 BUG_ON(dev
->state
!= DEV_STATE_ENROLL_STARTING
);
119 fp_dbg("adjusted to %d", status
);
121 dev
->state
= DEV_STATE_ERROR
;
122 if (dev
->enroll_stage_cb
)
123 dev
->enroll_stage_cb(dev
, status
, NULL
, NULL
,
124 dev
->enroll_stage_cb_data
);
126 dev
->state
= DEV_STATE_ENROLLING
;
130 API_EXPORTED
int fp_async_enroll_start(struct fp_dev
*dev
,
131 fp_enroll_stage_cb callback
, void *user_data
)
133 struct fp_driver
*drv
= dev
->drv
;
136 if (!dev
->nr_enroll_stages
|| !drv
->enroll_start
) {
137 fp_err("driver %s has 0 enroll stages or no enroll func",
142 fp_dbg("starting enrollment");
143 dev
->enroll_stage_cb
= callback
;
144 dev
->enroll_stage_cb_data
= user_data
;
146 dev
->state
= DEV_STATE_ENROLL_STARTING
;
147 r
= drv
->enroll_start(dev
);
149 dev
->enroll_stage_cb
= NULL
;
150 fp_err("failed to start enrollment");
151 dev
->state
= DEV_STATE_ERROR
;
157 /* Drivers call this when an enroll stage has completed */
158 void fpi_drvcb_enroll_stage_completed(struct fp_dev
*dev
, int result
,
159 struct fp_print_data
*data
, struct fp_img
*img
)
161 BUG_ON(dev
->state
!= DEV_STATE_ENROLLING
);
162 fp_dbg("result %d", result
);
163 if (!dev
->enroll_stage_cb
) {
164 fp_dbg("ignoring enroll result as no callback is subscribed");
167 if (result
== FP_ENROLL_COMPLETE
&& !data
) {
168 fp_err("BUG: complete but no data?");
169 result
= FP_ENROLL_FAIL
;
171 dev
->enroll_stage_cb(dev
, result
, data
, img
, dev
->enroll_stage_cb_data
);
174 /* Drivers call this when enrollment has stopped */
175 void fpi_drvcb_enroll_stopped(struct fp_dev
*dev
)
178 BUG_ON(dev
->state
!= DEV_STATE_ENROLL_STOPPING
);
179 dev
->state
= DEV_STATE_INITIALIZED
;
180 if (dev
->enroll_stop_cb
)
181 dev
->enroll_stop_cb(dev
, dev
->enroll_stop_cb_data
);
184 API_EXPORTED
int fp_async_enroll_stop(struct fp_dev
*dev
,
185 fp_enroll_stop_cb callback
, void *user_data
)
187 struct fp_driver
*drv
= dev
->drv
;
191 if (!drv
->enroll_start
)
194 dev
->enroll_stage_cb
= NULL
;
195 dev
->enroll_stop_cb
= callback
;
196 dev
->enroll_stop_cb_data
= user_data
;
197 dev
->state
= DEV_STATE_ENROLL_STOPPING
;
199 if (!drv
->enroll_stop
) {
200 fpi_drvcb_enroll_stopped(dev
);
204 r
= drv
->enroll_stop(dev
);
206 fp_err("failed to stop enrollment");
207 dev
->enroll_stop_cb
= NULL
;
213 API_EXPORTED
int fp_async_verify_start(struct fp_dev
*dev
,
214 struct fp_print_data
*data
, fp_verify_cb callback
, void *user_data
)
216 struct fp_driver
*drv
= dev
->drv
;
220 if (!drv
->verify_start
)
223 dev
->state
= DEV_STATE_VERIFY_STARTING
;
224 dev
->verify_cb
= callback
;
225 dev
->verify_cb_data
= user_data
;
226 dev
->verify_data
= data
;
228 r
= drv
->verify_start(dev
);
230 dev
->verify_cb
= NULL
;
231 dev
->state
= DEV_STATE_ERROR
;
232 fp_err("failed to start verification, error %d", r
);
237 /* Drivers call this when verification has started */
238 void fpi_drvcb_verify_started(struct fp_dev
*dev
, int status
)
241 BUG_ON(dev
->state
!= DEV_STATE_VERIFY_STARTING
);
245 fp_dbg("adjusted to %d", status
);
247 dev
->state
= DEV_STATE_ERROR
;
249 dev
->verify_cb(dev
, status
, NULL
, dev
->verify_cb_data
);
251 dev
->state
= DEV_STATE_VERIFYING
;
255 /* Drivers call this to report a verify result (which might mark completion) */
256 void fpi_drvcb_report_verify_result(struct fp_dev
*dev
, int result
,
259 fp_dbg("result %d", result
);
260 BUG_ON(dev
->state
!= DEV_STATE_VERIFYING
);
261 if (result
< 0 || result
== FP_VERIFY_NO_MATCH
262 || result
== FP_VERIFY_MATCH
)
263 dev
->state
= DEV_STATE_VERIFY_DONE
;
266 dev
->verify_cb(dev
, result
, img
, dev
->verify_cb_data
);
268 fp_dbg("ignoring verify result as no callback is subscribed");
271 /* Drivers call this when verification has stopped */
272 void fpi_drvcb_verify_stopped(struct fp_dev
*dev
)
275 BUG_ON(dev
->state
!= DEV_STATE_VERIFY_STOPPING
);
276 dev
->state
= DEV_STATE_INITIALIZED
;
277 if (dev
->verify_stop_cb
)
278 dev
->verify_stop_cb(dev
, dev
->verify_stop_cb_data
);
281 API_EXPORTED
int fp_async_verify_stop(struct fp_dev
*dev
,
282 fp_verify_stop_cb callback
, void *user_data
)
284 struct fp_driver
*drv
= dev
->drv
;
285 gboolean iterating
= (dev
->state
== DEV_STATE_VERIFYING
);
289 BUG_ON(dev
->state
!= DEV_STATE_ERROR
290 && dev
->state
!= DEV_STATE_VERIFYING
291 && dev
->state
!= DEV_STATE_VERIFY_DONE
);
293 dev
->verify_cb
= NULL
;
294 dev
->verify_stop_cb
= callback
;
295 dev
->verify_stop_cb_data
= user_data
;
296 dev
->state
= DEV_STATE_VERIFY_STOPPING
;
298 if (!drv
->verify_start
)
300 if (!drv
->verify_stop
) {
301 dev
->state
= DEV_STATE_INITIALIZED
;
302 fpi_drvcb_verify_stopped(dev
);
306 r
= drv
->verify_stop(dev
, iterating
);
308 fp_err("failed to stop verification");
309 dev
->verify_stop_cb
= NULL
;
314 API_EXPORTED
int fp_async_identify_start(struct fp_dev
*dev
,
315 struct fp_print_data
**gallery
, fp_identify_cb callback
, void *user_data
)
317 struct fp_driver
*drv
= dev
->drv
;
321 if (!drv
->identify_start
)
323 dev
->state
= DEV_STATE_IDENTIFY_STARTING
;
324 dev
->identify_cb
= callback
;
325 dev
->identify_cb_data
= user_data
;
326 dev
->identify_gallery
= gallery
;
328 r
= drv
->identify_start(dev
);
330 fp_err("identify_start failed with error %d", r
);
331 dev
->identify_cb
= NULL
;
332 dev
->state
= DEV_STATE_ERROR
;
337 /* Driver-lib: identification has started, expect results soon */
338 void fpi_drvcb_identify_started(struct fp_dev
*dev
, int status
)
340 fp_dbg("status %d", status
);
341 BUG_ON(dev
->state
!= DEV_STATE_IDENTIFY_STARTING
);
345 fp_dbg("adjusted to %d", status
);
347 dev
->state
= DEV_STATE_ERROR
;
348 if (dev
->identify_cb
)
349 dev
->identify_cb(dev
, status
, 0, NULL
, dev
->identify_cb_data
);
351 dev
->state
= DEV_STATE_IDENTIFYING
;
355 /* Drivers report an identify result (which might mark completion) */
356 void fpi_drvcb_report_identify_result(struct fp_dev
*dev
, int result
,
357 size_t match_offset
, struct fp_img
*img
)
359 fp_dbg("result %d", result
);
360 BUG_ON(dev
->state
!= DEV_STATE_IDENTIFYING
361 && dev
->state
!= DEV_STATE_ERROR
);
362 if (result
< 0 || result
== FP_VERIFY_NO_MATCH
363 || result
== FP_VERIFY_MATCH
)
364 dev
->state
= DEV_STATE_IDENTIFY_DONE
;
366 if (dev
->identify_cb
)
367 dev
->identify_cb(dev
, result
, match_offset
, img
, dev
->identify_cb_data
);
369 fp_dbg("ignoring verify result as no callback is subscribed");
372 API_EXPORTED
int fp_async_identify_stop(struct fp_dev
*dev
,
373 fp_identify_stop_cb callback
, void *user_data
)
375 struct fp_driver
*drv
= dev
->drv
;
376 gboolean iterating
= (dev
->state
== DEV_STATE_IDENTIFYING
);
380 BUG_ON(dev
->state
!= DEV_STATE_IDENTIFYING
381 && dev
->state
!= DEV_STATE_IDENTIFY_DONE
);
383 dev
->state
= DEV_STATE_IDENTIFY_STOPPING
;
384 dev
->identify_cb
= NULL
;
385 dev
->identify_stop_cb
= callback
;
386 dev
->identify_stop_cb_data
= user_data
;
388 if (!drv
->identify_start
)
390 if (!drv
->identify_stop
) {
391 dev
->state
= DEV_STATE_INITIALIZED
;
392 fpi_drvcb_identify_stopped(dev
);
396 r
= drv
->identify_stop(dev
, iterating
);
398 fp_err("failed to stop identification");
399 dev
->identify_stop_cb
= NULL
;
405 /* Drivers call this when identification has stopped */
406 void fpi_drvcb_identify_stopped(struct fp_dev
*dev
)
409 BUG_ON(dev
->state
!= DEV_STATE_IDENTIFY_STOPPING
);
410 dev
->state
= DEV_STATE_INITIALIZED
;
411 if (dev
->identify_stop_cb
)
412 dev
->identify_stop_cb(dev
, dev
->identify_stop_cb_data
);