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 |