GCC Code Coverage Report


Directory: ./
File: libfprint/drivers/realtek/realtek.c
Date: 2024-05-04 14:54:39
Exec Total Coverage
Lines: 500 583 85.8%
Functions: 39 39 100.0%
Branches: 126 212 59.4%

Line Branch Exec Source
1 /*
2 * Copyright (C) 2022-2023 Realtek Corp.
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 #define FP_COMPONENT "realtek"
20
21 #include "drivers_api.h"
22
23 #include "fpi-byte-reader.h"
24
25 #include "realtek.h"
26
27
4/5
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 117 times.
✓ Branch 3 taken 117 times.
✗ Branch 4 not taken.
750 G_DEFINE_TYPE (FpiDeviceRealtek, fpi_device_realtek, FP_TYPE_DEVICE)
28
29 static const FpIdEntry id_table[] = {
30 { .vid = 0x0bda, .pid = 0x5813, },
31 { .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
32 };
33
34 static gboolean
35 1 parse_print_data (GVariant *data,
36 guint8 *finger,
37 const guint8 **user_id,
38 gsize *user_id_len)
39 {
40 2 g_autoptr(GVariant) user_id_var = NULL;
41
42
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 g_return_val_if_fail (data, FALSE);
43
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 g_return_val_if_fail (finger, FALSE);
44
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 g_return_val_if_fail (user_id, FALSE);
45
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 g_return_val_if_fail (user_id_len, FALSE);
46
47 1 *user_id = NULL;
48 1 *user_id_len = 0;
49 1 *finger = 0;
50
51
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (!g_variant_check_format_string (data, "(y@ay)", FALSE))
52 return FALSE;
53
54 1 g_variant_get (data,
55 "(y@ay)",
56 finger,
57 &user_id_var);
58
59 1 *user_id = g_variant_get_fixed_array (user_id_var, user_id_len, 1);
60
61
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (*user_id_len <= 0 || *user_id_len > DEFAULT_UID_LEN)
62 return FALSE;
63
64
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (*user_id[0] == '\0' || *user_id[0] == ' ')
65 return FALSE;
66
67
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (*finger != SUB_FINGER_01)
68 return FALSE;
69
70 return TRUE;
71 }
72
73 static void
74 46 fp_cmd_ssm_done_data_free (CommandData *data)
75 {
76 46 g_free (data);
77 46 }
78
79 /* data callbacks */
80
81 static void
82 16 fp_task_ssm_generic_cb (FpiDeviceRealtek *self,
83 uint8_t *buffer_in,
84 GError *error)
85 {
86
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (error)
87 {
88 fpi_ssm_mark_failed (self->task_ssm, error);
89 return;
90 }
91
92 16 fpi_ssm_next_state (self->task_ssm);
93 }
94
95 static void
96 11 fp_finish_capture_cb (FpiDeviceRealtek *self,
97 uint8_t *buffer_in,
98 GError *error)
99 {
100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (error)
101 {
102 fpi_ssm_mark_failed (self->task_ssm, error);
103 return;
104 }
105
106 11 gint capture_status = buffer_in[0];
107
108
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if (capture_status == 0)
109 {
110 11 fpi_device_report_finger_status_changes (FP_DEVICE (self),
111 FP_FINGER_STATUS_PRESENT,
112 FP_FINGER_STATUS_NEEDED);
113 11 fpi_ssm_next_state (self->task_ssm);
114 }
115 else
116 {
117 fpi_ssm_jump_to_state (self->task_ssm,
118 fpi_ssm_get_cur_state (self->task_ssm));
119 }
120 }
121
122 static void
123 11 fp_accept_sample_cb (FpiDeviceRealtek *self,
124 uint8_t *buffer_in,
125 GError *error)
126 {
127 11 fpi_device_report_finger_status_changes (FP_DEVICE (self),
128 FP_FINGER_STATUS_NONE,
129 FP_FINGER_STATUS_PRESENT);
130
131
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (error)
132 {
133 fpi_ssm_mark_failed (self->task_ssm, error);
134 return;
135 }
136
137 11 gint in_status = buffer_in[0];
138
139
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 9 times.
11 if (self->fp_purpose != FP_RTK_PURPOSE_ENROLL)
140 {
141 /* verify or identify purpose process */
142 2 fpi_ssm_next_state (self->task_ssm);
143 2 return;
144 }
145 else
146 {
147 /* enroll purpose process */
148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (in_status == FP_RTK_CMD_ERR)
149 {
150 fpi_ssm_mark_failed (self->task_ssm,
151 fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
152 "Command error!"));
153 return;
154 }
155
156
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
9 if (self->enroll_stage < self->max_enroll_stage)
157 {
158
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if (in_status == FP_RTK_SUCCESS)
159 {
160 8 self->enroll_stage++;
161 8 fpi_device_enroll_progress (FP_DEVICE (self), self->enroll_stage, NULL, NULL);
162 8 fpi_ssm_jump_to_state (self->task_ssm, FP_RTK_ENROLL_CAPTURE);
163 }
164 else if (in_status == FP_RTK_MATCH_FAIL)
165 {
166 fpi_ssm_mark_failed (self->task_ssm,
167 fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID,
168 "InStatus invalid!"));
169 }
170 else
171 {
172 fpi_device_enroll_progress (FP_DEVICE (self),
173 self->enroll_stage,
174 NULL,
175 fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL));
176
177 fpi_ssm_jump_to_state (self->task_ssm, FP_RTK_ENROLL_CAPTURE);
178 }
179 8 return;
180 }
181 1 fpi_ssm_next_state (self->task_ssm);
182 }
183 }
184
185 static FpPrint *
186 3 fp_print_from_data (FpiDeviceRealtek *self, uint8_t *buffer)
187 {
188 3 FpPrint *print;
189 3 GVariant *data;
190 3 GVariant *uid;
191 3 guint finger;
192 3 gsize userid_len;
193 6 g_autofree gchar *userid = NULL;
194
195 3 userid = g_strndup ((gchar *) buffer + 1, DEFAULT_UID_LEN);
196 3 finger = *(buffer);
197
198 3 print = fp_print_new (FP_DEVICE (self));
199 3 userid_len = MIN (DEFAULT_UID_LEN, strlen (userid));
200
201 3 uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
202 userid,
203 userid_len,
204 1);
205
206 3 data = g_variant_new ("(y@ay)",
207 finger,
208 uid);
209
210 3 fpi_print_set_type (print, FPI_PRINT_RAW);
211 3 fpi_print_set_device_stored (print, TRUE);
212 3 g_object_set (print, "fpi-data", data, NULL);
213 3 g_object_set (print, "description", userid, NULL);
214 3 fpi_print_fill_from_user_id (print, userid);
215
216 3 return print;
217 }
218
219 static void
220 2 fp_identify_feature_cb (FpiDeviceRealtek *self,
221 uint8_t *buffer_in,
222 GError *error)
223 {
224 2 FpDevice *device = FP_DEVICE (self);
225 2 FpPrint *match = NULL;
226 2 FpPrint *print = NULL;
227 2 FpiDeviceAction current_action;
228
229 2 g_autoptr(GPtrArray) templates = NULL;
230 2 gboolean found = FALSE;
231
232 2 current_action = fpi_device_get_current_action (device);
233
234
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (error)
235 {
236 fpi_ssm_mark_failed (self->task_ssm, error);
237 return;
238 }
239
240 2 gint in_status = buffer_in[0];
241
242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (in_status == FP_RTK_CMD_ERR)
243 {
244 fpi_ssm_mark_failed (self->task_ssm,
245 fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
246 "Command error!"));
247 return;
248 }
249
250
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (in_status >= FP_RTK_TOO_HIGH && in_status <= FP_RTK_MERGE_FAILURE)
251 {
252 fpi_ssm_mark_failed (self->task_ssm,
253 fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL));
254 return;
255 }
256
257
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (in_status == FP_RTK_SUCCESS)
258 {
259 2 match = fp_print_from_data (self, buffer_in + 1);
260
261
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (current_action == FPI_DEVICE_ACTION_VERIFY)
262 {
263 1 templates = g_ptr_array_sized_new (1);
264 1 fpi_device_get_verify_data (device, &print);
265 1 g_ptr_array_add (templates, print);
266 }
267 else
268 {
269 1 fpi_device_get_identify_data (device, &templates);
270 1 g_ptr_array_ref (templates);
271 }
272
273
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 for (gint cnt = 0; cnt < templates->len; cnt++)
274 {
275 2 print = g_ptr_array_index (templates, cnt);
276
277
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (fp_print_equal (print, match))
278 {
279 found = TRUE;
280 break;
281 }
282 }
283
284
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (found)
285 {
286
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (current_action == FPI_DEVICE_ACTION_VERIFY)
287 {
288 1 fpi_device_verify_report (device, FPI_MATCH_SUCCESS, match, error);
289 1 fpi_ssm_next_state (self->task_ssm);
290 }
291 else
292 {
293 1 fpi_device_identify_report (device, print, match, error);
294 1 fpi_ssm_mark_completed (self->task_ssm);
295 }
296 2 return;
297 }
298 }
299
300 if (!found)
301 {
302 if (current_action == FPI_DEVICE_ACTION_VERIFY)
303 fpi_device_verify_report (device, FPI_MATCH_FAIL, NULL, error);
304 else
305 fpi_device_identify_report (device, NULL, NULL, error);
306
307 fpi_ssm_jump_to_state (self->task_ssm, FP_RTK_VERIFY_NUM_STATES);
308 }
309 }
310
311 static void
312 1 fp_get_delete_pos_cb (FpiDeviceRealtek *self,
313 uint8_t *buffer_in,
314 GError *error)
315 {
316 1 FpPrint *print = NULL;
317
318 1 g_autoptr(GVariant) data = NULL;
319 1 gsize user_id_len = 0;
320 1 const guint8 *user_id;
321 1 guint8 finger;
322 1 gboolean found = FALSE;
323 1 gchar temp_userid[DEFAULT_UID_LEN + 1] = {0};
324
325
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (error)
326 {
327 fpi_ssm_mark_failed (self->task_ssm, error);
328 return;
329 }
330
331 1 fpi_device_get_delete_data (FP_DEVICE (self), &print);
332 1 g_object_get (print, "fpi-data", &data, NULL);
333
334
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (!parse_print_data (data, &finger, &user_id, &user_id_len))
335 {
336 fpi_device_delete_complete (FP_DEVICE (self),
337 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
338 return;
339 }
340
341
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 for (gint i = 0; i < self->template_num; i++)
342 {
343
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buffer_in[i * TEMPLATE_LEN] != 0)
344 {
345 1 memcpy (temp_userid, buffer_in + i * TEMPLATE_LEN + UID_OFFSET, DEFAULT_UID_LEN);
346
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if (g_strcmp0 (fp_print_get_description (print), (const char *) temp_userid) == 0)
347 {
348 1 self->pos_index = i;
349 1 found = TRUE;
350 1 break;
351 }
352 }
353 }
354
355 1 if (!found)
356 {
357 fpi_ssm_mark_failed (self->task_ssm,
358 fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
359 "Get template position failed!"));
360 return;
361 }
362
363
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 fpi_ssm_next_state (self->task_ssm);
364 }
365
366 static void
367 1 fp_get_enroll_num_cb (FpiDeviceRealtek *self,
368 uint8_t *buffer_in,
369 GError *error)
370 {
371
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (error)
372 {
373 fpi_ssm_mark_failed (self->task_ssm, error);
374 return;
375 }
376
377 1 self->template_num = buffer_in[1];
378
379 1 fpi_ssm_next_state (self->task_ssm);
380 }
381
382 static void
383 1 fp_get_template_cb (FpiDeviceRealtek *self,
384 uint8_t *buffer_in,
385 GError *error)
386 {
387 1 gboolean found = FALSE;
388
389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (error)
390 {
391 fpi_ssm_mark_failed (self->task_ssm, error);
392 return;
393 }
394
395
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 for (gint i = 0; i < self->template_num; i++)
396 {
397
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buffer_in[i * TEMPLATE_LEN] == 0)
398 {
399 1 self->pos_index = i;
400 1 found = TRUE;
401 1 break;
402 }
403 }
404
405 1 if (!found)
406 {
407 fpi_ssm_mark_failed (self->task_ssm,
408 fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
409 "No free template was found!"));
410 return;
411 }
412
413 1 fpi_ssm_next_state (self->task_ssm);
414 }
415
416 static void
417 1 fp_check_duplicate_cb (FpiDeviceRealtek *self,
418 uint8_t *buffer_in,
419 GError *error)
420 {
421
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (error)
422 {
423 fpi_ssm_mark_failed (self->task_ssm, error);
424 return;
425 }
426
427 1 gint in_status = buffer_in[0];
428
429
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (in_status == FP_RTK_CMD_ERR)
430 {
431 fpi_ssm_mark_failed (self->task_ssm,
432 fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
433 "Command error!"));
434 return;
435 }
436
437
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (in_status == FP_RTK_SUCCESS)
438 {
439 fpi_ssm_mark_failed (self->task_ssm,
440 fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
441 "Current fingerprint is duplicate!"));
442 }
443
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 else if (in_status == FP_RTK_MATCH_FAIL)
444 {
445 1 fpi_ssm_next_state (self->task_ssm);
446 }
447 else
448 {
449 fpi_ssm_mark_failed (self->task_ssm,
450 fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID,
451 "InStatus invalid!"));
452 }
453 }
454
455 static void
456 1 fp_list_cb (FpiDeviceRealtek *self,
457 uint8_t *buffer_in,
458 GError *error)
459 {
460 1 gboolean found = FALSE;
461
462 1 g_autoptr(GPtrArray) list_result = NULL;
463
464
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (error)
465 {
466 fpi_device_list_complete (FP_DEVICE (self), NULL, error);
467 return;
468 }
469
470 1 list_result = g_ptr_array_new_with_free_func (g_object_unref);
471
472
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 1 times.
6 for (gint i = 0; i < self->template_num; i++)
473 {
474
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
5 if (buffer_in[i * TEMPLATE_LEN] != 0)
475 {
476 1 FpPrint *print = NULL;
477 1 print = fp_print_from_data (self, buffer_in + i * TEMPLATE_LEN + SUBFACTOR_OFFSET);
478 1 g_ptr_array_add (list_result, g_object_ref_sink (print));
479 1 found = TRUE;
480 }
481 }
482
483
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!found)
484 {
485 fpi_device_list_complete (FP_DEVICE (self),
486 g_steal_pointer (&list_result),
487 fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_FULL,
488 "Database is empty"));
489 return;
490 }
491
492 1 fp_info ("Query templates complete!");
493 1 fpi_device_list_complete (FP_DEVICE (self),
494 1 g_steal_pointer (&list_result),
495 NULL);
496 }
497
498 static void
499 1 fp_clear_storage_cb (FpiDeviceRealtek *self,
500 uint8_t *buffer_in,
501 GError *error)
502 {
503 1 FpDevice *device = FP_DEVICE (self);
504
505
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (error)
506 {
507 fpi_device_clear_storage_complete (device, error);
508 return;
509 }
510
511 1 fp_info ("Successfully cleared storage");
512 1 fpi_device_clear_storage_complete (device, NULL);
513 }
514
515
516 static gint
517 46 parse_status (guint8 *buffer, gint status_type)
518 {
519 46 switch (status_type)
520 {
521 case FP_RTK_MSG_PLAINTEXT_NO_STATUS:
522 return 0;
523 32 break;
524
525 32 case FP_RTK_MSG_PLAINTEXT:
526 32 return buffer[0];
527 break;
528
529 default:
530 return 1;
531 32 break;
532 }
533 }
534
535 static void
536 75 fp_cmd_receive_cb (FpiUsbTransfer *transfer,
537 FpDevice *device,
538 gpointer user_data,
539 GError *error)
540 {
541 75 FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (device);
542 75 CommandData *data = user_data;
543 75 gint ssm_state = 0;
544 75 gint status_flag = 1;
545
546
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 75 times.
75 if (error)
547 {
548 fpi_ssm_mark_failed (transfer->ssm, error);
549 return;
550 }
551
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 75 times.
75 if (data == NULL)
552 {
553 fpi_ssm_mark_failed (transfer->ssm,
554 fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
555 return;
556 }
557
558 75 ssm_state = fpi_ssm_get_cur_state (transfer->ssm);
559
560 /* skip zero length package */
561
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 75 times.
75 if (transfer->actual_length == 0)
562 {
563 fpi_ssm_jump_to_state (transfer->ssm, ssm_state);
564 return;
565 }
566
567 /* get data */
568
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 46 times.
75 if (ssm_state == FP_RTK_CMD_TRANS_DATA)
569 {
570 29 g_autofree guchar *read_buf = NULL;
571
572 29 read_buf = g_malloc0 (sizeof (guchar) * (self->trans_data_len));
573 29 memcpy (read_buf, transfer->buffer, self->trans_data_len);
574 29 self->read_data = g_steal_pointer (&read_buf);
575
576 29 fpi_ssm_next_state (transfer->ssm);
577 29 return;
578 }
579
580 /* get status */
581
2/3
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
46 status_flag = parse_status (transfer->buffer, self->message_type);
582
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 if (status_flag != 0)
583 {
584 fpi_ssm_mark_failed (transfer->ssm,
585 fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
586 "Status check failed"));
587 return;
588 }
589
590
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 if (data->callback)
591 46 data->callback (self, self->read_data, NULL);
592
593
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 17 times.
46 if (self->read_data)
594 29 g_clear_pointer (&self->read_data, g_free);
595
596 46 fpi_ssm_mark_completed (transfer->ssm);
597 }
598
599 static void
600 138 fp_cmd_run_state (FpiSsm *ssm, FpDevice *dev)
601 {
602 138 FpiUsbTransfer *transfer = NULL;
603 138 FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (dev);
604
605
3/4
✓ Branch 1 taken 46 times.
✓ Branch 2 taken 46 times.
✓ Branch 3 taken 46 times.
✗ Branch 4 not taken.
138 switch (fpi_ssm_get_cur_state (ssm))
606 {
607 46 case FP_RTK_CMD_SEND:
608
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 if (self->cmd_transfer)
609 {
610 46 self->cmd_transfer->ssm = ssm;
611 46 fpi_usb_transfer_submit (g_steal_pointer (&self->cmd_transfer),
612 CMD_TIMEOUT,
613 NULL,
614 fpi_ssm_usb_transfer_cb,
615 NULL);
616 }
617 else
618 {
619 fpi_ssm_next_state (ssm);
620 }
621 break;
622
623 46 case FP_RTK_CMD_TRANS_DATA:
624
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 30 times.
46 if (self->cmd_type == FP_RTK_CMD_ONLY)
625 {
626 16 fpi_ssm_jump_to_state (ssm, FP_RTK_CMD_GET_STATUS);
627 16 break;
628 }
629
630
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 29 times.
30 if (self->cmd_type == FP_RTK_CMD_WRITE)
631 {
632
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (self->data_transfer)
633 {
634 1 self->data_transfer->ssm = ssm;
635 1 fpi_usb_transfer_submit (g_steal_pointer (&self->data_transfer),
636 DATA_TIMEOUT,
637 NULL,
638 fpi_ssm_usb_transfer_cb,
639 NULL);
640 }
641 else
642 {
643 fpi_ssm_next_state (ssm);
644 }
645 }
646 else /* CMD_READ */
647 {
648 29 transfer = fpi_usb_transfer_new (dev);
649 29 transfer->ssm = ssm;
650 29 fpi_usb_transfer_fill_bulk (transfer, EP_IN, EP_IN_MAX_BUF_SIZE);
651
652 58 fpi_usb_transfer_submit (transfer,
653
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 24 times.
29 self->cmd_cancellable ? 0 : DATA_TIMEOUT,
654
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 5 times.
29 self->cmd_cancellable ? fpi_device_get_cancellable (dev) : NULL,
655 fp_cmd_receive_cb,
656 fpi_ssm_get_data (ssm));
657 }
658 break;
659
660 46 case FP_RTK_CMD_GET_STATUS:
661 46 transfer = fpi_usb_transfer_new (dev);
662 46 transfer->ssm = ssm;
663 46 fpi_usb_transfer_fill_bulk (transfer, EP_IN, EP_IN_MAX_BUF_SIZE);
664 46 fpi_usb_transfer_submit (transfer,
665 STATUS_TIMEOUT,
666 NULL,
667 fp_cmd_receive_cb,
668 fpi_ssm_get_data (ssm));
669 46 break;
670 }
671 138 }
672
673 static void
674 46 fp_cmd_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
675 {
676 46 FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (dev);
677 46 CommandData *data = fpi_ssm_get_data (ssm);
678
679 46 self->cmd_ssm = NULL;
680
681
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (error)
682 {
683 if (data->callback)
684 data->callback (self, NULL, error);
685 else
686 g_error_free (error);
687 }
688 46 }
689
690 static FpiUsbTransfer *
691 47 prepare_transfer (FpDevice *dev,
692 guint8 *data,
693 gsize data_len,
694 GDestroyNotify free_func)
695 {
696 94 g_autoptr(FpiUsbTransfer) transfer = NULL;
697
698
1/2
✓ Branch 0 taken 47 times.
✗ Branch 1 not taken.
47 g_return_val_if_fail (data || data_len == 0, NULL);
699
700 47 transfer = fpi_usb_transfer_new (dev);
701
702 47 fpi_usb_transfer_fill_bulk_full (transfer,
703 EP_OUT,
704 data,
705 data_len,
706 free_func);
707
708 47 return g_steal_pointer (&transfer);
709 }
710
711 static void
712 46 realtek_sensor_cmd (FpiDeviceRealtek *self,
713 guint8 *cmd,
714 guint8 *trans_data,
715 FpRtkMsgType message_type,
716 gboolean bwait_data_delay,
717 SynCmdMsgCallback callback)
718 {
719 92 g_autoptr(FpiUsbTransfer) cmd_transfer = NULL;
720 92 g_autoptr(FpiUsbTransfer) data_transfer = NULL;
721 46 CommandData *data = g_new0 (CommandData, 1);
722
723 46 self->cmd_type = GET_CMD_TYPE (cmd[0]);
724 46 self->message_type = message_type;
725 46 self->trans_data_len = GET_TRANS_DATA_LEN (cmd[11], cmd[10]);
726 46 self->cmd_cancellable = bwait_data_delay;
727
728 46 cmd_transfer = prepare_transfer (FP_DEVICE (self), cmd, FP_RTK_CMD_TOTAL_LEN, NULL);
729
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 45 times.
46 self->cmd_transfer = g_steal_pointer (&cmd_transfer);
730
731
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
46 if ((self->cmd_type == FP_RTK_CMD_WRITE) && trans_data)
732 {
733 1 data_transfer = prepare_transfer (FP_DEVICE (self), trans_data, self->trans_data_len, g_free);
734 1 self->data_transfer = g_steal_pointer (&data_transfer);
735 }
736
737 46 self->cmd_ssm = fpi_ssm_new (FP_DEVICE (self),
738 fp_cmd_run_state,
739 FP_RTK_CMD_NUM_STATES);
740
741 46 data->callback = callback;
742 46 fpi_ssm_set_data (self->cmd_ssm, data, (GDestroyNotify) fp_cmd_ssm_done_data_free);
743
744 46 fpi_ssm_start (self->cmd_ssm, fp_cmd_ssm_done);
745 46 }
746
747 static void
748 2 fp_verify_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
749 {
750 2 FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (dev);
751
752 2 fp_info ("Verify complete!");
753
754
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (fpi_ssm_get_error (ssm))
755 error = fpi_ssm_get_error (ssm);
756
757
1/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
2 if (error && error->domain == FP_DEVICE_RETRY)
758 {
759 if (fpi_device_get_current_action (dev) == FPI_DEVICE_ACTION_VERIFY)
760 fpi_device_verify_report (dev, FPI_MATCH_ERROR, NULL, g_steal_pointer (&error));
761 else
762 fpi_device_identify_report (dev, NULL, NULL, g_steal_pointer (&error));
763 }
764
765
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if (fpi_device_get_current_action (dev) == FPI_DEVICE_ACTION_VERIFY)
766 1 fpi_device_verify_complete (dev, error);
767 else
768 1 fpi_device_identify_complete (dev, error);
769
770 2 self->task_ssm = NULL;
771 2 }
772
773 static void
774 1 fp_enroll_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
775 {
776 1 FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (dev);
777 1 FpPrint *print = NULL;
778
779 1 fp_info ("Enrollment complete!");
780
781
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (fpi_ssm_get_error (ssm))
782 error = fpi_ssm_get_error (ssm);
783
784
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (error)
785 {
786 fpi_device_enroll_complete (dev, NULL, error);
787 self->task_ssm = NULL;
788 return;
789 }
790
791 1 fpi_device_get_enroll_data (FP_DEVICE (self), &print);
792 1 fpi_device_enroll_complete (FP_DEVICE (self), g_object_ref (print), NULL);
793 1 self->task_ssm = NULL;
794 }
795
796 static void
797 1 fp_init_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
798 {
799 1 FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (dev);
800
801 1 fp_info ("Init complete!");
802
803
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (fpi_ssm_get_error (ssm))
804 error = fpi_ssm_get_error (ssm);
805
806 1 fpi_device_open_complete (dev, error);
807 1 self->task_ssm = NULL;
808 1 }
809
810 static void
811 1 fp_delete_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
812 {
813 1 FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (dev);
814
815 1 fp_info ("Delete print complete!");
816
817
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (fpi_ssm_get_error (ssm))
818 error = fpi_ssm_get_error (ssm);
819
820 1 fpi_device_delete_complete (dev, error);
821 1 self->task_ssm = NULL;
822 1 }
823
824 static void
825 9 fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
826 {
827 9 FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (device);
828 9 guint8 *cmd_buf = NULL;
829
830
5/6
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
9 switch (fpi_ssm_get_cur_state (ssm))
831 {
832 2 case FP_RTK_VERIFY_CAPTURE:
833 2 fpi_device_report_finger_status_changes (device,
834 FP_FINGER_STATUS_NEEDED,
835 FP_FINGER_STATUS_NONE);
836
837 2 cmd_buf = (guint8 *) &co_start_capture;
838 2 realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 1, fp_task_ssm_generic_cb);
839 2 break;
840
841 2 case FP_RTK_VERIFY_FINISH_CAPTURE:
842 2 cmd_buf = (guint8 *) &co_finish_capture;
843 2 realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 1, fp_finish_capture_cb);
844 2 break;
845
846 2 case FP_RTK_VERIFY_ACCEPT_SAMPLE:
847 2 co_accept_sample.param[0] = self->fp_purpose;
848 2 cmd_buf = (guint8 *) &co_accept_sample;
849 2 realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT_NO_STATUS, 1, fp_accept_sample_cb);
850 2 break;
851
852 2 case FP_RTK_VERIFY_INDENTIFY_FEATURE:
853 2 cmd_buf = (guint8 *) &tls_identify_feature;
854 2 realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT_NO_STATUS, 0, fp_identify_feature_cb);
855 2 break;
856
857 1 case FP_RTK_VERIFY_UPDATE_TEMPLATE:
858 1 cmd_buf = (guint8 *) &co_update_template;
859 1 realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 0, fp_task_ssm_generic_cb);
860 1 break;
861 }
862 9 }
863
864 static void
865 31 fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
866 {
867 62 g_autofree gchar *user_id = NULL;
868 31 g_autofree guint8 *payload = NULL;
869 31 FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (device);
870 31 FpPrint *print = NULL;
871 31 guint8 *cmd_buf = NULL;
872 31 guint8 *trans_id = NULL;
873 31 GVariant *uid = NULL;
874 31 GVariant *data = NULL;
875 31 gsize user_id_len;
876 31 guint finger;
877
878
7/8
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 9 times.
✓ Branch 6 taken 9 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 1 times.
31 switch (fpi_ssm_get_cur_state (ssm))
879 {
880 1 case FP_RTK_ENROLL_GET_TEMPLATE:
881
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 g_assert (self->template_num > 0);
882
883 1 co_get_template.data_len[0] = GET_LEN_L (TEMPLATE_LEN * self->template_num);
884 1 co_get_template.data_len[1] = GET_LEN_H (TEMPLATE_LEN * self->template_num);
885
886 1 cmd_buf = (guint8 *) &co_get_template;
887 1 realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 0, fp_get_template_cb);
888 1 break;
889
890 1 case FP_RTK_ENROLL_BEGIN_POS:
891 1 tls_enroll_begin.param[0] = self->pos_index;
892 1 cmd_buf = (guint8 *) &tls_enroll_begin;
893 1 realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 0, fp_task_ssm_generic_cb);
894 1 break;
895
896 9 case FP_RTK_ENROLL_CAPTURE:
897 9 fpi_device_report_finger_status_changes (device,
898 FP_FINGER_STATUS_NEEDED,
899 FP_FINGER_STATUS_NONE);
900
901 9 cmd_buf = (guint8 *) &co_start_capture;
902 9 realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 1, fp_task_ssm_generic_cb);
903 9 break;
904
905 9 case FP_RTK_ENROLL_FINISH_CAPTURE:
906 9 cmd_buf = (guint8 *) &co_finish_capture;
907 9 realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 1, fp_finish_capture_cb);
908 9 break;
909
910 9 case FP_RTK_ENROLL_ACCEPT_SAMPLE:
911 9 co_accept_sample.param[0] = self->fp_purpose;
912 9 cmd_buf = (guint8 *) &co_accept_sample;
913 9 realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT_NO_STATUS, 1, fp_accept_sample_cb);
914 9 break;
915
916 1 case FP_RTK_ENROLL_CHECK_DUPLICATE:
917 1 cmd_buf = (guint8 *) &co_check_duplicate;
918 1 realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT_NO_STATUS, 1, fp_check_duplicate_cb);
919 1 break;
920
921 1 case FP_RTK_ENROLL_COMMIT:
922 1 fpi_device_get_enroll_data (device, &print);
923 1 user_id = fpi_print_generate_user_id (print);
924 1 user_id_len = strlen (user_id);
925 1 user_id_len = MIN (DEFAULT_UID_LEN, user_id_len);
926
927 1 payload = g_malloc0 (UID_PAYLOAD_LEN);
928 1 memcpy (payload, user_id, user_id_len);
929
930 1 trans_id = g_steal_pointer (&payload);
931
932 1 finger = SUB_FINGER_01;
933 1 uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
934 user_id,
935 user_id_len,
936 1);
937 1 data = g_variant_new ("(y@ay)",
938 finger,
939 uid);
940
941 1 fpi_print_set_type (print, FPI_PRINT_RAW);
942 1 fpi_print_set_device_stored (print, TRUE);
943 1 g_object_set (print, "fpi-data", data, NULL);
944 1 g_object_set (print, "description", user_id, NULL);
945
946 1 g_debug ("user_id: %s, finger: 0x%x", user_id, finger);
947
948 1 tls_enroll_commit.param[0] = SUB_FINGER_01;
949 1 cmd_buf = (guint8 *) &tls_enroll_commit;
950 1 realtek_sensor_cmd (self, cmd_buf, trans_id, FP_RTK_MSG_PLAINTEXT, 0, fp_task_ssm_generic_cb);
951 1 break;
952 }
953 31 }
954
955 static void
956 2 fp_init_sm_run_state (FpiSsm *ssm, FpDevice *device)
957 {
958 2 FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (device);
959 2 guint8 *cmd_buf = NULL;
960
961
2/3
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 switch (fpi_ssm_get_cur_state (ssm))
962 {
963 1 case FP_RTK_INIT_SELECT_OS:
964 1 co_select_system.param[0] = 0x01;
965 1 cmd_buf = (guint8 *) &co_select_system;
966 1 realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 0, fp_task_ssm_generic_cb);
967 1 break;
968
969 1 case FP_RTK_INIT_GET_ENROLL_NUM:
970 1 cmd_buf = (guint8 *) &co_get_enroll_num;
971 1 realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 0, fp_get_enroll_num_cb);
972 1 break;
973 }
974 2 }
975
976 static void
977 2 fp_delete_sm_run_state (FpiSsm *ssm, FpDevice *device)
978 {
979 2 FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (device);
980 2 guint8 *cmd_buf = NULL;
981
982
2/3
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 switch (fpi_ssm_get_cur_state (ssm))
983 {
984 1 case FP_RTK_DELETE_GET_POS:
985
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 g_assert (self->template_num > 0);
986
987 1 co_get_template.data_len[0] = GET_LEN_L (TEMPLATE_LEN * self->template_num);
988 1 co_get_template.data_len[1] = GET_LEN_H (TEMPLATE_LEN * self->template_num);
989
990 1 cmd_buf = (guint8 *) &co_get_template;
991 1 realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 0, fp_get_delete_pos_cb);
992 1 break;
993
994 1 case FP_RTK_DELETE_PRINT:
995 1 co_delete_record.param[0] = self->pos_index;
996 1 cmd_buf = (guint8 *) &co_delete_record;
997 1 realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 0, fp_task_ssm_generic_cb);
998 1 break;
999 }
1000 2 }
1001
1002
1003 static void
1004 2 identify_verify (FpDevice *device)
1005 {
1006 2 FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (device);
1007 2 FpiDeviceAction current_action;
1008
1009 2 G_DEBUG_HERE ();
1010 2 current_action = fpi_device_get_current_action (device);
1011
1012
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 g_assert (current_action == FPI_DEVICE_ACTION_VERIFY ||
1013 current_action == FPI_DEVICE_ACTION_IDENTIFY);
1014
1015
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (current_action == FPI_DEVICE_ACTION_IDENTIFY)
1016 1 self->fp_purpose = FP_RTK_PURPOSE_IDENTIFY;
1017 else
1018 1 self->fp_purpose = FP_RTK_PURPOSE_VERIFY;
1019
1020
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 g_assert (!self->task_ssm);
1021
1022 2 self->task_ssm = fpi_ssm_new_full (device,
1023 fp_verify_sm_run_state,
1024 FP_RTK_VERIFY_NUM_STATES,
1025 FP_RTK_VERIFY_NUM_STATES,
1026 "Verify & Identify");
1027
1028 2 fpi_ssm_start (self->task_ssm, fp_verify_ssm_done);
1029 2 }
1030
1031 static void
1032 1 enroll (FpDevice *device)
1033 {
1034 1 FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (device);
1035
1036 1 G_DEBUG_HERE ();
1037 1 self->enroll_stage = 0;
1038 1 self->fp_purpose = FP_RTK_PURPOSE_ENROLL;
1039
1040
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 g_assert (!self->task_ssm);
1041
1042 1 self->task_ssm = fpi_ssm_new_full (device,
1043 fp_enroll_sm_run_state,
1044 FP_RTK_ENROLL_NUM_STATES,
1045 FP_RTK_ENROLL_NUM_STATES,
1046 "Enroll");
1047
1048 1 fpi_ssm_start (self->task_ssm, fp_enroll_ssm_done);
1049 1 }
1050
1051 static void
1052 1 dev_probe (FpDevice *device)
1053 {
1054 1 GUsbDevice *usb_dev;
1055 1 GError *error = NULL;
1056 1 g_autofree gchar *product = NULL;
1057 1 FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (device);
1058
1059 1 G_DEBUG_HERE ();
1060 /* Claim usb interface */
1061 1 usb_dev = fpi_device_get_usb_device (device);
1062
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (!g_usb_device_open (usb_dev, &error))
1063 {
1064 fpi_device_probe_complete (device, NULL, NULL, error);
1065 return;
1066 }
1067
1068
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (!g_usb_device_reset (usb_dev, &error))
1069 {
1070 g_usb_device_close (usb_dev, NULL);
1071 fpi_device_probe_complete (device, NULL, NULL, error);
1072 return;
1073 }
1074
1075
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (!g_usb_device_claim_interface (usb_dev, 0, 0, &error))
1076 {
1077 g_usb_device_close (usb_dev, NULL);
1078 fpi_device_probe_complete (device, NULL, NULL, error);
1079 return;
1080 }
1081
1082 1 product = g_usb_device_get_string_descriptor (usb_dev,
1083 1 g_usb_device_get_product_index (usb_dev),
1084 &error);
1085
1086
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (product)
1087 1 fp_dbg ("Device name: %s", product);
1088
1089 1 self->max_enroll_stage = MAX_ENROLL_SAMPLES;
1090 1 fpi_device_set_nr_enroll_stages (device, self->max_enroll_stage);
1091
1092 1 g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (device)), 0, 0, NULL);
1093 1 g_usb_device_close (usb_dev, NULL);
1094
1095 1 fpi_device_probe_complete (device, NULL, product, error);
1096 }
1097
1098 static void
1099 1 dev_init (FpDevice *device)
1100 {
1101 1 FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (device);
1102 1 GError *error = NULL;
1103
1104 1 G_DEBUG_HERE ();
1105
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (!g_usb_device_reset (fpi_device_get_usb_device (device), &error))
1106 {
1107 fpi_device_open_complete (FP_DEVICE (self), error);
1108 return;
1109 }
1110
1111 /* Claim usb interface */
1112
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (!g_usb_device_claim_interface (fpi_device_get_usb_device (device), 0, 0, &error))
1113 {
1114 fpi_device_open_complete (FP_DEVICE (self), error);
1115 return;
1116 }
1117
1118
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 g_assert (!self->task_ssm);
1119
1120 1 self->task_ssm = fpi_ssm_new_full (device,
1121 fp_init_sm_run_state,
1122 FP_RTK_INIT_NUM_STATES,
1123 FP_RTK_INIT_NUM_STATES,
1124 "Init");
1125
1126 1 fpi_ssm_start (self->task_ssm, fp_init_ssm_done);
1127 }
1128
1129 static void
1130 1 dev_exit (FpDevice *device)
1131 {
1132 1 FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (device);
1133
1134 2 g_autoptr(GError) release_error = NULL;
1135
1136 1 G_DEBUG_HERE ();
1137
1138 1 g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (self)), 0, 0, &release_error);
1139
1140
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 fpi_device_close_complete (device, release_error);
1141 1 }
1142
1143 static void
1144 1 delete_print (FpDevice *device)
1145 {
1146 1 FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (device);
1147
1148 1 G_DEBUG_HERE ();
1149
1150
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 g_assert (!self->task_ssm);
1151
1152 1 self->task_ssm = fpi_ssm_new_full (device,
1153 fp_delete_sm_run_state,
1154 FP_RTK_DELETE_NUM_STATES,
1155 FP_RTK_DELETE_NUM_STATES,
1156 "Delete print");
1157
1158 1 fpi_ssm_start (self->task_ssm, fp_delete_ssm_done);
1159 1 }
1160
1161 static void
1162 1 clear_storage (FpDevice *device)
1163 {
1164 1 FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (device);
1165 1 guint8 *cmd_buf = NULL;
1166
1167 1 G_DEBUG_HERE ();
1168 1 co_delete_record.param[0] = 0xff;
1169 1 cmd_buf = (guint8 *) &co_delete_record;
1170 1 realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 0, fp_clear_storage_cb);
1171 1 }
1172
1173 static void
1174 1 list_print (FpDevice *device)
1175 {
1176 1 FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (device);
1177 1 guint8 *cmd_buf = NULL;
1178
1179 1 G_DEBUG_HERE ();
1180
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 g_assert (self->template_num > 0);
1181
1182 1 co_get_template.data_len[0] = GET_LEN_L (TEMPLATE_LEN * self->template_num);
1183 1 co_get_template.data_len[1] = GET_LEN_H (TEMPLATE_LEN * self->template_num);
1184
1185 1 cmd_buf = (guint8 *) &co_get_template;
1186 1 realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 1, fp_list_cb);
1187 1 }
1188
1189 static void
1190 1 fpi_device_realtek_init (FpiDeviceRealtek *self)
1191 {
1192 1 }
1193
1194 static void
1195 117 fpi_device_realtek_class_init (FpiDeviceRealtekClass *klass)
1196 {
1197 117 FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
1198
1199 117 dev_class->id = FP_COMPONENT;
1200 117 dev_class->full_name = "Realtek MOC Fingerprint Sensor";
1201
1202 117 dev_class->type = FP_DEVICE_TYPE_USB;
1203 117 dev_class->scan_type = FP_SCAN_TYPE_PRESS;
1204 117 dev_class->id_table = id_table;
1205 117 dev_class->nr_enroll_stages = MAX_ENROLL_SAMPLES;
1206 117 dev_class->temp_hot_seconds = -1;
1207
1208 117 dev_class->open = dev_init;
1209 117 dev_class->close = dev_exit;
1210 117 dev_class->probe = dev_probe;
1211 117 dev_class->verify = identify_verify;
1212 117 dev_class->identify = identify_verify;
1213 117 dev_class->enroll = enroll;
1214 117 dev_class->delete = delete_print;
1215 117 dev_class->clear_storage = clear_storage;
1216 117 dev_class->list = list_print;
1217
1218 117 fpi_device_class_auto_initialize_features (dev_class);
1219 117 }
1220