GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 74.5% 791 / 0 / 1062
Functions: 89.6% 43 / 0 / 48
Branches: 48.3% 185 / 0 / 383

libfprint/drivers/fpcmoc/fpc.c
Line Branch Exec Source
1 /*
2 * Copyright (c) 2022 Fingerprint Cards AB <tech@fingerprints.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include "drivers_api.h"
20 #include "fpc.h"
21 #include "fpi-byte-writer.h"
22
23 #define FP_COMPONENT "fpcmoc"
24 #define MAX_ENROLL_SAMPLES (25)
25 #define CTRL_TIMEOUT (2000)
26 #define DATA_TIMEOUT (5000)
27
28 /* Usb port setting */
29 #define EP_IN (1 | FPI_USB_ENDPOINT_IN)
30 #define EP_IN_MAX_BUF_SIZE (2048)
31
32 struct _FpiDeviceFpcMoc
33 {
34 FpDevice parent;
35 FpiSsm *task_ssm;
36 FpiSsm *cmd_ssm;
37 gboolean cmd_suspended;
38 gint enroll_stage;
39 gint immobile_stage;
40 gint max_enroll_stage;
41 gint max_immobile_stage;
42 gint max_stored_prints;
43 guint cmd_data_timeout;
44 guint8 *dbid;
45 gboolean do_cleanup;
46 GCancellable *interrupt_cancellable;
47 };
48
49
4/6
fpi_device_fpcmoc_class_intern_init:
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 125 times.
fpi_device_fpcmoc_get_type:
✓ Branch 2 → 3 taken 125 times.
✓ Branch 2 → 7 taken 24 times.
✓ Branch 4 → 5 taken 125 times.
✗ Branch 4 → 7 not taken.
399 G_DEFINE_TYPE (FpiDeviceFpcMoc, fpi_device_fpcmoc, FP_TYPE_DEVICE);
50
51 typedef void (*SynCmdMsgCallback) (FpiDeviceFpcMoc *self,
52 void *resp,
53 GError *error);
54
55 typedef struct
56 {
57 FpcCmdType cmdtype;
58 guint8 request;
59 guint16 value;
60 guint16 index;
61 guint8 *data;
62 gsize data_len;
63 gsize resp_len;
64 SynCmdMsgCallback callback;
65 } CommandData;
66
67 static const FpIdEntry id_table[] = {
68 { .vid = 0x10A5, .pid = 0xFFE0, },
69 { .vid = 0x10A5, .pid = 0xA305, },
70 { .vid = 0x10A5, .pid = 0xA306, },
71 { .vid = 0x10A5, .pid = 0xDA04, },
72 { .vid = 0x10A5, .pid = 0xD805, },
73 { .vid = 0x10A5, .pid = 0xD205, },
74 { .vid = 0x10A5, .pid = 0x9524, },
75 { .vid = 0x10A5, .pid = 0x9544, },
76 { .vid = 0x10A5, .pid = 0xC844, },
77 { .vid = 0x10A5, .pid = 0x9B24, },
78 /* terminating entry */
79 { .vid = 0, .pid = 0, .driver_data = 0 },
80 };
81
82 static void
83 fpc_suspend_resume_cb (FpiUsbTransfer *transfer,
84 FpDevice *device,
85 gpointer user_data,
86 GError *error)
87 {
88 int ssm_state = fpi_ssm_get_cur_state (transfer->ssm);
89
90 fp_dbg ("%s current ssm state: %d", G_STRFUNC, ssm_state);
91
92 if (ssm_state == FPC_CMD_SUSPENDED)
93 {
94 if (error)
95 fpi_ssm_mark_failed (transfer->ssm, g_error_copy (error));
96
97 fpi_device_suspend_complete (device, error);
98 /* The resume handler continues to the next state! */
99 }
100 else if (ssm_state == FPC_CMD_RESUME)
101 {
102 if (error)
103 fpi_ssm_mark_failed (transfer->ssm, g_error_copy (error));
104 else
105 fpi_ssm_jump_to_state (transfer->ssm, FPC_CMD_GET_DATA);
106
107 fpi_device_resume_complete (device, error);
108 }
109 }
110
111 static void
112 103 fpc_cmd_receive_cb (FpiUsbTransfer *transfer,
113 FpDevice *device,
114 gpointer user_data,
115 GError *error)
116 {
117 103 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device);
118 103 CommandData *data = user_data;
119 103 int ssm_state = 0;
120
121
1/4
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 9 taken 103 times.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 9 not taken.
103 if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) && (self->cmd_suspended))
122 {
123 g_error_free (error);
124 fpi_ssm_jump_to_state (transfer->ssm, FPC_CMD_SUSPENDED);
125 return;
126 }
127
128
1/2
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 12 taken 103 times.
103 if (error)
129 {
130 fpi_ssm_mark_failed (transfer->ssm, error);
131 return;
132 }
133
134
1/2
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 16 taken 103 times.
103 if (data == NULL)
135 {
136 fpi_ssm_mark_failed (transfer->ssm,
137 fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
138 return;
139 }
140
141 103 ssm_state = fpi_ssm_get_cur_state (transfer->ssm);
142 103 fp_dbg ("%s current ssm request: %d state: %d", G_STRFUNC, data->request, ssm_state);
143
144 /* clean cmd_ssm except capture command for suspend/resume case */
145
4/4
✓ Branch 18 → 19 taken 66 times.
✓ Branch 18 → 20 taken 37 times.
✓ Branch 19 → 20 taken 49 times.
✓ Branch 19 → 21 taken 17 times.
103 if (ssm_state != FPC_CMD_SEND || data->request != FPC_CMD_ARM)
146 86 self->cmd_ssm = NULL;
147
148
2/2
✓ Branch 21 → 22 taken 7 times.
✓ Branch 21 → 26 taken 96 times.
103 if (data->cmdtype == FPC_CMDTYPE_TO_DEVICE)
149 {
150 /* It should not receive any data. */
151
1/2
✓ Branch 22 → 23 taken 7 times.
✗ Branch 22 → 24 not taken.
7 if (data->callback)
152 7 data->callback (self, NULL, NULL);
153
154 7 fpi_ssm_mark_completed (transfer->ssm);
155 7 return;
156 }
157
2/2
✓ Branch 26 → 27 taken 74 times.
✓ Branch 26 → 46 taken 22 times.
96 else if (data->cmdtype == FPC_CMDTYPE_TO_DEVICE_EVTDATA)
158 {
159
2/2
✓ Branch 27 → 28 taken 37 times.
✓ Branch 27 → 30 taken 37 times.
74 if (ssm_state == FPC_CMD_SEND)
160 {
161 37 fpi_ssm_next_state (transfer->ssm);
162 37 return;
163 }
164
165
1/2
✓ Branch 30 → 31 taken 37 times.
✗ Branch 30 → 60 not taken.
37 if (ssm_state == FPC_CMD_GET_DATA)
166 {
167 37 fp_dbg ("%s recv evt data length: %ld", G_STRFUNC, transfer->actual_length);
168
1/2
✗ Branch 32 → 33 not taken.
✓ Branch 32 → 37 taken 37 times.
37 if (transfer->actual_length == 0)
169 {
170 fp_err ("%s Expect data but actual_length = 0", G_STRFUNC);
171 fpi_ssm_mark_failed (transfer->ssm,
172 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
173 return;
174 }
175
176
1/2
✗ Branch 37 → 38 not taken.
✓ Branch 37 → 42 taken 37 times.
37 if (transfer->actual_length > sizeof (fpc_cmd_response_t))
177 {
178 fp_err ("%s recv evt data length (%ld) exceeds buffer size (%ld)",
179 G_STRFUNC, transfer->actual_length, sizeof (fpc_cmd_response_t));
180 fpi_ssm_mark_failed (transfer->ssm,
181 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
182 return;
183 }
184
185 37 data->resp_len = transfer->actual_length;
186
187
1/2
✓ Branch 42 → 43 taken 37 times.
✗ Branch 42 → 44 not taken.
37 if (data->callback)
188 37 data->callback (self, transfer->buffer, NULL);
189
190 37 fpi_ssm_mark_completed (transfer->ssm);
191 37 return;
192 }
193 }
194
1/2
✓ Branch 46 → 47 taken 22 times.
✗ Branch 46 → 56 not taken.
22 else if (data->cmdtype == FPC_CMDTYPE_FROM_DEVICE)
195 {
196
1/2
✗ Branch 47 → 48 not taken.
✓ Branch 47 → 52 taken 22 times.
22 if (transfer->actual_length == 0)
197 {
198 fp_err ("%s Expect data but actual_length = 0", G_STRFUNC);
199 fpi_ssm_mark_failed (transfer->ssm,
200 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
201 return;
202 }
203
204 22 data->resp_len = transfer->actual_length;
205
206
1/2
✓ Branch 52 → 53 taken 22 times.
✗ Branch 52 → 54 not taken.
22 if (data->callback)
207 22 data->callback (self, transfer->buffer, NULL);
208
209 22 fpi_ssm_mark_completed (transfer->ssm);
210 22 return;
211 }
212 else
213 {
214 fp_err ("%s incorrect cmdtype (%x) ", G_STRFUNC, data->cmdtype);
215 fpi_ssm_mark_failed (transfer->ssm,
216 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
217 return;
218 }
219
220 /* should not run here... */
221 fpi_ssm_mark_failed (transfer->ssm,
222 fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
223 }
224
225 static void
226 66 fpc_send_ctrl_cmd (FpDevice *dev)
227 {
228 66 FpiUsbTransfer *transfer = NULL;
229 66 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (dev);
230 66 CommandData *cmd_data = fpi_ssm_get_data (self->cmd_ssm);
231 66 FpcCmdType cmdtype = FPC_CMDTYPE_UNKNOWN;
232
233
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 7 taken 66 times.
66 if (!cmd_data)
234 {
235 fp_err ("%s No cmd_data is set ", G_STRFUNC);
236 fpi_ssm_mark_failed (self->cmd_ssm,
237 fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
238 }
239
240 66 cmdtype = cmd_data->cmdtype;
241
242
4/4
✓ Branch 7 → 8 taken 44 times.
✓ Branch 7 → 17 taken 22 times.
✓ Branch 8 → 9 taken 24 times.
✓ Branch 8 → 13 taken 20 times.
66 if ((cmdtype != FPC_CMDTYPE_FROM_DEVICE) && cmd_data->data_len &&
243
1/2
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 13 taken 24 times.
24 (cmd_data->data == NULL))
244 {
245 fp_err ("%s data buffer is null but len is not! ", G_STRFUNC);
246 fpi_ssm_mark_failed (self->cmd_ssm,
247 fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
248 }
249
250
1/2
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 17 taken 44 times.
44 if (cmdtype == FPC_CMDTYPE_UNKNOWN)
251 {
252 fp_err ("%s unknown cmd type ", G_STRFUNC);
253 fpi_ssm_mark_failed (self->cmd_ssm,
254 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
255 }
256
257 66 fp_dbg ("%s CMD: 0x%x, value: 0x%x, index: %x type: %d", G_STRFUNC,
258 cmd_data->request, cmd_data->value, cmd_data->index, cmdtype);
259
260 66 transfer = fpi_usb_transfer_new (dev);
261 66 fpi_usb_transfer_fill_control (transfer,
262 ((cmdtype == FPC_CMDTYPE_FROM_DEVICE) ?
263 (G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST) :
264 (G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE)),
265 G_USB_DEVICE_REQUEST_TYPE_VENDOR,
266 G_USB_DEVICE_RECIPIENT_DEVICE,
267 cmd_data->request,
268 cmd_data->value,
269 cmd_data->index,
270 cmd_data->data_len);
271
272 66 transfer->ssm = self->cmd_ssm;
273
2/2
✓ Branch 20 → 21 taken 44 times.
✓ Branch 20 → 24 taken 22 times.
66 if (cmdtype != FPC_CMDTYPE_FROM_DEVICE &&
274
2/2
✓ Branch 21 → 22 taken 24 times.
✓ Branch 21 → 24 taken 20 times.
44 cmd_data->data != NULL &&
275
1/2
✓ Branch 22 → 23 taken 24 times.
✗ Branch 22 → 24 not taken.
24 cmd_data->data_len != 0)
276 24 memcpy (transfer->buffer, cmd_data->data, cmd_data->data_len);
277
278 66 fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL,
279 fpc_cmd_receive_cb,
280 fpi_ssm_get_data (transfer->ssm));
281 66 }
282
283 static void
284 66 fpc_cmd_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
285 {
286 66 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (dev);
287 66 CommandData *data;
288
289 66 self->cmd_ssm = NULL;
290 /* Notify about the SSM failure from here instead. */
291
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 7 taken 66 times.
66 if (error)
292 {
293 fp_err ("%s error: %s ", G_STRFUNC, error->message);
294 data = fpi_ssm_get_data (ssm);
295 if (data->callback)
296 data->callback (self, NULL, error);
297 }
298 66 }
299
300 static void
301 103 fpc_cmd_run_state (FpiSsm *ssm,
302 FpDevice *dev)
303 {
304 103 FpiUsbTransfer *transfer = NULL;
305 103 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (dev);
306
307
2/5
✓ Branch 3 → 4 taken 66 times.
✓ Branch 3 → 6 taken 37 times.
✗ Branch 3 → 11 not taken.
✗ Branch 3 → 15 not taken.
✗ Branch 3 → 19 not taken.
103 switch (fpi_ssm_get_cur_state (ssm))
308 {
309 66 case FPC_CMD_SEND:
310 66 fpc_send_ctrl_cmd (dev);
311 66 break;
312
313 37 case FPC_CMD_GET_DATA:
314 37 transfer = fpi_usb_transfer_new (dev);
315 37 transfer->ssm = ssm;
316 37 fpi_usb_transfer_fill_bulk (transfer, EP_IN, EP_IN_MAX_BUF_SIZE);
317 37 fpi_usb_transfer_submit (transfer,
318 self->cmd_data_timeout,
319 self->interrupt_cancellable,
320 fpc_cmd_receive_cb,
321 fpi_ssm_get_data (ssm));
322 37 break;
323
324 case FPC_CMD_SUSPENDED:
325 transfer = fpi_usb_transfer_new (dev);
326 transfer->ssm = ssm;
327 fpi_usb_transfer_fill_control (transfer,
328 G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
329 G_USB_DEVICE_REQUEST_TYPE_VENDOR,
330 G_USB_DEVICE_RECIPIENT_DEVICE,
331 FPC_CMD_INDICATE_S_STATE,
332 FPC_HOST_MS_SX,
333 0,
334 0);
335
336 fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL,
337 fpc_suspend_resume_cb, NULL);
338 break;
339
340 case FPC_CMD_RESUME:
341 transfer = fpi_usb_transfer_new (dev);
342 transfer->ssm = ssm;
343 fpi_usb_transfer_fill_control (transfer,
344 G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
345 G_USB_DEVICE_REQUEST_TYPE_VENDOR,
346 G_USB_DEVICE_RECIPIENT_DEVICE,
347 FPC_CMD_INDICATE_S_STATE,
348 FPC_HOST_MS_S0,
349 0,
350 0);
351
352 fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL,
353 fpc_suspend_resume_cb, NULL);
354 break;
355 }
356
357 103 }
358
359 static void
360 66 fpc_sensor_cmd (FpiDeviceFpcMoc *self,
361 gboolean wait_data_delay,
362 CommandData *cmd_data)
363 {
364 66 CommandData *data = NULL;
365
366
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 66 times.
66 g_return_if_fail (cmd_data);
367
1/2
✓ Branch 4 → 5 taken 66 times.
✗ Branch 4 → 7 not taken.
66 g_return_if_fail (cmd_data->cmdtype != FPC_CMDTYPE_UNKNOWN);
368
369 66 data = g_memdup2 (cmd_data, sizeof (CommandData));
370
371
2/2
✓ Branch 6 → 8 taken 17 times.
✓ Branch 6 → 9 taken 49 times.
66 g_clear_object (&self->interrupt_cancellable);
372
373
2/2
✓ Branch 9 → 10 taken 17 times.
✓ Branch 9 → 12 taken 49 times.
66 if (wait_data_delay)
374 {
375 17 self->cmd_data_timeout = 0;
376 17 self->interrupt_cancellable = g_cancellable_new ();
377 }
378 else
379 {
380 49 self->cmd_data_timeout = DATA_TIMEOUT;
381 }
382
383
1/2
✓ Branch 13 → 14 taken 66 times.
✗ Branch 13 → 17 not taken.
66 g_assert (self->cmd_ssm == NULL);
384 66 self->cmd_ssm = fpi_ssm_new (FP_DEVICE (self),
385 fpc_cmd_run_state,
386 FPC_CMD_NUM_STATES);
387
388 66 fpi_ssm_set_data (self->cmd_ssm, data, g_free);
389 66 fpi_ssm_start (self->cmd_ssm, fpc_cmd_ssm_done);
390 }
391
392 static void
393 1 fpc_dev_release_interface (FpiDeviceFpcMoc *self,
394 GError *error)
395 {
396 1 g_autoptr(GError) release_error = NULL;
397
398 /* Release usb interface */
399 1 g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (self)),
400 0, 0, &release_error);
401 /* Retain passed error if set, otherwise propagate error from release. */
402
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 9 taken 1 time.
1 if (error)
403 {
404 fpi_device_close_complete (FP_DEVICE (self), error);
405 return;
406 }
407
408 /* Notify close complete */
409
1/2
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 1 time.
1 fpi_device_close_complete (FP_DEVICE (self), g_steal_pointer (&release_error));
410 }
411
412 static gboolean
413 57 check_data (void *data, GError **error)
414 {
415
1/2
✓ Branch 2 → 3 taken 57 times.
✗ Branch 2 → 7 not taken.
57 if (*error != NULL)
416 return FALSE;
417
418
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 7 taken 57 times.
57 if (data == NULL)
419 {
420 g_propagate_error (error,
421 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
422 return FALSE;
423 }
424
425 return TRUE;
426 }
427
428 static void
429 36 fpc_evt_cb (FpiDeviceFpcMoc *self,
430 void *data,
431 GError *error)
432 {
433 36 FpiByteReader reader;
434 36 guint32 cmdid;
435 36 guint32 evt_length;
436 36 guint32 evt_status;
437
438
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 6 taken 36 times.
36 if (!check_data (data, &error))
439 {
440 fp_err ("%s error: %s", G_STRFUNC, error->message);
441 fpi_ssm_mark_failed (self->task_ssm, error);
442 return;
443 }
444
445 36 fpi_byte_reader_init (&reader, data, EP_IN_MAX_BUF_SIZE);
446
447
1/2
✓ Branch 7 → 8 taken 36 times.
✗ Branch 7 → 12 not taken.
36 if (!fpi_byte_reader_get_uint32_le (&reader, &cmdid) ||
448
1/2
✓ Branch 9 → 10 taken 36 times.
✗ Branch 9 → 12 not taken.
36 !fpi_byte_reader_get_uint32_le (&reader, &evt_length))
449 {
450 fpi_ssm_mark_failed (self->task_ssm,
451 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
452 return;
453 }
454
455
1/2
✓ Branch 11 → 15 taken 36 times.
✗ Branch 11 → 16 not taken.
36 if (!fpi_byte_reader_get_uint32_le (&reader, &evt_status))
456 {
457 fpi_ssm_mark_failed (self->task_ssm,
458 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
459 return;
460 }
461
462
4/5
✓ Branch 15 → 19 taken 1 time.
✓ Branch 15 → 34 taken 1 time.
✓ Branch 15 → 50 taken 17 times.
✓ Branch 15 → 56 taken 17 times.
✗ Branch 15 → 58 not taken.
36 switch (cmdid)
463 {
464 1 case FPC_EVT_FID_DATA:
465 {
466 1 gint enum_status;
467 1 guint32 num_ids;
468
469
1/2
✓ Branch 20 → 21 taken 1 time.
✗ Branch 20 → 25 not taken.
1 if (!fpi_byte_reader_get_int32_le (&reader, &enum_status) ||
470
1/2
✓ Branch 22 → 23 taken 1 time.
✗ Branch 22 → 25 not taken.
1 !fpi_byte_reader_get_uint32_le (&reader, &num_ids))
471 {
472 fpi_ssm_mark_failed (self->task_ssm,
473 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
474 return;
475 }
476
477 1 fp_dbg ("%s Enum Fids: status = %d, NumFids = %d", G_STRFUNC,
478 enum_status, num_ids);
479
2/4
✓ Branch 24 → 27 taken 1 time.
✗ Branch 24 → 28 not taken.
✗ Branch 27 → 28 not taken.
✓ Branch 27 → 31 taken 1 time.
1 if (enum_status || (num_ids > FPC_TEMPLATES_MAX))
480 {
481 fpi_ssm_mark_failed (self->task_ssm,
482 fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID,
483 "Get Fids failed"));
484 return;
485 }
486 }
487 1 break;
488
489 1 case FPC_EVT_INIT_RESULT:
490 {
491 1 guint16 sensor;
492 1 guint16 hw_id;
493 1 guint16 img_w;
494 1 guint16 img_h;
495 1 const guint8 *fw_version;
496
497
1/2
✓ Branch 35 → 36 taken 1 time.
✗ Branch 35 → 47 not taken.
1 if (!fpi_byte_reader_get_uint16_le (&reader, &sensor) ||
498
1/2
✓ Branch 37 → 38 taken 1 time.
✗ Branch 37 → 47 not taken.
1 !fpi_byte_reader_get_uint16_le (&reader, &hw_id) ||
499
1/2
✓ Branch 39 → 40 taken 1 time.
✗ Branch 39 → 47 not taken.
1 !fpi_byte_reader_get_uint16_le (&reader, &img_w) ||
500
1/2
✓ Branch 41 → 42 taken 1 time.
✗ Branch 41 → 47 not taken.
1 !fpi_byte_reader_get_uint16_le (&reader, &img_h) ||
501
1/2
✓ Branch 43 → 44 taken 1 time.
✗ Branch 43 → 47 not taken.
1 !fpi_byte_reader_get_data (&reader, MAX_FW_VERSION_STR_LEN, &fw_version))
502 {
503 fpi_ssm_mark_failed (self->task_ssm,
504 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
505 return;
506 }
507
508 1 fp_dbg ("%s INIT: status=%d, Sensor = %d, HWID = 0x%04X, WxH = %d x %d", G_STRFUNC,
509 evt_status, sensor, hw_id, img_w, img_h);
510
511 1 fp_dbg ("%s INIT: FW version: %s", G_STRFUNC, (const gchar *) fw_version);
512 }
513 1 break;
514
515 17 case FPC_EVT_FINGER_DWN:
516 17 fp_dbg ("%s Got finger down event (%d)", G_STRFUNC, evt_status);
517 17 fpi_device_report_finger_status_changes (FP_DEVICE (self),
518 FP_FINGER_STATUS_PRESENT,
519 FP_FINGER_STATUS_NONE);
520
1/2
✗ Branch 52 → 53 not taken.
✓ Branch 52 → 62 taken 17 times.
17 if (evt_status != 0)
521 {
522 /* Redo the current task state if capture failed */
523 fpi_ssm_jump_to_state (self->task_ssm, fpi_ssm_get_cur_state (self->task_ssm));
524 return;
525 }
526 break;
527
528 17 case FPC_EVT_IMG:
529 17 fp_dbg ("%s Got capture event", G_STRFUNC);
530 17 fpi_device_report_finger_status_changes (FP_DEVICE (self),
531 FP_FINGER_STATUS_NONE,
532 FP_FINGER_STATUS_PRESENT);
533 17 break;
534
535 default:
536 fpi_ssm_mark_failed (self->task_ssm,
537 fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
538 "Unknown Evt (0x%x)!", cmdid));
539 return;
540 }
541
542 36 fpi_ssm_next_state (self->task_ssm);
543 }
544
545 static void
546 3 fpc_do_abort_cb (FpiDeviceFpcMoc *self,
547 void *data,
548 GError *error)
549 {
550
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 6 taken 3 times.
3 if (error)
551 {
552 fp_err ("%s error: %s ", G_STRFUNC, error->message);
553 fpi_ssm_mark_failed (self->task_ssm, error);
554 return;
555 }
556
557 3 fp_dbg ("%s Do abort for reasons", G_STRFUNC);
558 3 fpi_ssm_next_state (self->task_ssm);
559 }
560
561 static void
562 fpc_do_cleanup_cb (FpiDeviceFpcMoc *self,
563 void *data,
564 GError *error)
565 {
566 if (error)
567 {
568 fp_err ("%s error: %s ", G_STRFUNC, error->message);
569 fpi_ssm_mark_failed (self->task_ssm, error);
570 return;
571 }
572
573 fp_dbg ("%s Do cleanup for reasons", G_STRFUNC);
574 self->do_cleanup = FALSE;
575 fpi_ssm_next_state (self->task_ssm);
576 }
577
578 static void
579 1 fpc_template_delete_cb (FpiDeviceFpcMoc *self,
580 void *resp,
581 GError *error)
582 {
583 1 FpDevice *device = FP_DEVICE (self);
584
585 1 fpi_device_delete_complete (device, error);
586 1 }
587
588 static gboolean
589 1 parse_print_data (GVariant *data,
590 guint8 *finger,
591 const guint8 **user_id,
592 gsize *user_id_len)
593 {
594 2 g_autoptr(GVariant) user_id_var = NULL;
595
596
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
1 g_return_val_if_fail (data, FALSE);
597
1/2
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 6 not taken.
1 g_return_val_if_fail (finger, FALSE);
598
1/2
✓ Branch 5 → 7 taken 1 time.
✗ Branch 5 → 8 not taken.
1 g_return_val_if_fail (user_id, FALSE);
599
1/2
✓ Branch 7 → 9 taken 1 time.
✗ Branch 7 → 11 not taken.
1 g_return_val_if_fail (user_id_len, FALSE);
600
601 1 *user_id = NULL;
602 1 *user_id_len = 0;
603 1 *finger = FPC_SUBTYPE_NOINFORMATION;
604
605
1/2
✓ Branch 10 → 12 taken 1 time.
✗ Branch 10 → 19 not taken.
1 if (!g_variant_check_format_string (data, "(y@ay)", FALSE))
606 return FALSE;
607
608 1 g_variant_get (data,
609 "(y@ay)",
610 finger,
611 &user_id_var);
612
613 1 *user_id = g_variant_get_fixed_array (user_id_var, user_id_len, 1);
614
615
1/2
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 19 not taken.
1 if (*user_id_len == 0 || *user_id_len > SECURITY_MAX_SID_SIZE)
616 return FALSE;
617
618
2/4
✓ Branch 15 → 16 taken 1 time.
✗ Branch 15 → 19 not taken.
✓ Branch 16 → 17 taken 1 time.
✗ Branch 16 → 19 not taken.
1 if (*user_id_len <= 0 || *user_id[0] == '\0' || *user_id[0] == ' ')
619 return FALSE;
620
621
1/2
✗ Branch 17 → 18 not taken.
✓ Branch 17 → 19 taken 1 time.
1 if (*finger != FPC_SUBTYPE_RESERVED)
622 return FALSE;
623
624 return TRUE;
625 }
626
627 /******************************************************************************
628 *
629 * fpc_template_xxx Function
630 *
631 *****************************************************************************/
632 static FpPrint *
633 3 fpc_print_from_data (FpiDeviceFpcMoc *self, fpc_fid_data_t *fid_data)
634 {
635 3 FpPrint *print = NULL;
636 3 GVariant *data;
637 3 GVariant *uid;
638 3 guint32 identity_size;
639 6 g_autofree gchar *userid = NULL;
640
641 3 identity_size = MIN (fid_data->identity_size, sizeof (fid_data->identity));
642 3 g_warn_if_fail (identity_size <= sizeof (fid_data->identity));
643
644 3 userid = g_strndup ((gchar *) fid_data->identity, identity_size);
645 3 print = fp_print_new (FP_DEVICE (self));
646
647 3 uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
648 fid_data->identity,
649 identity_size,
650 1);
651
652 6 data = g_variant_new ("(y@ay)",
653 3 fid_data->subfactor,
654 uid);
655
656 3 fpi_print_set_type (print, FPI_PRINT_RAW);
657 3 fpi_print_set_device_stored (print, TRUE);
658 3 g_object_set (print, "fpi-data", data, NULL);
659 3 g_object_set (print, "description", userid, NULL);
660 3 fpi_print_fill_from_user_id (print, userid);
661
662 3 return print;
663 }
664
665 static void
666 1 fpc_template_list_cb (FpiDeviceFpcMoc *self,
667 void *data,
668 GError *error)
669 {
670 1 g_autoptr(GPtrArray) list_result = NULL;
671 1 FpDevice *device = FP_DEVICE (self);
672 1 FpiByteReader reader;
673 1 guint32 cmdid;
674 1 guint32 evt_length;
675 1 guint32 evt_status;
676
677
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
1 if (error)
678 {
679 fpi_device_list_complete (FP_DEVICE (self), NULL, error);
680 return;
681 }
682
683
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 7 taken 1 time.
1 if (data == NULL)
684 {
685 fpi_device_list_complete (FP_DEVICE (self),
686 NULL,
687 fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID,
688 "Data is null"));
689 return;
690 }
691
692 1 fpi_byte_reader_init (&reader, data, EP_IN_MAX_BUF_SIZE);
693
694
1/2
✓ Branch 8 → 9 taken 1 time.
✗ Branch 8 → 14 not taken.
1 if (!fpi_byte_reader_get_uint32_le (&reader, &cmdid) ||
695
1/2
✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 14 not taken.
1 !fpi_byte_reader_get_uint32_le (&reader, &evt_length) ||
696
1/2
✓ Branch 12 → 13 taken 1 time.
✗ Branch 12 → 14 not taken.
1 !fpi_byte_reader_get_uint32_le (&reader, &evt_status))
697 {
698 fpi_device_list_complete (FP_DEVICE (self),
699 NULL,
700 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
701 return;
702 }
703
704
1/2
✗ Branch 13 → 16 not taken.
✓ Branch 13 → 18 taken 1 time.
1 if (cmdid != FPC_EVT_FID_DATA)
705 {
706 fpi_device_list_complete (FP_DEVICE (self),
707 NULL,
708 fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID,
709 "Recv evt is incorrect: 0x%x",
710 cmdid));
711 return;
712 }
713
714 {
715 1 gint enum_status;
716 1 guint32 num_ids;
717
718
1/2
✓ Branch 19 → 20 taken 1 time.
✗ Branch 19 → 23 not taken.
1 if (!fpi_byte_reader_get_int32_le (&reader, &enum_status) ||
719
1/2
✓ Branch 21 → 22 taken 1 time.
✗ Branch 21 → 23 not taken.
1 !fpi_byte_reader_get_uint32_le (&reader, &num_ids))
720 {
721 fpi_device_list_complete (FP_DEVICE (self),
722 NULL,
723 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
724 return;
725 }
726
727
1/2
✗ Branch 22 → 26 not taken.
✓ Branch 22 → 29 taken 1 time.
1 if (num_ids > FPC_TEMPLATES_MAX)
728 {
729 fpi_device_list_complete (FP_DEVICE (self),
730 NULL,
731 fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_FULL,
732 "Database is full"));
733 return;
734 }
735
736 1 list_result = g_ptr_array_new_with_free_func (g_object_unref);
737
738
1/2
✗ Branch 30 → 31 not taken.
✓ Branch 30 → 60 taken 1 time.
1 if (num_ids == 0)
739 {
740 fp_info ("Database is empty");
741 fpi_device_list_complete (device,
742 g_steal_pointer (&list_result),
743 NULL);
744 return;
745 }
746
747
2/2
✓ Branch 60 → 34 taken 1 time.
✓ Branch 60 → 61 taken 1 time.
2 for (guint32 n = 0; n < num_ids; n++)
748 {
749 1 FpPrint *print = NULL;
750 1 fpc_fid_data_t fid_data = {0};
751 1 guint8 subfactor;
752 1 guint32 identity_type;
753 1 guint32 identity_size;
754
755
1/2
✓ Branch 35 → 36 taken 1 time.
✗ Branch 35 → 41 not taken.
1 if (!fpi_byte_reader_get_uint8 (&reader, &subfactor) ||
756
1/2
✓ Branch 37 → 38 taken 1 time.
✗ Branch 37 → 41 not taken.
1 !fpi_byte_reader_get_uint32_le (&reader, &identity_type) ||
757
1/2
✓ Branch 39 → 40 taken 1 time.
✗ Branch 39 → 41 not taken.
1 !fpi_byte_reader_get_uint32_le (&reader, &identity_size))
758 {
759 fpi_device_list_complete (FP_DEVICE (self),
760 NULL,
761 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
762 return;
763 }
764
765 1 fid_data.subfactor = subfactor;
766 1 fid_data.identity_type = identity_type;
767 1 fid_data.identity_size = identity_size;
768
769
1/4
✗ Branch 40 → 43 not taken.
✓ Branch 40 → 48 taken 1 time.
✗ Branch 43 → 44 not taken.
✗ Branch 43 → 48 not taken.
1 if ((subfactor != FPC_SUBTYPE_RESERVED) &&
770 (identity_type != FPC_IDENTITY_TYPE_RESERVED))
771 {
772 fp_info ("Incompatible template found (0x%x, 0x%x)",
773 subfactor, identity_type);
774 fpi_byte_reader_skip (&reader, SECURITY_MAX_SID_SIZE);
775 continue;
776 }
777
778
1/2
✗ Branch 49 → 50 not taken.
✓ Branch 49 → 53 taken 1 time.
1 if (!fpi_byte_reader_get_data_static (&reader, fid_data.identity))
779 {
780 fpi_device_list_complete (FP_DEVICE (self),
781 NULL,
782 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
783 return;
784 }
785
786 1 print = fpc_print_from_data (self, &fid_data);
787
788 1 g_ptr_array_add (list_result, g_object_ref_sink (print));
789 }
790 }
791
792 1 fp_info ("Query templates complete!");
793 1 fpi_device_list_complete (device,
794 1 g_steal_pointer (&list_result),
795 NULL);
796 }
797
798 /******************************************************************************
799 *
800 * fpc_enroll_xxxx Function
801 *
802 *****************************************************************************/
803
804 static void
805 1 fpc_enroll_create_cb (FpiDeviceFpcMoc *self,
806 void *data,
807 GError *error)
808 {
809 1 FpiByteReader reader;
810 1 gint32 status;
811
812
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 6 taken 1 time.
1 if (!check_data (data, &error))
813 {
814 fp_err ("%s error: %s ", G_STRFUNC, error->message);
815 fpi_ssm_mark_failed (self->task_ssm, error);
816 return;
817 }
818
819 1 fpi_byte_reader_init (&reader, data, sizeof (FPC_BEGIN_ENROL));
820
821
1/2
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 11 taken 1 time.
1 if (!fpi_byte_reader_get_int32_le (&reader, &status))
822 {
823 fpi_ssm_mark_failed (self->task_ssm,
824 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
825 return;
826 }
827
828
1/2
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 14 taken 1 time.
1 if (status != 0)
829 {
830 error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
831 "End Enroll failed: %d",
832 status);
833 }
834
835
1/2
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 18 taken 1 time.
1 if (error)
836 {
837 fp_err ("%s error: %s ", G_STRFUNC, error->message);
838 fpi_ssm_mark_failed (self->task_ssm, error);
839 return;
840 }
841 else
842 {
843 1 self->do_cleanup = TRUE;
844 1 fpi_ssm_next_state (self->task_ssm);
845 }
846 }
847
848 static void
849 15 fpc_enroll_update_cb (FpiDeviceFpcMoc *self,
850 void *data,
851 GError *error)
852 {
853 15 FpiByteReader reader;
854 15 gint32 status;
855 15 guint32 remaining;
856
857
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 6 taken 15 times.
15 if (!check_data (data, &error))
858 {
859 fp_err ("%s error: %s ", G_STRFUNC, error->message);
860 fpi_ssm_mark_failed (self->task_ssm, error);
861 1 return;
862 }
863
864 15 fpi_byte_reader_init (&reader, data, sizeof (FPC_ENROL));
865
866
1/2
✓ Branch 7 → 8 taken 15 times.
✗ Branch 7 → 12 not taken.
15 if (!fpi_byte_reader_get_int32_le (&reader, &status) ||
867
1/2
✓ Branch 9 → 10 taken 15 times.
✗ Branch 9 → 12 not taken.
15 !fpi_byte_reader_get_uint32_le (&reader, &remaining))
868 {
869 fpi_ssm_mark_failed (self->task_ssm,
870 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
871 return;
872 }
873
874 15 fp_dbg ("Enrol Update status: %d, remaining: %d", status, remaining);
875
3/8
✗ Branch 11 → 15 not taken.
✗ Branch 11 → 17 not taken.
✓ Branch 11 → 19 taken 1 time.
✓ Branch 11 → 22 taken 3 times.
✓ Branch 11 → 33 taken 11 times.
✗ Branch 11 → 37 not taken.
✗ Branch 11 → 40 not taken.
✗ Branch 11 → 43 not taken.
15 switch (status)
876 {
877 case FPC_ENROL_STATUS_FAILED_COULD_NOT_COMPLETE:
878 error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
879 break;
880
881 case FPC_ENROL_STATUS_FAILED_ALREADY_ENROLED:
882 error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_DUPLICATE);
883 break;
884
885 1 case FPC_ENROL_STATUS_COMPLETED:
886 1 self->enroll_stage++;
887 1 fpi_device_enroll_progress (FP_DEVICE (self), self->enroll_stage, NULL, NULL);
888 1 fpi_ssm_jump_to_state (self->task_ssm, FPC_ENROLL_COMPLETE);
889 1 return;
890
891 3 case FPC_ENROL_STATUS_IMAGE_TOO_SIMILAR:
892 3 fp_dbg ("Sample overlapping ratio is too High");
893 /* here should tips remove finger and try again */
894
1/2
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 30 taken 3 times.
3 if (self->max_immobile_stage)
895 {
896 self->immobile_stage++;
897 if (self->immobile_stage > self->max_immobile_stage)
898 {
899 fp_dbg ("Skip similar handle due to customer enrollment %d(%d)",
900 self->immobile_stage, self->max_immobile_stage);
901 /* Skip too similar handle, treat as normal enroll progress. */
902 self->enroll_stage++;
903 fpi_device_enroll_progress (FP_DEVICE (self), self->enroll_stage, NULL, NULL);
904 /* Used for customer enrollment scheme */
905 if (self->enroll_stage >= (self->max_enroll_stage - self->max_immobile_stage))
906 {
907 fpi_ssm_jump_to_state (self->task_ssm, FPC_ENROLL_COMPLETE);
908 return;
909 }
910 break;
911 }
912 }
913 3 fpi_device_enroll_progress (FP_DEVICE (self),
914 self->enroll_stage,
915 NULL,
916 fpi_device_retry_new (FP_DEVICE_RETRY_REMOVE_FINGER));
917 3 break;
918
919 11 case FPC_ENROL_STATUS_PROGRESS:
920 11 self->enroll_stage++;
921 11 fpi_device_enroll_progress (FP_DEVICE (self), self->enroll_stage, NULL, NULL);
922 /* Used for customer enrollment scheme */
923
1/2
✗ Branch 34 → 35 not taken.
✓ Branch 34 → 46 taken 11 times.
11 if (self->enroll_stage >= (self->max_enroll_stage - self->max_immobile_stage))
924 {
925 fpi_ssm_jump_to_state (self->task_ssm, FPC_ENROLL_COMPLETE);
926 return;
927 }
928 break;
929
930 case FPC_ENROL_STATUS_IMAGE_LOW_COVERAGE:
931 fpi_device_enroll_progress (FP_DEVICE (self),
932 self->enroll_stage,
933 NULL,
934 fpi_device_retry_new (FP_DEVICE_RETRY_CENTER_FINGER));
935 break;
936
937 case FPC_ENROL_STATUS_IMAGE_LOW_QUALITY:
938 fpi_device_enroll_progress (FP_DEVICE (self),
939 self->enroll_stage,
940 NULL,
941 fpi_device_retry_new (FP_DEVICE_RETRY_TOO_SHORT));
942 break;
943
944 default:
945 fp_err ("%s Unknown result code: %d ", G_STRFUNC, status);
946 error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
947 "Enroll failed: %d",
948 status);
949 break;
950 }
951
952
1/2
✗ Branch 46 → 47 not taken.
✓ Branch 46 → 50 taken 14 times.
14 if (error)
953 {
954 fp_err ("%s error: %s ", G_STRFUNC, error->message);
955 fpi_ssm_mark_failed (self->task_ssm, error);
956 return;
957 }
958 else
959 {
960 14 fpi_ssm_jump_to_state (self->task_ssm, FPC_ENROLL_CAPTURE);
961 }
962 }
963
964 static void
965 1 fpc_enroll_complete_cb (FpiDeviceFpcMoc *self,
966 void *data,
967 GError *error)
968 {
969 1 FpiByteReader reader;
970 1 gint32 status;
971 1 guint32 fid;
972
973 1 self->do_cleanup = FALSE;
974
975
1/2
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 14 not taken.
1 if (check_data (data, &error))
976 {
977 1 fpi_byte_reader_init (&reader, data, sizeof (FPC_END_ENROL));
978
979
1/2
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 9 not taken.
1 if (!fpi_byte_reader_get_int32_le (&reader, &status) ||
980
1/2
✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 9 not taken.
1 !fpi_byte_reader_get_uint32_le (&reader, &fid))
981 {
982 fpi_ssm_mark_failed (self->task_ssm,
983 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
984 return;
985 }
986
987
1/2
✗ Branch 8 → 11 not taken.
✓ Branch 8 → 13 taken 1 time.
1 if (status != 0)
988 {
989 error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
990 "End Enroll failed: %d",
991 status);
992 }
993 else
994 {
995 1 fp_dbg ("Enrol End status: %d, fid: 0x%x",
996 status, fid);
997 }
998 }
999
1000
1/2
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 18 taken 1 time.
1 if (error)
1001 {
1002 fp_err ("%s error: %s ", G_STRFUNC, error->message);
1003 fpi_ssm_mark_failed (self->task_ssm, error);
1004 return;
1005 }
1006 else
1007 {
1008 1 fpi_ssm_next_state (self->task_ssm);
1009 }
1010 }
1011
1012 static void
1013 1 fpc_enroll_check_duplicate_cb (FpiDeviceFpcMoc *self,
1014 void *data,
1015 GError *error)
1016 {
1017 1 FpiByteReader reader;
1018
1019
1/2
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 24 not taken.
1 if (check_data (data, &error))
1020 {
1021 1 gint32 status;
1022 1 guint32 identity_type;
1023 1 guint32 identity_size;
1024 1 guint32 subfactor;
1025
1026 1 fpi_byte_reader_init (&reader, data, sizeof (FPC_IDENTIFY));
1027
1028
1/2
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 14 not taken.
1 if (!fpi_byte_reader_get_int32_le (&reader, &status) ||
1029
1/2
✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 14 not taken.
1 !fpi_byte_reader_get_uint32_le (&reader, &identity_type) ||
1030
1/2
✓ Branch 8 → 9 taken 1 time.
✗ Branch 8 → 14 not taken.
1 !fpi_byte_reader_skip (&reader, 4) ||
1031
1/2
✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 14 not taken.
1 !fpi_byte_reader_get_uint32_le (&reader, &identity_size) ||
1032
1/2
✓ Branch 12 → 13 taken 1 time.
✗ Branch 12 → 14 not taken.
1 !fpi_byte_reader_get_uint32_le (&reader, &subfactor))
1033 {
1034 fpi_ssm_mark_failed (self->task_ssm,
1035 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
1036 return;
1037 }
1038
1039
1/4
✗ Branch 13 → 17 not taken.
✓ Branch 13 → 23 taken 1 time.
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 23 not taken.
1 if ((status == 0) && (subfactor == FPC_SUBTYPE_RESERVED) &&
1040 (identity_type == FPC_IDENTITY_TYPE_RESERVED) &&
1041 (identity_size <= SECURITY_MAX_SID_SIZE))
1042 {
1043 fp_info ("%s Got a duplicated template", G_STRFUNC);
1044 error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_DUPLICATE);
1045 }
1046 }
1047
1048
1/2
✗ Branch 24 → 25 not taken.
✓ Branch 24 → 27 taken 1 time.
1 if (error)
1049 {
1050 fp_err ("%s error: %s ", G_STRFUNC, error->message);
1051 fpi_ssm_mark_failed (self->task_ssm, error);
1052 return;
1053 }
1054 else
1055 {
1056 1 fpi_ssm_next_state (self->task_ssm);
1057 }
1058
1059 }
1060
1061 static void
1062 1 fpc_enroll_bindid_cb (FpiDeviceFpcMoc *self,
1063 void *data,
1064 GError *error)
1065 {
1066
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 6 taken 1 time.
1 if (error)
1067 {
1068 fp_err ("%s error: %s ", G_STRFUNC, error->message);
1069 fpi_ssm_mark_failed (self->task_ssm, error);
1070 return;
1071 }
1072
1073 1 fpi_ssm_next_state (self->task_ssm);
1074 }
1075
1076 static void
1077 1 fpc_enroll_commit_cb (FpiDeviceFpcMoc *self,
1078 void *data,
1079 GError *error)
1080 {
1081
1/2
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 13 not taken.
1 if (check_data (data, &error))
1082 {
1083 1 FpiByteReader reader;
1084 1 gint32 result;
1085
1086 1 fpi_byte_reader_init (&reader, data, sizeof (gint32));
1087
1088
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 9 taken 1 time.
1 if (!fpi_byte_reader_get_int32_le (&reader, &result))
1089 {
1090 fpi_ssm_mark_failed (self->task_ssm,
1091 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
1092 return;
1093 }
1094
1095
1/2
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 12 taken 1 time.
1 if (result != 0)
1096 {
1097 error = fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_FULL,
1098 "Save DB failed: %d",
1099 result);
1100 }
1101 }
1102
1103
1/2
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 17 taken 1 time.
1 if (error)
1104 {
1105 fp_err ("%s error: %s ", G_STRFUNC, error->message);
1106 fpi_ssm_mark_failed (self->task_ssm, error);
1107 return;
1108 }
1109 else
1110 {
1111 1 fpi_ssm_mark_completed (self->task_ssm);
1112 }
1113 }
1114
1115
1116 static void
1117 53 fpc_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
1118 {
1119 53 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device);
1120 53 CommandData cmd_data = {0};
1121 53 gsize recv_data_len = 0;
1122
1123
11/12
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 12 taken 1 time.
✓ Branch 3 → 14 taken 15 times.
✓ Branch 3 → 19 taken 15 times.
✓ Branch 3 → 21 taken 15 times.
✓ Branch 3 → 23 taken 1 time.
✓ Branch 3 → 25 taken 1 time.
✓ Branch 3 → 27 taken 1 time.
✓ Branch 3 → 45 taken 1 time.
✓ Branch 3 → 47 taken 1 time.
✓ Branch 3 → 49 taken 1 time.
✗ Branch 3 → 52 not taken.
53 switch (fpi_ssm_get_cur_state (ssm))
1124 {
1125 1 case FPC_ENROLL_ENUM:
1126 {
1127 1 guint8 buf[sizeof (FPC_FID_DATA)] = {0};
1128 1 FpiByteWriter writer;
1129
1130 1 fpi_byte_writer_init_with_data (&writer, buf, sizeof (buf), FALSE);
1131 1 fpi_byte_writer_put_uint32_le (&writer, FPC_IDENTITY_TYPE_WILDCARD);
1132 1 fpi_byte_writer_put_uint32_le (&writer, 16);
1133 1 fpi_byte_writer_put_uint32_le (&writer, sizeof (guint32));
1134 1 fpi_byte_writer_put_uint32_le (&writer, FPC_SUBTYPE_ANY);
1135 1 fpi_byte_writer_put_uint32_le (&writer, FPC_IDENTITY_WILDCARD);
1136
1137 1 cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE_EVTDATA;
1138 1 cmd_data.request = FPC_CMD_ENUM;
1139 1 cmd_data.value = 0x0;
1140 1 cmd_data.index = 0x0;
1141 1 cmd_data.data = buf;
1142 1 cmd_data.data_len = sizeof (buf);
1143 1 cmd_data.callback = fpc_evt_cb;
1144
1145 1 fpc_sensor_cmd (self, FALSE, &cmd_data);
1146 }
1147 1 break;
1148
1149 1 case FPC_ENROLL_CREATE:
1150 {
1151 1 recv_data_len = sizeof (FPC_BEGIN_ENROL);
1152 1 cmd_data.cmdtype = FPC_CMDTYPE_FROM_DEVICE;
1153 1 cmd_data.request = FPC_CMD_BEGIN_ENROL;
1154 1 cmd_data.value = 0x0;
1155 1 cmd_data.index = 0x0;
1156 1 cmd_data.data = NULL;
1157 1 cmd_data.data_len = recv_data_len;
1158 1 cmd_data.callback = fpc_enroll_create_cb;
1159
1160 1 fpc_sensor_cmd (self, FALSE, &cmd_data);
1161 }
1162 1 break;
1163
1164 15 case FPC_ENROLL_CAPTURE:
1165 {
1166 15 guint8 buf[4];
1167 15 FpiByteWriter writer;
1168
1169 15 fpi_byte_writer_init_with_data (&writer, buf, sizeof (buf), FALSE);
1170 15 fpi_byte_writer_put_uint32_le (&writer, FPC_CAPTUREID_RESERVED);
1171
1172 15 fpi_device_report_finger_status_changes (device,
1173 FP_FINGER_STATUS_NEEDED,
1174 FP_FINGER_STATUS_NONE);
1175 15 cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE_EVTDATA;
1176 15 cmd_data.request = FPC_CMD_ARM;
1177 15 cmd_data.value = 0x1;
1178 15 cmd_data.index = 0x0;
1179 15 cmd_data.data = buf;
1180 15 cmd_data.data_len = sizeof (buf);
1181 15 cmd_data.callback = fpc_evt_cb;
1182
1183 15 fpc_sensor_cmd (self, TRUE, &cmd_data);
1184 }
1185 15 break;
1186
1187 15 case FPC_ENROLL_GET_IMG:
1188 {
1189 15 cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE_EVTDATA;
1190 15 cmd_data.request = FPC_CMD_GET_IMG;
1191 15 cmd_data.value = 0x0;
1192 15 cmd_data.index = 0x0;
1193 15 cmd_data.data = NULL;
1194 15 cmd_data.data_len = 0;
1195 15 cmd_data.callback = fpc_evt_cb;
1196
1197 15 fpc_sensor_cmd (self, FALSE, &cmd_data);
1198 }
1199 15 break;
1200
1201 15 case FPC_ENROLL_UPDATE:
1202 {
1203 15 recv_data_len = sizeof (FPC_ENROL);
1204 15 cmd_data.cmdtype = FPC_CMDTYPE_FROM_DEVICE;
1205 15 cmd_data.request = FPC_CMD_ENROL;
1206 15 cmd_data.value = 0x0;
1207 15 cmd_data.index = 0x0;
1208 15 cmd_data.data = NULL;
1209 15 cmd_data.data_len = recv_data_len;
1210 15 cmd_data.callback = fpc_enroll_update_cb;
1211
1212 15 fpc_sensor_cmd (self, FALSE, &cmd_data);
1213 }
1214 15 break;
1215
1216 1 case FPC_ENROLL_COMPLETE:
1217 {
1218 1 recv_data_len = sizeof (FPC_END_ENROL);
1219 1 cmd_data.cmdtype = FPC_CMDTYPE_FROM_DEVICE;
1220 1 cmd_data.request = FPC_CMD_END_ENROL;
1221 1 cmd_data.value = 0x0;
1222 1 cmd_data.index = 0x0;
1223 1 cmd_data.data = NULL;
1224 1 cmd_data.data_len = recv_data_len;
1225 1 cmd_data.callback = fpc_enroll_complete_cb;
1226
1227 1 fpc_sensor_cmd (self, FALSE, &cmd_data);
1228 }
1229 1 break;
1230
1231 1 case FPC_ENROLL_CHECK_DUPLICATE:
1232 {
1233 1 recv_data_len = sizeof (FPC_IDENTIFY);
1234 1 cmd_data.cmdtype = FPC_CMDTYPE_FROM_DEVICE;
1235 1 cmd_data.request = FPC_CMD_IDENTIFY;
1236 1 cmd_data.value = 0x0;
1237 1 cmd_data.index = 0x0;
1238 1 cmd_data.data = NULL;
1239 1 cmd_data.data_len = recv_data_len;
1240 1 cmd_data.callback = fpc_enroll_check_duplicate_cb;
1241
1242 1 fpc_sensor_cmd (self, FALSE, &cmd_data);
1243 }
1244 1 break;
1245
1246 1 case FPC_ENROLL_BINDID:
1247 {
1248 1 guint8 buf[sizeof (FPC_FID_DATA)] = {0};
1249 1 FpiByteWriter writer;
1250 1 FpPrint *print = NULL;
1251 1 GVariant *fpi_data = NULL;
1252 1 GVariant *uid = NULL;
1253 1 guint finger = FPC_SUBTYPE_RESERVED;
1254 2 g_autofree gchar *user_id = NULL;
1255 1 gssize user_id_len;
1256
1257 1 fpi_device_get_enroll_data (device, &print);
1258
1259 1 user_id = fpi_print_generate_user_id (print);
1260
1261 1 user_id_len = strlen (user_id);
1262 1 user_id_len = MIN (SECURITY_MAX_SID_SIZE, user_id_len);
1263
1264 1 uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
1265 user_id,
1266 user_id_len,
1267 1);
1268 1 fpi_data = g_variant_new ("(y@ay)",
1269 finger,
1270 uid);
1271
1272 1 fpi_print_set_type (print, FPI_PRINT_RAW);
1273 1 fpi_print_set_device_stored (print, TRUE);
1274 1 g_object_set (print, "fpi-data", fpi_data, NULL);
1275 1 g_object_set (print, "description", user_id, NULL);
1276
1277 1 fp_dbg ("user_id: %s, finger: 0x%x", user_id, finger);
1278
1279 1 fpi_byte_writer_init_with_data (&writer, buf, sizeof (buf), FALSE);
1280 1 fpi_byte_writer_put_uint32_le (&writer, FPC_IDENTITY_TYPE_RESERVED);
1281 1 fpi_byte_writer_put_uint32_le (&writer, 16);
1282 1 fpi_byte_writer_put_uint32_le (&writer, user_id_len);
1283 1 fpi_byte_writer_put_uint32_le (&writer, finger);
1284 1 fpi_byte_writer_put_data (&writer, (const guint8 *) user_id, user_id_len);
1285
1286 1 cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE;
1287 1 cmd_data.request = FPC_CMD_BIND_IDENTITY;
1288 1 cmd_data.value = 0x0;
1289 1 cmd_data.index = 0x0;
1290 1 cmd_data.data = buf;
1291 1 cmd_data.data_len = sizeof (buf);
1292 1 cmd_data.callback = fpc_enroll_bindid_cb;
1293
1294 1 fpc_sensor_cmd (self, FALSE, &cmd_data);
1295 }
1296 1 break;
1297
1298 1 case FPC_ENROLL_COMMIT:
1299 {
1300 1 recv_data_len = sizeof (gint32);
1301 1 cmd_data.cmdtype = FPC_CMDTYPE_FROM_DEVICE;
1302 1 cmd_data.request = FPC_CMD_STORE_DB;
1303 1 cmd_data.value = 0x0;
1304 1 cmd_data.index = 0x0;
1305 1 cmd_data.data = NULL;
1306 1 cmd_data.data_len = recv_data_len;
1307 1 cmd_data.callback = fpc_enroll_commit_cb;
1308
1309 1 fpc_sensor_cmd (self, FALSE, &cmd_data);
1310 }
1311 1 break;
1312
1313 1 case FPC_ENROLL_DICARD:
1314 {
1315 1 cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE;
1316 1 cmd_data.request = FPC_CMD_ABORT;
1317 1 cmd_data.value = 0x1;
1318 1 cmd_data.index = 0x0;
1319 1 cmd_data.data = NULL;
1320 1 cmd_data.data_len = 0;
1321 1 cmd_data.callback = fpc_do_abort_cb;
1322 1 fpc_sensor_cmd (self, FALSE, &cmd_data);
1323 }
1324 1 break;
1325
1326 1 case FPC_ENROLL_CLEANUP:
1327 {
1328
1/2
✗ Branch 49 → 50 not taken.
✓ Branch 49 → 51 taken 1 time.
1 if (self->do_cleanup == TRUE)
1329 {
1330 recv_data_len = sizeof (FPC_END_ENROL);
1331 cmd_data.cmdtype = FPC_CMDTYPE_FROM_DEVICE;
1332 cmd_data.request = FPC_CMD_END_ENROL;
1333 cmd_data.value = 0x0;
1334 cmd_data.index = 0x0;
1335 cmd_data.data = NULL;
1336 cmd_data.data_len = recv_data_len;
1337 cmd_data.callback = fpc_do_cleanup_cb;
1338 fpc_sensor_cmd (self, FALSE, &cmd_data);
1339 }
1340 else
1341 {
1342 1 fpi_ssm_next_state (self->task_ssm);
1343 }
1344 }
1345 break;
1346 }
1347 53 }
1348
1349 static void
1350 1 fpc_enroll_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
1351 {
1352 1 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (dev);
1353 1 FpPrint *print = NULL;
1354
1355 1 fp_info ("Enrollment complete!");
1356
1357
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 1 time.
1 if (error)
1358 {
1359 fpi_device_enroll_complete (dev, NULL, g_steal_pointer (&error));
1360 self->task_ssm = NULL;
1361 return;
1362 }
1363
1364 1 fpi_device_get_enroll_data (FP_DEVICE (self), &print);
1365 1 fpi_device_enroll_complete (FP_DEVICE (self), g_object_ref (print), NULL);
1366 1 self->task_ssm = NULL;
1367 }
1368
1369 /******************************************************************************
1370 *
1371 * fpc_identify_xxx function
1372 *
1373 *****************************************************************************/
1374
1375 static void
1376 2 fpc_identify_cb (FpiDeviceFpcMoc *self,
1377 void *data,
1378 GError *error)
1379 {
1380 2 g_autoptr(GPtrArray) templates = NULL;
1381 2 FpDevice *device = FP_DEVICE (self);
1382 2 FpiByteReader reader;
1383 2 gint32 status;
1384 2 guint32 identity_type;
1385 2 guint32 identity_size;
1386 2 guint32 subfactor;
1387
1388
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 6 taken 2 times.
2 if (!check_data (data, &error))
1389 {
1390 fp_err ("%s error: %s ", G_STRFUNC, error->message);
1391 fpi_ssm_mark_failed (self->task_ssm, error);
1392 return;
1393 }
1394
1395 2 fpi_byte_reader_init (&reader, data, sizeof (FPC_IDENTIFY));
1396
1397
1/2
✓ Branch 7 → 8 taken 2 times.
✗ Branch 7 → 16 not taken.
2 if (!fpi_byte_reader_get_int32_le (&reader, &status) ||
1398
1/2
✓ Branch 9 → 10 taken 2 times.
✗ Branch 9 → 16 not taken.
2 !fpi_byte_reader_get_uint32_le (&reader, &identity_type) ||
1399
1/2
✓ Branch 10 → 11 taken 2 times.
✗ Branch 10 → 16 not taken.
2 !fpi_byte_reader_skip (&reader, 4) ||
1400
1/2
✓ Branch 12 → 13 taken 2 times.
✗ Branch 12 → 16 not taken.
2 !fpi_byte_reader_get_uint32_le (&reader, &identity_size) ||
1401
1/2
✓ Branch 14 → 15 taken 2 times.
✗ Branch 14 → 16 not taken.
2 !fpi_byte_reader_get_uint32_le (&reader, &subfactor))
1402 {
1403 fpi_ssm_mark_failed (self->task_ssm,
1404 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
1405 return;
1406 }
1407
1408
2/4
✓ Branch 15 → 19 taken 2 times.
✗ Branch 15 → 37 not taken.
✓ Branch 19 → 20 taken 2 times.
✗ Branch 19 → 37 not taken.
2 if ((status == 0) && (subfactor == FPC_SUBTYPE_RESERVED) &&
1409
1/2
✓ Branch 20 → 21 taken 2 times.
✗ Branch 20 → 37 not taken.
2 (identity_type == FPC_IDENTITY_TYPE_RESERVED) &&
1410
1/2
✓ Branch 21 → 22 taken 2 times.
✗ Branch 21 → 37 not taken.
2 (identity_size <= SECURITY_MAX_SID_SIZE))
1411 {
1412 2 FpPrint *match = NULL;
1413 2 fpc_fid_data_t fid_data = {0};
1414
1415 2 fid_data.subfactor = subfactor;
1416 2 fid_data.identity_type = identity_type;
1417 2 fid_data.identity_size = identity_size;
1418
1419
1/2
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 26 taken 2 times.
2 if (!(fpi_byte_reader_get_data_static) (&reader, identity_size, fid_data.identity))
1420 {
1421 fpi_ssm_mark_failed (self->task_ssm,
1422 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
1423 2 return;
1424 }
1425
1426 2 match = fpc_print_from_data (self, &fid_data);
1427
1428 2 fpi_device_get_identify_data (device, &templates);
1429 2 g_ptr_array_ref (templates);
1430
1431 2 guint matching_index;
1432
1433
1/2
✓ Branch 30 → 31 taken 2 times.
✗ Branch 30 → 34 not taken.
2 if (g_ptr_array_find_with_equal_func (templates, match,
1434 (GEqualFunc) fp_print_equal, &matching_index))
1435 {
1436 2 FpPrint *print = g_ptr_array_index (templates, matching_index);
1437
1438 2 fpi_device_identify_report (device, print, match, error);
1439
1440 2 fpi_ssm_mark_completed (self->task_ssm);
1441 2 return;
1442 }
1443 }
1444
1445 fpi_device_identify_report (device, NULL, NULL, error);
1446 fpi_ssm_mark_completed (self->task_ssm);
1447 }
1448
1449 static void
1450 8 fpc_identify_sm_run_state (FpiSsm *ssm, FpDevice *device)
1451 {
1452 8 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device);
1453 8 CommandData cmd_data = {0};
1454
1455
4/5
✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 9 taken 2 times.
✓ Branch 3 → 11 taken 2 times.
✓ Branch 3 → 13 taken 2 times.
✗ Branch 3 → 15 not taken.
8 switch (fpi_ssm_get_cur_state (ssm))
1456 {
1457 2 case FPC_IDENTIFY_CAPTURE:
1458 {
1459 2 guint8 buf[4];
1460 2 FpiByteWriter writer;
1461
1462 2 fpi_byte_writer_init_with_data (&writer, buf, sizeof (buf), FALSE);
1463 2 fpi_byte_writer_put_uint32_le (&writer, FPC_CAPTUREID_RESERVED);
1464
1465 2 fpi_device_report_finger_status_changes (device,
1466 FP_FINGER_STATUS_NEEDED,
1467 FP_FINGER_STATUS_NONE);
1468 2 cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE_EVTDATA;
1469 2 cmd_data.request = FPC_CMD_ARM;
1470 2 cmd_data.value = 0x1;
1471 2 cmd_data.index = 0x0;
1472 2 cmd_data.data = buf;
1473 2 cmd_data.data_len = sizeof (buf);
1474 2 cmd_data.callback = fpc_evt_cb;
1475
1476 2 fpc_sensor_cmd (self, TRUE, &cmd_data);
1477 }
1478 2 break;
1479
1480 2 case FPC_IDENTIFY_GET_IMG:
1481 {
1482 2 cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE_EVTDATA;
1483 2 cmd_data.request = FPC_CMD_GET_IMG;
1484 2 cmd_data.value = 0x0;
1485 2 cmd_data.index = 0x0;
1486 2 cmd_data.data = NULL;
1487 2 cmd_data.data_len = 0;
1488 2 cmd_data.callback = fpc_evt_cb;
1489
1490 2 fpc_sensor_cmd (self, FALSE, &cmd_data);
1491 }
1492 2 break;
1493
1494 2 case FPC_IDENTIFY_IDENTIFY:
1495 {
1496 2 gsize recv_data_len = sizeof (FPC_IDENTIFY);
1497 2 cmd_data.cmdtype = FPC_CMDTYPE_FROM_DEVICE;
1498 2 cmd_data.request = FPC_CMD_IDENTIFY;
1499 2 cmd_data.value = 0x0;
1500 2 cmd_data.index = 0x0;
1501 2 cmd_data.data = NULL;
1502 2 cmd_data.data_len = recv_data_len;
1503 2 cmd_data.callback = fpc_identify_cb;
1504
1505 2 fpc_sensor_cmd (self, FALSE, &cmd_data);
1506 }
1507 2 break;
1508
1509 2 case FPC_IDENTIFY_CANCEL:
1510 {
1511 2 cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE;
1512 2 cmd_data.request = FPC_CMD_ABORT;
1513 2 cmd_data.value = 0x1;
1514 2 cmd_data.index = 0x0;
1515 2 cmd_data.data = NULL;
1516 2 cmd_data.data_len = 0;
1517 2 cmd_data.callback = fpc_do_abort_cb;
1518 2 fpc_sensor_cmd (self, FALSE, &cmd_data);
1519
1520 }
1521 2 break;
1522 }
1523 8 }
1524
1525 static void
1526 2 fpc_identify_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
1527 {
1528 2 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (dev);
1529
1530 2 fp_info ("Verify_identify complete!");
1531
1532
1/4
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 7 taken 2 times.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 7 not taken.
2 if (error && error->domain == FP_DEVICE_RETRY)
1533 fpi_device_identify_report (dev, NULL, NULL, g_steal_pointer (&error));
1534
1535 2 fpi_device_identify_complete (dev, g_steal_pointer (&error));
1536
1537 2 self->task_ssm = NULL;
1538 2 }
1539
1540 /******************************************************************************
1541 *
1542 * fpc_init_xxx function
1543 *
1544 *****************************************************************************/
1545 static void
1546 2 fpc_clear_storage_cb (FpiDeviceFpcMoc *self,
1547 void *resp,
1548 GError *error)
1549 {
1550
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 6 taken 2 times.
2 if (error)
1551 {
1552 fp_err ("%s error: %s ", G_STRFUNC, error->message);
1553 fpi_ssm_mark_failed (self->task_ssm, error);
1554 return;
1555 }
1556
1557 2 fpi_ssm_next_state (self->task_ssm);
1558
1559 }
1560
1561 static void
1562 2 fpc_clear_sm_run_state (FpiSsm *ssm, FpDevice *device)
1563 {
1564 2 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device);
1565 2 CommandData cmd_data = {0};
1566 2 FPC_DB_OP data = {0};
1567 2 gsize data_len = 0;
1568
1569
2/3
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 8 taken 1 time.
✗ Branch 3 → 12 not taken.
2 switch (fpi_ssm_get_cur_state (ssm))
1570 {
1571 1 case FPC_CLEAR_DELETE_DB:
1572 {
1573
1/2
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 6 not taken.
1 if (self->dbid)
1574 {
1575 1 data_len = sizeof (FPC_DB_OP);
1576 1 data.database_id_size = FPC_DB_ID_LEN;
1577 1 data.reserved = 8;
1578 1 memcpy (&data.data[0], self->dbid, FPC_DB_ID_LEN);
1579 1 cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE;
1580 1 cmd_data.request = FPC_CMD_DELETE_DB;
1581 1 cmd_data.value = 0x0;
1582 1 cmd_data.index = 0x0;
1583 1 cmd_data.data = (guint8 *) &data;
1584 1 cmd_data.data_len = data_len;
1585 1 cmd_data.callback = fpc_clear_storage_cb;
1586 1 fpc_sensor_cmd (self, FALSE, &cmd_data);
1587 }
1588 else
1589 {
1590 fpi_ssm_mark_failed (self->task_ssm,
1591 fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
1592 "No DBID found"));
1593 }
1594
1595 }
1596 break;
1597
1598 1 case FPC_CLEAR_CREATE_DB:
1599 {
1600
1/2
✓ Branch 8 → 9 taken 1 time.
✗ Branch 8 → 10 not taken.
1 if (self->dbid)
1601 {
1602 1 data_len = sizeof (FPC_DB_OP);
1603 1 data.database_id_size = FPC_DB_ID_LEN;
1604 1 data.reserved = 8;
1605 1 memcpy (&data.data[0], self->dbid, FPC_DB_ID_LEN);
1606 1 cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE;
1607 1 cmd_data.request = FPC_CMD_LOAD_DB;
1608 1 cmd_data.value = 0x1;
1609 1 cmd_data.index = 0x0;
1610 1 cmd_data.data = (guint8 *) &data;
1611 1 cmd_data.data_len = data_len;
1612 1 cmd_data.callback = fpc_clear_storage_cb;
1613 1 fpc_sensor_cmd (self, FALSE, &cmd_data);
1614 }
1615 else
1616 {
1617 fpi_ssm_mark_failed (self->task_ssm,
1618 fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
1619 "No DBID found"));
1620 }
1621 }
1622 break;
1623 }
1624 2 }
1625
1626 static void
1627 1 fpc_clear_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
1628 {
1629 1 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (dev);
1630
1631 1 fp_info ("Clear Storage complete!");
1632
1633 1 fpi_device_clear_storage_complete (dev, g_steal_pointer (&error));
1634 1 self->task_ssm = NULL;
1635 1 }
1636
1637 /******************************************************************************
1638 *
1639 * fpc_init_xxx function
1640 *
1641 *****************************************************************************/
1642
1643 static void
1644 1 fpc_init_load_db_cb (FpiDeviceFpcMoc *self,
1645 void *data,
1646 GError *error)
1647 {
1648 1 FpiByteReader reader;
1649
1650
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 6 taken 1 time.
1 if (error)
1651 {
1652 fp_err ("%s error: %s ", G_STRFUNC, error->message);
1653 fpi_ssm_mark_failed (self->task_ssm, error);
1654 return;
1655 }
1656
1657
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 10 taken 1 time.
1 if (data == NULL)
1658 {
1659 fpi_ssm_mark_failed (self->task_ssm,
1660 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
1661 return;
1662 }
1663
1664 1 fpi_byte_reader_init (&reader, data, sizeof (FPC_LOAD_DB));
1665
1666 {
1667 1 gint32 status;
1668 1 guint32 database_id_size;
1669 1 const guint8 *db_data;
1670
1671
1/2
✓ Branch 11 → 12 taken 1 time.
✗ Branch 11 → 18 not taken.
1 if (!fpi_byte_reader_get_int32_le (&reader, &status) ||
1672
1/2
✓ Branch 12 → 13 taken 1 time.
✗ Branch 12 → 18 not taken.
1 !fpi_byte_reader_skip (&reader, 4) ||
1673
1/2
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 18 not taken.
1 !fpi_byte_reader_get_uint32_le (&reader, &database_id_size) ||
1674
1/2
✓ Branch 16 → 17 taken 1 time.
✗ Branch 16 → 18 not taken.
1 !fpi_byte_reader_get_data (&reader, FPC_DB_ID_LEN, &db_data))
1675 {
1676 fpi_ssm_mark_failed (self->task_ssm,
1677 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
1678 return;
1679 }
1680
1681
1/2
✗ Branch 17 → 20 not taken.
✓ Branch 17 → 23 taken 1 time.
1 if (status)
1682 {
1683 fp_err ("%s Load DB failed: %d - Expect to create a new one", G_STRFUNC, status);
1684 fpi_ssm_next_state (self->task_ssm);
1685 return;
1686 }
1687
1688
1/2
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 25 taken 1 time.
1 g_clear_pointer (&self->dbid, g_free);
1689 1 self->dbid = g_memdup2 (db_data, FPC_DB_ID_LEN);
1690
1/2
✗ Branch 26 → 27 not taken.
✓ Branch 26 → 30 taken 1 time.
1 if (self->dbid == NULL)
1691 {
1692 fpi_ssm_mark_failed (self->task_ssm, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
1693 return;
1694 }
1695
1696 1 fp_dbg ("%s got dbid size: %d", G_STRFUNC, database_id_size);
1697 1 fp_dbg ("%s dbid: 0x%02x%02x%02x%02x-%02x%02x-%02x%02x-" \
1698 "%02x%02x-%02x%02x%02x%02x%02x%02x",
1699 G_STRFUNC,
1700 db_data[0], db_data[1],
1701 db_data[2], db_data[3],
1702 db_data[4], db_data[5],
1703 db_data[6], db_data[7],
1704 db_data[8], db_data[9],
1705 db_data[10], db_data[11],
1706 db_data[12], db_data[13],
1707 db_data[14], db_data[15]);
1708
1709 1 fpi_ssm_mark_completed (self->task_ssm);
1710 }
1711 }
1712
1713 static void
1714 2 fpc_init_sm_run_state (FpiSsm *ssm, FpDevice *device)
1715 {
1716 2 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device);
1717 2 CommandData cmd_data = {0};
1718
1719
2/3
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 8 taken 1 time.
✗ Branch 3 → 10 not taken.
2 switch (fpi_ssm_get_cur_state (ssm))
1720 {
1721 1 case FPC_INIT:
1722 {
1723 1 guint8 buf[4];
1724 1 FpiByteWriter writer;
1725
1726 1 fpi_byte_writer_init_with_data (&writer, buf, sizeof (buf), FALSE);
1727 1 fpi_byte_writer_put_uint32_le (&writer, FPC_SESSIONID_RESERVED);
1728
1729 1 cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE_EVTDATA;
1730 1 cmd_data.request = FPC_CMD_INIT;
1731 1 cmd_data.value = 0x1;
1732 1 cmd_data.index = 0x0;
1733 1 cmd_data.data = buf;
1734 1 cmd_data.data_len = sizeof (buf);
1735 1 cmd_data.callback = fpc_evt_cb;
1736
1737 1 fpc_sensor_cmd (self, FALSE, &cmd_data);
1738 }
1739 1 break;
1740
1741 1 case FPC_INIT_LOAD_DB:
1742 {
1743 1 gsize recv_data_len = sizeof (FPC_LOAD_DB);
1744 1 cmd_data.cmdtype = FPC_CMDTYPE_FROM_DEVICE;
1745 1 cmd_data.request = FPC_CMD_LOAD_DB;
1746 1 cmd_data.value = 0x0;
1747 1 cmd_data.index = 0x0;
1748 1 cmd_data.data = NULL;
1749 1 cmd_data.data_len = recv_data_len;
1750 1 cmd_data.callback = fpc_init_load_db_cb;
1751
1752 1 fpc_sensor_cmd (self, FALSE, &cmd_data);
1753 }
1754 1 break;
1755 }
1756 2 }
1757
1758 static void
1759 1 fpc_init_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
1760 {
1761 1 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (dev);
1762
1763 1 fpi_device_open_complete (dev, g_steal_pointer (&error));
1764 1 self->task_ssm = NULL;
1765 1 }
1766
1767 /******************************************************************************
1768 *
1769 * Interface Function
1770 *
1771 *****************************************************************************/
1772
1773 static void
1774 1 fpc_dev_probe (FpDevice *device)
1775 {
1776 1 GUsbDevice *usb_dev;
1777 1 GError *error = NULL;
1778 1 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device);
1779 1 g_autofree gchar *product = NULL;
1780 1 gint product_id = 0;
1781
1782 1 fp_dbg ("%s enter --> ", G_STRFUNC);
1783
1784 /* Claim usb interface */
1785 1 usb_dev = fpi_device_get_usb_device (device);
1786
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 8 taken 1 time.
1 if (!g_usb_device_open (usb_dev, &error))
1787 {
1788 fp_dbg ("%s g_usb_device_open failed %s", G_STRFUNC, error->message);
1789 fpi_device_probe_complete (device, NULL, NULL, error);
1790 return;
1791 }
1792
1793
1/2
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 14 taken 1 time.
1 if (!g_usb_device_reset (usb_dev, &error))
1794 {
1795 fp_dbg ("%s g_usb_device_reset failed %s", G_STRFUNC, error->message);
1796 g_usb_device_close (usb_dev, NULL);
1797 fpi_device_probe_complete (device, NULL, NULL, error);
1798 return;
1799 }
1800
1801
1/2
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 20 taken 1 time.
1 if (!g_usb_device_claim_interface (usb_dev, 0, 0, &error))
1802 {
1803 fp_dbg ("%s g_usb_device_claim_interface failed %s", G_STRFUNC, error->message);
1804 g_usb_device_close (usb_dev, NULL);
1805 fpi_device_probe_complete (device, NULL, NULL, error);
1806 return;
1807 }
1808
1809 1 product = g_usb_device_get_string_descriptor (usb_dev,
1810 g_usb_device_get_product_index (usb_dev),
1811 &error);
1812
1/2
✓ Branch 22 → 23 taken 1 time.
✗ Branch 22 → 24 not taken.
1 if (product)
1813 1 fp_dbg ("Device name: %s", product);
1814
1815
1/2
✗ Branch 24 → 25 not taken.
✓ Branch 24 → 31 taken 1 time.
1 if (error)
1816 {
1817 fp_dbg ("%s g_usb_device_get_string_descriptor failed %s", G_STRFUNC, error->message);
1818 g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (device)),
1819 0, 0, NULL);
1820 g_usb_device_close (usb_dev, NULL);
1821 fpi_device_probe_complete (device, NULL, NULL, error);
1822 return;
1823 }
1824
1825 1 product_id = g_usb_device_get_pid (usb_dev);
1826 /* Reserved for customer enroll scheme */
1827 1 self->max_immobile_stage = 0; /* By default is not customer enrollment */
1828
1/2
✓ Branch 32 → 33 taken 1 time.
✗ Branch 32 → 34 not taken.
1 switch (product_id)
1829 {
1830 1 case 0xFFE0:
1831 case 0xA305:
1832 case 0xA306:
1833 case 0xD805:
1834 case 0xDA04:
1835 case 0xD205:
1836 case 0x9524:
1837 case 0x9544:
1838 case 0xC844:
1839 1 self->max_enroll_stage = MAX_ENROLL_SAMPLES;
1840 1 break;
1841
1842 default:
1843 fp_warn ("Device %x is not supported", product_id);
1844 self->max_enroll_stage = MAX_ENROLL_SAMPLES;
1845 break;
1846 }
1847 1 fpi_device_set_nr_enroll_stages (device, self->max_enroll_stage);
1848 1 g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (device)),
1849 0, 0, NULL);
1850 1 g_usb_device_close (usb_dev, NULL);
1851 1 fpi_device_probe_complete (device, NULL, product, error);
1852 }
1853
1854 static void
1855 1 fpc_dev_open (FpDevice *device)
1856 {
1857 1 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device);
1858 1 GError *error = NULL;
1859
1860 1 fp_dbg ("%s enter -->", G_STRFUNC);
1861
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 1 time.
1 if (!g_usb_device_reset (fpi_device_get_usb_device (device), &error))
1862 {
1863 fpi_device_open_complete (FP_DEVICE (self), error);
1864 return;
1865 }
1866
1867 /* Claim usb interface */
1868
1/2
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 12 taken 1 time.
1 if (!g_usb_device_claim_interface (fpi_device_get_usb_device (device), 0, 0, &error))
1869 {
1870 fpi_device_open_complete (FP_DEVICE (self), error);
1871 return;
1872 }
1873
1874 1 self->task_ssm = fpi_ssm_new (device, fpc_init_sm_run_state,
1875 FPC_INIT_NUM_STATES);
1876
1877 1 fpi_ssm_start (self->task_ssm, fpc_init_ssm_done);
1878 }
1879
1880 static void
1881 1 fpc_dev_close (FpDevice *device)
1882 {
1883 1 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device);
1884
1885 1 fp_dbg ("%s enter -->", G_STRFUNC);
1886
1/2
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 5 not taken.
1 g_clear_pointer (&self->dbid, g_free);
1887 1 g_cancellable_cancel (self->interrupt_cancellable);
1888
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 1 time.
1 g_clear_object (&self->interrupt_cancellable);
1889 1 fpc_dev_release_interface (self, NULL);
1890 1 }
1891
1892 static void
1893 2 fpc_dev_identify (FpDevice *device)
1894 {
1895 2 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device);
1896
1897 2 fp_dbg ("%s enter -->", G_STRFUNC);
1898 2 self->task_ssm = fpi_ssm_new_full (device, fpc_identify_sm_run_state,
1899 FPC_IDENTIFY_NUM_STATES,
1900 FPC_IDENTIFY_CANCEL,
1901 "identify");
1902
1903 2 fpi_ssm_start (self->task_ssm, fpc_identify_ssm_done);
1904 2 }
1905
1906 static void
1907 1 fpc_dev_enroll (FpDevice *device)
1908 {
1909 1 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device);
1910
1911 1 fp_dbg ("%s enter -->", G_STRFUNC);
1912
1913 1 self->enroll_stage = 0;
1914 1 self->immobile_stage = 0;
1915 1 self->task_ssm = fpi_ssm_new_full (device, fpc_enroll_sm_run_state,
1916 FPC_ENROLL_NUM_STATES,
1917 FPC_ENROLL_DICARD,
1918 "enroll");
1919
1920 1 fpi_ssm_start (self->task_ssm, fpc_enroll_ssm_done);
1921 1 }
1922
1923 static void
1924 1 fpc_dev_template_list (FpDevice *device)
1925 {
1926 1 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device);
1927 1 CommandData cmd_data = {0};
1928 1 guint8 buf[sizeof (FPC_FID_DATA)] = {0};
1929 1 FpiByteWriter writer;
1930
1931 1 fp_dbg ("%s enter -->", G_STRFUNC);
1932
1933 1 fpi_byte_writer_init_with_data (&writer, buf, sizeof (buf), FALSE);
1934 1 fpi_byte_writer_put_uint32_le (&writer, FPC_IDENTITY_TYPE_WILDCARD);
1935 1 fpi_byte_writer_put_uint32_le (&writer, 16);
1936 1 fpi_byte_writer_put_uint32_le (&writer, sizeof (guint32));
1937 1 fpi_byte_writer_put_uint32_le (&writer, FPC_SUBTYPE_ANY);
1938 1 fpi_byte_writer_put_uint32_le (&writer, FPC_IDENTITY_WILDCARD);
1939
1940 1 cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE_EVTDATA;
1941 1 cmd_data.request = FPC_CMD_ENUM;
1942 1 cmd_data.value = 0x0;
1943 1 cmd_data.index = 0x0;
1944 1 cmd_data.data = buf;
1945 1 cmd_data.data_len = sizeof (buf);
1946 1 cmd_data.callback = fpc_template_list_cb;
1947
1948 1 fpc_sensor_cmd (self, FALSE, &cmd_data);
1949 1 }
1950
1951 static void
1952 fpc_dev_suspend (FpDevice *device)
1953 {
1954 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device);
1955 FpiDeviceAction action = fpi_device_get_current_action (device);
1956
1957 fp_dbg ("%s enter -->", G_STRFUNC);
1958
1959 if (action != FPI_DEVICE_ACTION_IDENTIFY)
1960 {
1961 fpi_device_suspend_complete (device, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
1962 return;
1963 }
1964
1965 g_assert (self->cmd_ssm);
1966 g_assert (fpi_ssm_get_cur_state (self->cmd_ssm) == FPC_CMD_GET_DATA);
1967 self->cmd_suspended = TRUE;
1968 g_cancellable_cancel (self->interrupt_cancellable);
1969 }
1970
1971 static void
1972 fpc_dev_resume (FpDevice *device)
1973 {
1974 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device);
1975 FpiDeviceAction action = fpi_device_get_current_action (device);
1976
1977 fp_dbg ("%s enter -->", G_STRFUNC);
1978
1979 if (action != FPI_DEVICE_ACTION_IDENTIFY)
1980 {
1981 g_assert_not_reached ();
1982 fpi_device_resume_complete (device, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
1983 return;
1984 }
1985
1986 g_assert (self->cmd_ssm);
1987 g_assert (self->cmd_suspended);
1988 g_assert (fpi_ssm_get_cur_state (self->cmd_ssm) == FPC_CMD_SUSPENDED);
1989 self->cmd_suspended = FALSE;
1990
1991 g_clear_object (&self->interrupt_cancellable);
1992 self->interrupt_cancellable = g_cancellable_new ();
1993 fpi_ssm_jump_to_state (self->cmd_ssm, FPC_CMD_RESUME);
1994 }
1995
1996 static void
1997 fpc_dev_cancel (FpDevice *device)
1998 {
1999 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device);
2000
2001 fp_dbg ("%s enter -->", G_STRFUNC);
2002 g_cancellable_cancel (self->interrupt_cancellable);
2003 }
2004
2005 static void
2006 1 fpc_dev_template_delete (FpDevice *device)
2007 {
2008 1 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device);
2009 1 CommandData cmd_data = {0};
2010 1 FpPrint *print = NULL;
2011
2012 1 g_autoptr(GVariant) fpi_data = NULL;
2013 1 guint8 buf[sizeof (FPC_FID_DATA)] = {0};
2014 1 FpiByteWriter writer;
2015 1 guint8 finger = FPC_SUBTYPE_NOINFORMATION;
2016 1 const guint8 *user_id;
2017 1 gsize user_id_len = 0;
2018
2019 1 fp_dbg ("%s enter -->", G_STRFUNC);
2020
2021 1 fpi_device_get_delete_data (device, &print);
2022
2023 1 g_object_get (print, "fpi-data", &fpi_data, NULL);
2024
2025
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 12 taken 1 time.
1 if (!parse_print_data (fpi_data, &finger, &user_id, &user_id_len))
2026 {
2027 fpi_device_delete_complete (device,
2028 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
2029 return;
2030 }
2031
2032 1 fpi_byte_writer_init_with_data (&writer, buf, sizeof (buf), FALSE);
2033 1 fpi_byte_writer_put_uint32_le (&writer, FPC_IDENTITY_TYPE_RESERVED);
2034 1 fpi_byte_writer_put_uint32_le (&writer, 16);
2035 1 fpi_byte_writer_put_uint32_le (&writer, user_id_len);
2036 1 fpi_byte_writer_put_uint32_le (&writer, (guint32) finger);
2037 1 fpi_byte_writer_put_data (&writer, user_id, user_id_len);
2038
2039 1 cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE;
2040 1 cmd_data.request = FPC_CMD_DELETE_TEMPLATE;
2041 1 cmd_data.value = 0x0;
2042 1 cmd_data.index = 0x0;
2043 1 cmd_data.data = buf;
2044 1 cmd_data.data_len = sizeof (buf);
2045 1 cmd_data.callback = fpc_template_delete_cb;
2046
2047 1 fpc_sensor_cmd (self, FALSE, &cmd_data);
2048
1/2
✓ Branch 20 → 21 taken 1 time.
✗ Branch 20 → 22 not taken.
1 fp_dbg ("%s exit <--", G_STRFUNC);
2049 }
2050
2051 static void
2052 1 fpc_dev_clear_storage (FpDevice *device)
2053 {
2054 1 FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device);
2055
2056 1 fp_dbg ("%s enter -->", G_STRFUNC);
2057 1 self->task_ssm = fpi_ssm_new_full (device, fpc_clear_sm_run_state,
2058 FPC_CLEAR_NUM_STATES,
2059 FPC_CLEAR_NUM_STATES,
2060 "Clear storage");
2061
2062 1 fpi_ssm_start (self->task_ssm, fpc_clear_ssm_done);
2063 1 }
2064
2065 static void
2066 1 fpi_device_fpcmoc_init (FpiDeviceFpcMoc *self)
2067 {
2068 1 fp_dbg ("%s enter -->", G_STRFUNC);
2069 1 G_DEBUG_HERE ();
2070 1 }
2071
2072 static void
2073 125 fpi_device_fpcmoc_class_init (FpiDeviceFpcMocClass *klass)
2074 {
2075 125 FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
2076
2077 125 dev_class->id = FP_COMPONENT;
2078 125 dev_class->full_name = "FPC MOC Fingerprint Sensor";
2079 125 dev_class->type = FP_DEVICE_TYPE_USB;
2080 125 dev_class->scan_type = FP_SCAN_TYPE_PRESS;
2081 125 dev_class->id_table = id_table;
2082 125 dev_class->nr_enroll_stages = MAX_ENROLL_SAMPLES;
2083 125 dev_class->temp_hot_seconds = -1;
2084
2085 125 dev_class->open = fpc_dev_open;
2086 125 dev_class->close = fpc_dev_close;
2087 125 dev_class->probe = fpc_dev_probe;
2088 125 dev_class->enroll = fpc_dev_enroll;
2089 125 dev_class->delete = fpc_dev_template_delete;
2090 125 dev_class->list = fpc_dev_template_list;
2091 125 dev_class->identify = fpc_dev_identify;
2092 125 dev_class->suspend = fpc_dev_suspend;
2093 125 dev_class->resume = fpc_dev_resume;
2094 125 dev_class->clear_storage = fpc_dev_clear_storage;
2095 125 dev_class->cancel = fpc_dev_cancel;
2096
2097 125 fpi_device_class_auto_initialize_features (dev_class);
2098 125 dev_class->features |= FP_DEVICE_FEATURE_DUPLICATES_CHECK;
2099 125 }
2100