GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 72.7% 966 / 0 / 1328
Functions: 91.2% 83 / 0 / 91
Branches: 48.6% 277 / 0 / 570

libfprint/drivers/mafpmoc/mafpmoc.c
Line Branch Exec Source
1 #define FP_COMPONENT "mafpmoc"
2
3 #include "glib.h"
4 #include "drivers_api.h"
5 #include "mafpmoc.h"
6 #include "fpi-byte-writer.h"
7
8 struct _FpiDeviceMafpmoc
9 {
10 FpDevice parent;
11 FpiSsm *task_ssm;
12 FpiSsm *cmd_ssm;
13 FpiUsbTransfer *cmd_transfer;
14 gboolean cmd_cancelable;
15 gboolean cmd_force_pass;
16 int enroll_stage;
17 int max_stored_prints;
18 uint8_t interface_num;
19 uint8_t press_state;
20 uint32_t finger_status;
21 char *serial_number;
22 uint16_t enroll_id;
23 char *enroll_user_id;
24 unsigned enroll_identify_index;
25 uint16_t enroll_identify_id;
26 uint8_t enroll_identify_state;
27 uint8_t enroll_dupl_del_state;
28 uint8_t enroll_dupl_area_state;
29 pmafp_templates_t templates;
30 uint16_t search_id;
31 unsigned capture_cnt;
32 FpPrint *identify_new_print;
33 FpPrint *identify_match_print;
34 };
35
36
4/6
fpi_device_mafpmoc_class_intern_init:
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 125 times.
fpi_device_mafpmoc_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 (FpiDeviceMafpmoc, fpi_device_mafpmoc, FP_TYPE_DEVICE)
37
38 typedef void (*SynCmdMsgCallback) (FpiDeviceMafpmoc *self,
39 mafp_cmd_response_t *resp,
40 GError *error);
41
42 typedef struct
43 {
44 uint16_t cmd;
45 SynCmdMsgCallback callback;
46 FpiUsbTransfer *cmd_transfer;
47 gboolean cmd_cancelable;
48 uint16_t cmd_request_len;
49 uint16_t cmd_actual_len;
50 uint8_t recv_buffer[MAFP_USB_BUFFER_SIZE];
51 gboolean cmd_force_pass;
52 uint16_t crc;
53 } CommandData;
54
55 static void mafp_sensor_cmd (FpiDeviceMafpmoc *self,
56 uint16_t cmd,
57 const uint8_t *data,
58 uint8_t data_len,
59 SynCmdMsgCallback callback);
60
61 static uint16_t
62 257 ma_protocol_crc16_calc ( uint8_t *data, uint32_t data_len, uint32_t start)
63 {
64 257 const uint8_t *temp = data;
65 257 uint32_t sum = 0;
66 257 uint32_t i;
67
68
4/4
✓ Branch 39 → 38 taken 905 times.
✓ Branch 39 → 40 taken 129 times.
✓ Branch 45 → 44 taken 1236 times.
✓ Branch 45 → 46 taken 128 times.
2398 for (i = start; i < data_len; temp++, i++)
69 2141 sum += *(temp + start) & 0xff;
70 257 uint16_t sum_s = (sum & 0xffff);
71
72 257 return sum_s;
73 }
74
75 /* data tansfer:
76 * while cmd_len = 0, put flag(end or not) in data[0]
77 */
78 static uint8_t *
79 129 ma_protocol_build_package (uint32_t package_len,
80 int16_t cmd,
81 uint8_t cmd_len,
82 const uint8_t *data,
83 uint32_t data_len)
84 {
85 258 g_autoptr(FpiByteWriter) writer = NULL;
86 129 uint8_t flag;
87 129 uint16_t frame_len;
88 129 uint16_t crc;
89 129 gboolean written;
90
91 129 writer = fpi_byte_writer_new_with_size (package_len, TRUE);
92
93
1/2
✓ Branch 4 → 5 taken 129 times.
✗ Branch 4 → 6 not taken.
129 written = fpi_byte_writer_put_uint8 (writer, 0xEF);
94
1/2
✓ Branch 7 → 8 taken 129 times.
✗ Branch 7 → 9 not taken.
129 written &= fpi_byte_writer_put_uint8 (writer, 0x01);
95
1/2
✓ Branch 10 → 11 taken 129 times.
✗ Branch 10 → 12 not taken.
129 written &= fpi_byte_writer_put_uint8 (writer, 0xFF);
96
1/2
✓ Branch 13 → 14 taken 129 times.
✗ Branch 13 → 15 not taken.
129 written &= fpi_byte_writer_put_uint8 (writer, 0xFF);
97
1/2
✓ Branch 16 → 17 taken 129 times.
✗ Branch 16 → 18 not taken.
129 written &= fpi_byte_writer_put_uint8 (writer, 0xFF);
98
1/2
✓ Branch 19 → 20 taken 129 times.
✗ Branch 19 → 21 not taken.
129 written &= fpi_byte_writer_put_uint8 (writer, 0xFF);
99
100 129 flag = (uint8_t) MAPF_PACK_CMD;
101
102
1/2
✗ Branch 21 → 22 not taken.
✓ Branch 21 → 23 taken 129 times.
129 if (!cmd_len && data_len)
103 flag = data[0];
104
105 129 fpi_byte_writer_put_uint8 (writer, flag);
106
107 129 frame_len = package_len - PACKAGE_HEADER_SIZE;
108
109
1/2
✓ Branch 25 → 26 taken 129 times.
✗ Branch 25 → 27 not taken.
129 written &= fpi_byte_writer_put_uint16_be (writer, frame_len);
110
111
1/2
✓ Branch 27 → 28 taken 129 times.
✗ Branch 27 → 32 not taken.
129 if (cmd_len)
112
1/2
✓ Branch 29 → 30 taken 129 times.
✗ Branch 29 → 31 not taken.
129 written &= fpi_byte_writer_put_uint8 (writer, cmd);
113
114
2/2
✓ Branch 32 → 33 taken 72 times.
✓ Branch 32 → 37 taken 57 times.
129 if (data_len)
115
1/2
✓ Branch 34 → 35 taken 72 times.
✗ Branch 34 → 36 not taken.
72 written &= fpi_byte_writer_put_data (writer, data + !cmd_len, data_len);
116
117 258 crc = ma_protocol_crc16_calc ((uint8_t *) writer->parent.data,
118 129 PACKAGE_HEADER_SIZE + cmd_len + data_len,
119 6);
120
121
1/2
✓ Branch 41 → 42 taken 129 times.
✗ Branch 41 → 43 not taken.
129 written &= fpi_byte_writer_put_uint16_be (writer, crc);
122
123
1/2
✗ Branch 42 → 43 not taken.
✓ Branch 42 → 45 taken 129 times.
129 if (!written)
124 g_return_val_if_reached (NULL);
125
126 129 return fpi_byte_writer_free_and_get_data (g_steal_pointer (&writer));
127 }
128
129 static int
130 128 ma_protocol_parse_header ( uint8_t *buffer,
131 uint32_t buffer_len,
132 pack_header *pheader)
133 {
134
2/4
✓ Branch 2 → 3 taken 128 times.
✗ Branch 2 → 5 not taken.
✓ Branch 3 → 4 taken 128 times.
✗ Branch 3 → 5 not taken.
128 if (!buffer || !pheader || buffer_len < PACKAGE_HEADER_SIZE)
135 return -1;
136
137 128 memcpy (pheader, buffer, sizeof (pack_header));
138 128 return 0;
139 }
140
141 static uint8_t
142 1280 get_one_bit_value ( uint8_t src,
143 uint8_t bit_num)
144 {
145 1280 return (uint8_t) ((src >> (bit_num - 1)) & 1);
146 }
147
148 static int
149 128 ma_protocol_parse_body ( int16_t cmd,
150 uint8_t *buffer,
151 uint16_t buffer_len,
152 pmafp_cmd_response_t presp)
153 {
154 128 const int data_len = buffer_len - 1 - PACKAGE_CRC_SIZE;
155
156
2/4
✓ Branch 2 → 3 taken 128 times.
✗ Branch 2 → 22 not taken.
✓ Branch 3 → 4 taken 128 times.
✗ Branch 3 → 22 not taken.
128 if (!buffer || !presp || buffer_len < 1)
157 return -1;
158
159 128 presp->result = buffer[0];
160
161
6/7
✓ Branch 4 → 5 taken 1 time.
✓ Branch 4 → 7 taken 12 times.
✗ Branch 4 → 9 not taken.
✓ Branch 4 → 11 taken 5 times.
✓ Branch 4 → 17 taken 4 times.
✓ Branch 4 → 19 taken 3 times.
✓ Branch 4 → 21 taken 103 times.
128 switch (cmd)
162 {
163 1 case MOC_CMD_HANDSHAKE:
164
1/2
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 22 not taken.
1 if (data_len >= sizeof (mafp_handshake_t))
165 1 memcpy (&presp->handshake, buffer + 1, sizeof (mafp_handshake_t));
166 break;
167
168 12 case MOC_CMD_SEARCH:
169
1/2
✓ Branch 7 → 8 taken 12 times.
✗ Branch 7 → 22 not taken.
12 if (data_len >= sizeof (mafp_search_t))
170 12 memcpy (&presp->search, buffer + 1, sizeof (mafp_search_t));
171 break;
172
173 case MOC_CMD_GET_TEMPLATE_NUM:
174 if (data_len >= 2)
175 presp->tpl_table.used_num = ((buffer[1] & 0xff) << 8) | (buffer[2] & 0xff);
176 break;
177
178 5 case MOC_CMD_GET_TEMPLATE_TABLE:
179
1/2
✓ Branch 11 → 16 taken 5 times.
✗ Branch 11 → 22 not taken.
5 if (data_len >= 32)
180 {
181 uint16_t num = 0;
182
2/2
✓ Branch 16 → 12 taken 160 times.
✓ Branch 16 → 22 taken 5 times.
165 for (uint8_t i = 1; i < 33; i++)
183 {
184 160 uint8_t data = buffer[i];
185
2/2
✓ Branch 14 → 13 taken 1280 times.
✓ Branch 14 → 15 taken 160 times.
1440 for (uint8_t bit = 1; bit <= 8 && num < sizeof (presp->tpl_table.list); bit++, num++)
186 1280 presp->tpl_table.list[num] = get_one_bit_value (data, bit);
187 }
188 }
189 break;
190
191 4 case MOC_CMD_GET_TEMPLATE_INFO:
192
1/2
✓ Branch 17 → 18 taken 4 times.
✗ Branch 17 → 22 not taken.
4 if (data_len >= 128)
193 4 memcpy (&presp->tpl_info, buffer + 1, sizeof (mafp_tpl_info_t));
194 break;
195
196 3 case MOC_CMD_DUPAREA_TEST:
197
1/2
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 22 taken 3 times.
3 if (data_len >= 1)
198 presp->result = buffer[1];
199 break;
200
201 103 default:
202 103 memcpy (presp, buffer, MIN ((gsize) buffer_len, sizeof (*presp)));
203 103 break;
204 }
205 return 0;
206 }
207
208 static void
209 mafp_clean_usb_bulk_in (FpDevice *device)
210 {
211 g_autoptr(FpiUsbTransfer) transfer = fpi_usb_transfer_new (device);
212 fpi_usb_transfer_fill_bulk (transfer, MAFP_EP_BULK_IN, MAFP_USB_BUFFER_SIZE);
213 g_autoptr(GError) error = NULL;
214
215 fp_dbg ("bulk clean");
216 if (!fpi_usb_transfer_submit_sync (transfer, 200, &error))
217 fp_dbg ("bulk transfer out fail, %s", error->message);
218 }
219
220 static G_GNUC_PRINTF (4, 5) void
221 mafp_mark_failed (FpDevice *dev,
222 FpiSsm *ssm,
223 uint8_t err_code,
224 const char *msg,
225 ...)
226 {
227 if (err_code == FP_DEVICE_ERROR_PROTO)
228 mafp_clean_usb_bulk_in (dev);
229
230 if (msg == NULL)
231 {
232 fpi_ssm_mark_failed (ssm, fpi_device_error_new (err_code));
233 }
234 else
235 {
236 va_list args;
237 va_start (args, msg);
238 fpi_ssm_mark_failed (ssm, g_error_new_valist (FP_DEVICE_ERROR, err_code, msg, args));
239 va_end (args);
240 }
241 }
242
243 static void
244 128 fp_cmd_receive_cb (FpiUsbTransfer *transfer,
245 FpDevice *device,
246 gpointer user_data,
247 GError *error)
248 {
249 128 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
250 128 CommandData *data = user_data;
251 128 int ret = -1, ssm_state = 0;
252 128 mafp_cmd_response_t cmd_reponse = {0, };
253 128 pack_header header;
254 128 uint32_t data_index = 0;
255
256
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 12 taken 128 times.
128 if (error)
257 {
258 fp_dbg ("error: %d, %s", error->code, error->message);
259 if (data->cmd_force_pass) /* ex: G_USB_DEVICE_ERROR_TIMED_OUT */
260 {
261 if (data->callback)
262 data->callback (self, &cmd_reponse, NULL);
263 fpi_ssm_mark_completed (transfer->ssm);
264 g_clear_error (&error);
265 return;
266 }
267 fpi_ssm_mark_failed (transfer->ssm, g_steal_pointer (&error));
268 return;
269 }
270
1/2
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 16 taken 128 times.
128 if (data == NULL)
271 {
272 fp_dbg ("data null");
273 mafp_mark_failed (device, transfer->ssm, FP_DEVICE_ERROR_PROTO, "resp data null");
274 return;
275 }
276 128 ssm_state = fpi_ssm_get_cur_state (transfer->ssm);
277
278 /* skip zero length package */
279
1/2
✗ Branch 17 → 18 not taken.
✓ Branch 17 → 20 taken 128 times.
128 if (transfer->actual_length == 0)
280 {
281 fpi_ssm_jump_to_state (transfer->ssm, ssm_state);
282 return;
283 }
284
285
1/2
✓ Branch 20 → 21 taken 128 times.
✗ Branch 20 → 32 not taken.
128 if (ssm_state == MAPF_CMD_RECEIVE)
286 {
287 128 ret = ma_protocol_parse_header (transfer->buffer, transfer->actual_length, &header);
288
2/4
✓ Branch 22 → 23 taken 128 times.
✗ Branch 22 → 24 not taken.
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 26 taken 128 times.
128 if (ret != 0 || header.flag != MAPF_PACK_ANSWER)
289 {
290 mafp_mark_failed (device, transfer->ssm, FP_DEVICE_ERROR_PROTO, "Corrupted resp header received");
291 return;
292 }
293 128 data->cmd_request_len = ((header.frame_len0 & 0xff) << 8) | (header.frame_len1 & 0xff);
294
1/2
✗ Branch 26 → 27 not taken.
✓ Branch 26 → 29 taken 128 times.
128 if (!data->cmd_request_len)
295 {
296 mafp_mark_failed (device, transfer->ssm, FP_DEVICE_ERROR_PROTO, "Corrupted resp length received");
297 return;
298 }
299
1/2
✗ Branch 29 → 30 not taken.
✓ Branch 29 → 32 taken 128 times.
128 if (data->cmd_request_len + PACKAGE_HEADER_SIZE > sizeof (data->recv_buffer))
300 {
301 mafp_mark_failed (device, transfer->ssm, FP_DEVICE_ERROR_PROTO, "Resp length too large");
302 return;
303 }
304 data_index = PACKAGE_HEADER_SIZE;
305 }
306
1/2
✗ Branch 32 → 33 not taken.
✓ Branch 32 → 35 taken 128 times.
128 if (transfer->actual_length < data_index)
307 {
308 mafp_mark_failed (device, transfer->ssm, FP_DEVICE_ERROR_PROTO, "Corrupted resp payload received");
309 return;
310 }
311
1/2
✗ Branch 35 → 36 not taken.
✓ Branch 35 → 38 taken 128 times.
128 if (data->cmd_actual_len + transfer->actual_length > sizeof (data->recv_buffer))
312 {
313 mafp_mark_failed (device, transfer->ssm, FP_DEVICE_ERROR_PROTO, "Resp data overflow");
314 return;
315 }
316 128 memcpy (data->recv_buffer + data->cmd_actual_len, transfer->buffer, transfer->actual_length);
317 128 data->cmd_actual_len += transfer->actual_length - data_index;
318
319
1/2
✓ Branch 38 → 39 taken 128 times.
✗ Branch 38 → 53 not taken.
128 if (data->cmd_request_len <= data->cmd_actual_len)
320 {
321 128 ret = ma_protocol_parse_body (data->cmd, &data->recv_buffer[PACKAGE_HEADER_SIZE],
322 data->cmd_request_len, &cmd_reponse);
323
1/2
✗ Branch 40 → 41 not taken.
✓ Branch 40 → 43 taken 128 times.
128 if (ret != 0)
324 {
325 mafp_mark_failed (device, transfer->ssm, FP_DEVICE_ERROR_PROTO, "Corrupted resp body received");
326 return;
327 }
328 128 uint32_t no_crc_len = PACKAGE_HEADER_SIZE + data->cmd_request_len - PACKAGE_CRC_SIZE;
329 128 data->crc = ma_protocol_crc16_calc (&data->recv_buffer[0], no_crc_len, 6);
330 128 uint16_t frame_crc = ((data->recv_buffer[no_crc_len] & 0xff) << 8)
331 128 | (data->recv_buffer[no_crc_len + 1] & 0xff);
332
1/2
✗ Branch 46 → 47 not taken.
✓ Branch 46 → 49 taken 128 times.
128 if (data->crc != frame_crc)
333 {
334 mafp_mark_failed (device, transfer->ssm, FP_DEVICE_ERROR_PROTO, "Package crc check failed");
335 return;
336 }
337
1/2
✓ Branch 49 → 50 taken 128 times.
✗ Branch 49 → 51 not taken.
128 if (data->callback)
338 128 data->callback (self, &cmd_reponse, NULL);
339 128 fpi_ssm_mark_completed (transfer->ssm);
340
341 }
342 else if (data->cmd_request_len > data->cmd_actual_len)
343 {
344 fpi_ssm_next_state (transfer->ssm);
345 return;
346 }
347 }
348
349 static void
350 257 fp_cmd_run_state (FpiSsm *ssm,
351 FpDevice *dev)
352 {
353 257 FpiUsbTransfer *transfer;
354 257 CommandData *data = fpi_ssm_get_data (ssm);
355
356
2/4
✓ Branch 4 → 5 taken 129 times.
✓ Branch 4 → 8 taken 128 times.
✗ Branch 4 → 18 not taken.
✗ Branch 4 → 32 not taken.
257 switch (fpi_ssm_get_cur_state (ssm))
357 {
358 129 case MAPF_CMD_SEND:
359
1/2
✓ Branch 5 → 6 taken 129 times.
✗ Branch 5 → 7 not taken.
129 if (data->cmd_transfer)
360 {
361 129 data->cmd_transfer->ssm = ssm;
362 129 fpi_usb_transfer_submit (g_steal_pointer (&data->cmd_transfer),
363 CMD_TIMEOUT, NULL, fpi_ssm_usb_transfer_cb, NULL);
364 }
365 else
366 {
367 fpi_ssm_next_state (ssm);
368 }
369 break;
370
371 128 case MAPF_CMD_RECEIVE:
372 128 transfer = fpi_usb_transfer_new (dev);
373 128 transfer->ssm = ssm;
374 128 fpi_usb_transfer_fill_bulk (transfer, MAFP_EP_BULK_IN, MAFP_USB_BUFFER_SIZE);
375 128 fpi_usb_transfer_submit (transfer,
376
3/4
✓ Branch 13 → 14 taken 128 times.
✗ Branch 13 → 16 not taken.
✓ Branch 14 → 15 taken 127 times.
✓ Branch 14 → 16 taken 1 time.
128 data->cmd_cancelable ? 0 : data->cmd_force_pass ? CTRL_TIMEOUT : CMD_TIMEOUT,
377
1/2
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 128 times.
128 data->cmd_cancelable ? fpi_device_get_cancellable (dev) : NULL,
378 fp_cmd_receive_cb,
379 fpi_ssm_get_data (ssm));
380 128 break;
381
382 case MAPF_CMD_DATA_RECEIVE:
383 fp_dbg ("req: %d, act: %d", data->cmd_request_len, data->cmd_actual_len);
384 int req_len = MAFP_USB_BUFFER_SIZE;
385 if (data->cmd_request_len > 0 && data->cmd_actual_len > 0 && (data->cmd_request_len > data->cmd_actual_len))
386 req_len = data->cmd_request_len - data->cmd_actual_len;
387 transfer = fpi_usb_transfer_new (dev);
388 transfer->ssm = ssm;
389 fpi_usb_transfer_fill_bulk (transfer, MAFP_EP_BULK_IN, req_len);
390 fpi_usb_transfer_submit (transfer,
391 data->cmd_cancelable ? 0 : DATA_TIMEOUT,
392 data->cmd_cancelable ? fpi_device_get_cancellable (dev) : NULL,
393 fp_cmd_receive_cb,
394 fpi_ssm_get_data (ssm));
395 break;
396 }
397 257 }
398
399 static void
400 129 fp_cmd_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
401 {
402 129 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (dev);
403 129 CommandData *data = fpi_ssm_get_data (ssm);
404
405 129 self->cmd_ssm = NULL;
406
2/2
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 7 taken 128 times.
129 if (error)
407 {
408
1/2
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 6 not taken.
1 if (data->callback)
409 1 data->callback (self, NULL, error);
410 else
411 g_error_free (error);
412 }
413 129 }
414
415 static void
416 129 fp_cmd_ssm_done_data_free (CommandData *data)
417 {
418 129 g_free (data);
419 129 }
420
421 static FpiUsbTransfer *
422 129 alloc_cmd_transfer (FpiDeviceMafpmoc *self,
423 uint16_t cmd,
424 uint8_t cmd_len,
425 const uint8_t *data,
426 uint32_t data_len)
427 {
428 129 g_autoptr(FpiUsbTransfer) transfer = fpi_usb_transfer_new (FP_DEVICE (self));
429 129 uint32_t total_len = PACKAGE_HEADER_SIZE + cmd_len + data_len + PACKAGE_CRC_SIZE;
430 129 uint8_t *buffer;
431
432
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 129 times.
129 g_return_val_if_fail (data || data_len == 0, NULL);
433
434 129 buffer = ma_protocol_build_package (total_len, cmd, cmd_len, data, data_len);
435
1/2
✓ Branch 6 → 7 taken 129 times.
✗ Branch 6 → 8 not taken.
129 g_return_val_if_fail (buffer, NULL);
436
437 129 fpi_usb_transfer_fill_bulk_full (transfer, MAFP_EP_BULK_OUT, buffer, total_len, g_free);
438 129 return g_steal_pointer (&transfer);
439 }
440
441 static void
442 129 mafp_sensor_cmd (FpiDeviceMafpmoc *self,
443 uint16_t cmd,
444 const uint8_t *data,
445 uint8_t data_len,
446 SynCmdMsgCallback callback)
447 {
448 129 g_autoptr(FpiUsbTransfer) transfer = NULL;
449 129 CommandData *cmd_data = NULL;
450
451
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 9 taken 129 times.
129 if (!(transfer = alloc_cmd_transfer (self, cmd, 1, data, data_len)))
452 {
453 g_critical ("Failed to allocate command transfer");
454
455 if (callback)
456 callback (self, NULL, g_error_new (FP_DEVICE_ERROR, FP_DEVICE_ERROR_PROTO,
457 "Failed to allocate command transfer"));
458
459 return;
460 }
461
462 129 cmd_data = g_new0 (CommandData, 1);
463 129 cmd_data->cmd = cmd;
464 129 cmd_data->callback = callback;
465 129 cmd_data->cmd_transfer = g_steal_pointer (&transfer);
466 129 cmd_data->cmd_cancelable = FALSE;
467 129 cmd_data->cmd_force_pass = self->cmd_force_pass;
468 129 cmd_data->cmd_request_len = 0;
469 129 cmd_data->cmd_actual_len = 0;
470 129 self->cmd_force_pass = FALSE;
471
472 129 self->cmd_ssm = fpi_ssm_new (FP_DEVICE (self), fp_cmd_run_state, MAPF_CMD_TRANSFER_STATES);
473 129 if (!PRINT_SSM_DEBUG)
474 129 fpi_ssm_silence_debug (self->cmd_ssm);
475 129 fpi_ssm_set_data (self->cmd_ssm, cmd_data, (GDestroyNotify) fp_cmd_ssm_done_data_free);
476 129 fpi_ssm_start (self->cmd_ssm, fp_cmd_ssm_done);
477 }
478
479 static void
480 36 mafp_sensor_control (FpiDeviceMafpmoc *self,
481 uint8_t request,
482 uint16_t value,
483 FpiUsbTransferCallback callback,
484 gpointer user_data,
485 uint16_t timeout)
486 {
487 36 FpiUsbTransfer *transfer = fpi_usb_transfer_new (FP_DEVICE (self));
488
489 36 transfer->ssm = self->task_ssm;
490 36 fpi_usb_transfer_fill_control (transfer,
491 G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST,
492 G_USB_DEVICE_REQUEST_TYPE_VENDOR,
493 G_USB_DEVICE_RECIPIENT_DEVICE, request, value, 0, 1);
494
2/2
✓ Branch 4 → 5 taken 3 times.
✓ Branch 4 → 6 taken 33 times.
39 fpi_usb_transfer_submit (transfer, timeout ? timeout : CTRL_TIMEOUT, NULL, callback, user_data);
495 36 return;
496 }
497
498 static mafp_template_t
499 8 mafp_template_from_print (FpPrint *print)
500 {
501 16 g_autoptr(GVariant) data = NULL;
502
1/2
✓ Branch 19 → 20 taken 8 times.
✗ Branch 19 → 21 not taken.
8 g_autoptr(GVariant) tpl_uid = NULL;
503
1/2
✓ Branch 17 → 18 taken 8 times.
✗ Branch 17 → 19 not taken.
8 g_autoptr(GVariant) dev_sn = NULL;
504 8 uint16_t tpl_id = 0;
505 8 const char *user_id;
506 8 const char *serial_num;
507 8 gsize user_id_len = 0;
508 8 gsize serial_num_len = 0;
509 8 mafp_template_t template = { 0, };
510
511 8 g_object_get (print, "fpi-data", &data, NULL);
512
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 8 times.
8 if (!data)
513 return template;
514
515 8 g_variant_get (data, "(q@ay@ay)", &tpl_id, &tpl_uid, &dev_sn);
516 8 user_id = g_variant_get_fixed_array (tpl_uid, &user_id_len, 1);
517 8 serial_num = g_variant_get_fixed_array (dev_sn, &serial_num_len, 1);
518
519 8 template.id = tpl_id;
520 8 memset (template.uid, 0, TEMPLATE_UID_SIZE);
521
2/4
✓ Branch 8 → 9 taken 8 times.
✗ Branch 8 → 11 not taken.
✓ Branch 9 → 10 taken 8 times.
✗ Branch 9 → 11 not taken.
8 if (user_id && user_id_len > 0)
522 8 memcpy (template.uid, user_id, MIN (user_id_len, sizeof (template.uid) - 1));
523 8 memset (template.sn, 0, DEVICE_SN_SIZE);
524
2/4
✓ Branch 11 → 12 taken 8 times.
✗ Branch 11 → 14 not taken.
✓ Branch 12 → 13 taken 8 times.
✗ Branch 12 → 14 not taken.
8 if (serial_num && serial_num_len > 0)
525 8 memcpy (template.sn, serial_num, MIN (serial_num_len, sizeof (template.sn) - 1));
526
527 8 return template;
528 }
529
530 static FpPrint *
531 3 mafp_print_from_template (FpiDeviceMafpmoc *self, mafp_template_t *template)
532 {
533 3 FpPrint *print;
534 3 GVariant *data;
535 3 GVariant *uid;
536 3 GVariant *dev_sn;
537 3 g_autofree char *uid_str = g_strndup (template->uid, TEMPLATE_UID_SIZE);
538
1/2
✓ Branch 3 → 4 taken 3 times.
✗ Branch 3 → 5 not taken.
3 const char *serial = self->serial_number ? self->serial_number : "";
539 3 unsigned user_id_len = strlen (uid_str);
540 3 unsigned serial_num_len = strnlen (serial, DEVICE_SN_SIZE);
541
542 3 print = fp_print_new (FP_DEVICE (self));
543
544 3 uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, uid_str, user_id_len, 1);
545
546 3 dev_sn = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, serial, serial_num_len, 1);
547 3 fp_dbg ("print: %d/%s/%s", template->id, uid_str, serial);
548
549 3 data = g_variant_new ("(q@ay@ay)", template->id, uid, dev_sn);
550
551 3 fpi_print_set_type (print, FPI_PRINT_RAW);
552 3 fpi_print_set_device_stored (print, true);
553 3 g_object_set (print, "description", uid_str, NULL);
554 3 g_object_set (print, "fpi-data", data, NULL);
555
556 3 fpi_print_fill_from_user_id (print, uid_str);
557
558 3 return print;
559 }
560
561 static void
562 5 mafp_load_enrolled_ids (FpiDeviceMafpmoc *self, mafp_cmd_response_t *resp)
563 {
564 5 uint16_t num = 0;
565 5 char msg[1024] = {0};
566 5 size_t used = 0;
567
568
2/2
✓ Branch 9 → 3 taken 1280 times.
✓ Branch 9 → 10 taken 5 times.
1285 for (uint16_t i = 0; i < sizeof (resp->tpl_table.list); i++)
569 {
570
2/2
✓ Branch 3 → 4 taken 4 times.
✓ Branch 3 → 8 taken 1276 times.
1280 if (resp->tpl_table.list[i])
571 {
572 4 self->templates->total_list[num++].id = i;
573
1/2
✓ Branch 4 → 5 taken 4 times.
✗ Branch 4 → 8 not taken.
4 if (used < sizeof (msg))
574 {
575 4 int written = g_snprintf (msg + used, sizeof (msg) - used, "%u ", i);
576
1/2
✓ Branch 6 → 7 taken 4 times.
✗ Branch 6 → 8 not taken.
4 if (written > 0)
577 4 used += MIN ((size_t) written, sizeof (msg) - used);
578 }
579 }
580 }
581 5 self->templates->index = 0;
582 5 self->templates->total_num = num;
583 5 fp_dbg ("enrolled ids: %s", msg);
584 5 fp_dbg ("enrolled num: %d", self->templates->total_num);
585 5 }
586
587 static void
588 1 fp_init_handeshake_cb (FpiDeviceMafpmoc *self,
589 mafp_cmd_response_t *resp,
590 GError *error)
591 {
592 1 FpDevice *dev = FP_DEVICE (self);
593
594
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 6 taken 1 time.
1 if (error)
595 {
596 fp_dbg ("handshake fail");
597 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
598 return;
599 }
600
601 1 fp_dbg ("result: %d, handshake code 0x%02x 0x%02x",
602 resp->result, resp->handshake.code[0], resp->handshake.code[1]);
603
604
1/2
✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 12 not taken.
1 if (resp->result == MAFP_SUCCESS &&
605
1/2
✓ Branch 8 → 9 taken 1 time.
✗ Branch 8 → 12 not taken.
1 resp->handshake.code[0] == MAFP_HANDSHAKE_CODE1 &&
606
1/2
✓ Branch 9 → 10 taken 1 time.
✗ Branch 9 → 12 not taken.
1 resp->handshake.code[1] == MAFP_HANDSHAKE_CODE2)
607 {
608 1 fpi_ssm_next_state (self->task_ssm);
609 1 return;
610 }
611
612 mafp_mark_failed (dev, self->task_ssm, FP_DEVICE_ERROR_GENERAL,
613 "Failed to handshake, result: 0x%x", resp->result);
614 }
615
616 static void
617 1 fp_init_module_status_cb (FpiDeviceMafpmoc *self,
618 mafp_cmd_response_t *resp,
619 GError *error)
620 {
621
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
1 if (error)
622 {
623 resp->result = 0xff;
624 g_clear_error (&error);
625 }
626
627 1 fp_dbg ("result: %d", resp->result);
628
629
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 1 time.
1 if ((resp->result & MAFP_RE_CALIBRATE_ERROR) == MAFP_RE_CALIBRATE_ERROR)
630 fp_dbg ("no calibrate data");
631
632 1 fpi_ssm_next_state (self->task_ssm);
633 1 }
634
635 static void
636 2 fp_init_clean_epin_cb (FpiUsbTransfer *transfer,
637 FpDevice *device,
638 gpointer user_data,
639 GError *error)
640 {
641 2 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
642
643 2 fpi_ssm_next_state (self->task_ssm);
644 2 }
645
646 static void
647 1 fp_init_clean_epout_cb (FpiUsbTransfer *transfer,
648 FpDevice *device,
649 gpointer user_data,
650 GError *error)
651 {
652 1 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
653
654 1 fpi_ssm_next_state (self->task_ssm);
655 1 }
656
657 static void
658 5 fp_init_run_state (FpiSsm *ssm, FpDevice *device)
659 {
660 5 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
661 5 FpiUsbTransfer *transfer;
662
663
5/6
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 8 taken 1 time.
✓ Branch 3 → 12 taken 1 time.
✓ Branch 3 → 16 taken 1 time.
✓ Branch 3 → 18 taken 1 time.
✗ Branch 3 → 20 not taken.
5 switch (fpi_ssm_get_cur_state (ssm))
664 {
665 1 case MAPF_INIT_CLEAN_EPIN:
666 1 transfer = fpi_usb_transfer_new (device);
667 1 fpi_usb_transfer_fill_bulk (transfer, MAFP_EP_BULK_IN, MAFP_USB_BUFFER_SIZE);
668 1 fpi_usb_transfer_submit (transfer, 100, NULL, fp_init_clean_epin_cb, NULL);
669 1 break;
670
671 1 case MAPF_INIT_CLEAN_EPOUT:
672 1 transfer = fpi_usb_transfer_new (device);
673 1 fpi_usb_transfer_fill_bulk (transfer, MAFP_EP_BULK_OUT, MAFP_USB_BUFFER_SIZE);
674 1 fpi_usb_transfer_submit (transfer, 100, NULL, fp_init_clean_epout_cb, NULL);
675 1 break;
676
677 1 case MAPF_INIT_CLEAN_EPIN2:
678 1 transfer = fpi_usb_transfer_new (device);
679 1 fpi_usb_transfer_fill_bulk (transfer, MAFP_EP_BULK_IN, MAFP_USB_BUFFER_SIZE);
680 1 fpi_usb_transfer_submit (transfer, 100, NULL, fp_init_clean_epin_cb, NULL);
681 1 break;
682
683 1 case MAPF_INIT_HANDSHAKE:
684 1 mafp_sensor_cmd (self, MOC_CMD_HANDSHAKE, NULL, 0, fp_init_handeshake_cb);
685 1 break;
686
687 1 case MAPF_INIT_MODULE_STATUS:
688 1 self->cmd_force_pass = TRUE;
689 1 mafp_sensor_cmd (self, MOC_CMD_GET_INIT_STATUS, NULL, 0, fp_init_module_status_cb);
690 1 break;
691 }
692 5 }
693
694 static void
695 1 fp_init_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
696 {
697 1 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (dev);
698
699 1 self->task_ssm = NULL;
700
701
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 6 taken 1 time.
1 if (error)
702 {
703 fp_dbg ("%d %s", error->code, error->message);
704 fpi_device_open_complete (dev, g_steal_pointer (&error));
705 return;
706 }
707
708 1 fpi_device_open_complete (dev, NULL);
709 }
710
711 static void
712 1 fp_enroll_tpl_table_cb (FpiDeviceMafpmoc *self,
713 mafp_cmd_response_t *resp,
714 GError *error)
715 {
716 1 FpDevice *dev = FP_DEVICE (self);
717
718
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 1 time.
1 if (error)
719 {
720 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
721 return;
722 }
723
724 1 fp_dbg ("result: %d", resp->result);
725
726
1/2
✓ Branch 6 → 7 taken 1 time.
✗ Branch 6 → 17 not taken.
1 if (resp->result == MAFP_SUCCESS)
727 {
728 1 mafp_load_enrolled_ids (self, resp);
729 1 self->enroll_id = G_MAXUINT16;
730
1/2
✓ Branch 12 → 9 taken 1 time.
✗ Branch 12 → 13 not taken.
1 for (uint16_t i = 0; i < sizeof (resp->tpl_table.list); i++)
731 {
732
1/2
✓ Branch 9 → 10 taken 1 time.
✗ Branch 9 → 11 not taken.
1 if (!resp->tpl_table.list[i])
733 {
734 1 self->enroll_id = i;
735 1 break;
736 }
737 }
738
1/2
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 16 taken 1 time.
1 if (self->enroll_id == G_MAXUINT16)
739 {
740 mafp_mark_failed (dev, self->task_ssm, FP_DEVICE_ERROR_DATA_FULL,
741 "fingerprints total num reached max");
742 return;
743 }
744 1 fpi_ssm_next_state (self->task_ssm);
745 }
746 else
747 {
748 mafp_mark_failed (dev, self->task_ssm, FP_DEVICE_ERROR_GENERAL,
749 "Failed to get fingerprints index, result: 0x%x", resp->result);
750 }
751 }
752
753 static void
754 1 fp_enroll_read_tpl_cb (FpiDeviceMafpmoc *self,
755 mafp_cmd_response_t *resp,
756 GError *error)
757 {
758 1 FpDevice *dev = FP_DEVICE (self);
759
760
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 1 time.
1 if (error)
761 {
762 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
763 return;
764 }
765
766 1 fp_dbg ("result: %d", resp->result);
767
768 1 uint8_t *resp_buff = (uint8_t *) resp;
769 1 uint16_t max_id = 0;
770
771
1/2
✓ Branch 6 → 7 taken 1 time.
✗ Branch 6 → 11 not taken.
1 if (resp->result == MAFP_SUCCESS)
772 {
773 1 max_id = resp_buff[1] * 256 + resp_buff[2];
774 1 fp_dbg ("max_id: %d, %x %x %x %x", max_id, resp_buff[0], resp_buff[1], resp_buff[2], resp_buff[3]);
775
1/2
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 13 taken 1 time.
1 if (self->enroll_id >= max_id)
776 {
777 mafp_mark_failed (dev, self->task_ssm, FP_DEVICE_ERROR_DATA_FULL,
778 "fingerprints total num reached max");
779 return;
780 }
781 }
782 else
783 {
784 mafp_mark_failed (dev, self->task_ssm, FP_DEVICE_ERROR_DATA_FULL,
785 "fingerprints query total num fail");
786 return;
787 }
788 1 fpi_device_report_finger_status (dev, FP_FINGER_STATUS_NONE | FP_FINGER_STATUS_NEEDED);
789 1 fpi_ssm_next_state (self->task_ssm);
790 }
791
792 static void
793 38 fp_enroll_get_image_cb (FpiDeviceMafpmoc *self,
794 mafp_cmd_response_t *resp,
795 GError *error)
796 {
797 38 g_autoptr(GError) local_error = NULL;
798 38 FpDevice *dev = FP_DEVICE (self);
799 38 MapfEnrollState nextState = MAFP_ENROLL_VERIFY_GET_IMAGE;
800
801
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 38 times.
38 if (error)
802 {
803 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
804 return;
805 }
806
807
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 9 taken 38 times.
38 if (g_cancellable_set_error_if_cancelled (fpi_device_get_cancellable (dev),
808 &local_error))
809 {
810 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&local_error));
811 return;
812 }
813
814
2/2
✓ Branch 9 → 10 taken 12 times.
✓ Branch 9 → 16 taken 26 times.
38 if (self->press_state == MAFP_PRESS_WAIT_DOWN)
815 {
816 12 fp_dbg ("wait finger down state %d", resp->result);
817
1/2
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 21 taken 12 times.
12 if (resp->result == MAFP_RE_GET_IMAGE_SUCCESS)
818 {
819 nextState = MAFP_ENROLL_VERIFY_GENERATE_FEATURE;
820 }
821 else if (resp->result == MAFP_RE_GET_IMAGE_NONE)
822 {
823 self->capture_cnt++;
824 fp_dbg ("capture_cnt %d", self->capture_cnt);
825 if (self->capture_cnt > MAFP_IMAGE_ERR_TRRIGER)
826 nextState = MAFP_ENROLL_REFRESH_INT_PARA;
827 else
828 nextState = MAFP_ENROLL_DETECT_MODE;
829 }
830 }
831
1/2
✓ Branch 16 → 17 taken 26 times.
✗ Branch 16 → 21 not taken.
26 else if (self->press_state == MAFP_PRESS_WAIT_UP)
832 {
833 26 fp_dbg ("wait finger up state %d", resp->result);
834
2/2
✓ Branch 18 → 19 taken 12 times.
✓ Branch 18 → 21 taken 14 times.
26 if (resp->result == MAFP_RE_GET_IMAGE_SUCCESS)
835 {
836 nextState = MAFP_ENROLL_VERIFY_GET_IMAGE;
837 }
838
1/2
✓ Branch 19 → 20 taken 12 times.
✗ Branch 19 → 21 not taken.
12 else if (resp->result == MAFP_RE_GET_IMAGE_NONE)
839 {
840 12 self->press_state = MAFP_PRESS_WAIT_DOWN;
841 12 fpi_device_report_finger_status (dev, FP_FINGER_STATUS_NONE | FP_FINGER_STATUS_NEEDED);
842 12 nextState = MAFP_ENROLL_CHECK_INT_PARA;
843 }
844 }
845
1/2
✗ Branch 22 → 23 not taken.
✓ Branch 22 → 24 taken 38 times.
38 fpi_ssm_jump_to_state (self->task_ssm, nextState);
846 }
847
848 static void
849 12 fp_enroll_verify_search_cb (FpiDeviceMafpmoc *self,
850 mafp_cmd_response_t *resp,
851 GError *error)
852 {
853
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 12 times.
12 if (error)
854 {
855 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
856 return;
857 }
858
859 12 fp_dbg ("result: %d", resp->result);
860
861
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 9 taken 12 times.
12 if (resp->result == MAFP_SUCCESS)
862 {
863 self->search_id = ((resp->search.id[0] & 0xff) << 8) | (resp->search.id[1] & 0xff);
864 fp_dbg ("search_id: %d", self->search_id);
865 fpi_ssm_jump_to_state (self->task_ssm, MAFP_ENROLL_GET_TEMPLATE_INFO);
866 }
867 else
868 {
869 12 self->search_id = G_MAXUINT16;
870
2/2
✓ Branch 10 → 11 taken 1 time.
✓ Branch 10 → 12 taken 11 times.
12 if (self->enroll_stage >= fp_device_get_nr_enroll_stages (FP_DEVICE (self)))
871 1 fpi_ssm_jump_to_state (self->task_ssm, MAFP_ENROLL_SAVE_TEMPLATE_INFO);
872 else
873 11 fpi_ssm_jump_to_state (self->task_ssm, MAFP_ENROLL_VERIFY_GET_IMAGE);
874 }
875 }
876
877 static void
878 fp_enroll_get_tpl_info_cb (FpiDeviceMafpmoc *self,
879 mafp_cmd_response_t *resp,
880 GError *error)
881 {
882 FpDevice *dev = FP_DEVICE (self);
883 g_autofree char *uid = NULL;
884
885 if (error)
886 {
887 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
888 return;
889 }
890
891 uid = g_strndup (resp->tpl_info.uid, TEMPLATE_UID_SIZE);
892 fp_dbg ("result: %d, %s", resp->result, uid);
893
894 if (resp->result == MAFP_SUCCESS)
895 {
896 if (resp->tpl_info.uid[0] == 'F' && resp->tpl_info.uid[1] == 'P')
897 {
898 g_autoptr(FpPrint) print = NULL;
899 mafp_template_t tpl;
900
901 tpl.id = self->search_id;
902 memcpy (tpl.uid, resp->tpl_info.uid, sizeof (resp->tpl_info.uid));
903 print = mafp_print_from_template (self, &tpl);
904
905 mafp_mark_failed (dev, self->task_ssm, FP_DEVICE_ERROR_DATA_DUPLICATE,
906 "Finger was already enrolled as '%s'",
907 fp_print_get_description (print));
908 return;
909 }
910 }
911 if (self->enroll_stage >= fp_device_get_nr_enroll_stages (FP_DEVICE (self)))
912 fpi_ssm_jump_to_state (self->task_ssm, MAFP_ENROLL_SAVE_TEMPLATE_INFO);
913 else
914 fpi_ssm_jump_to_state (self->task_ssm, MAFP_ENROLL_VERIFY_GET_IMAGE);
915 }
916
917 static void
918 12 fp_enroll_once_complete_cb (FpiDeviceMafpmoc *self,
919 mafp_cmd_response_t *resp)
920 {
921 12 FpDevice *dev = FP_DEVICE (self);
922
923
1/2
✓ Branch 2 → 3 taken 12 times.
✗ Branch 2 → 12 not taken.
12 if (resp->result == MAFP_SUCCESS)
924 {
925 12 self->enroll_stage++;
926 12 self->press_state = MAFP_PRESS_WAIT_UP;
927 12 fpi_device_enroll_progress (dev, self->enroll_stage, NULL, NULL);
928
929
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 9 taken 12 times.
12 if (self->enroll_identify_state == MAFP_ENROLL_IDENTIFY_DISABLED)
930 {
931 if (self->enroll_stage >= fp_device_get_nr_enroll_stages (FP_DEVICE (self)))
932 fpi_ssm_jump_to_state (self->task_ssm, MAFP_ENROLL_SAVE_TEMPLATE_INFO);
933 else
934 fpi_ssm_jump_to_state (self->task_ssm, MAFP_ENROLL_VERIFY_GET_IMAGE);
935 return;
936 }
937
1/2
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 12 times.
12 if (self->enroll_identify_state == MAFP_ENROLL_IDENTIFY_ONCE)
938 self->enroll_identify_state = MAFP_ENROLL_IDENTIFY_DISABLED;
939 12 fpi_ssm_jump_to_state (self->task_ssm, MAFP_ENROLL_VERIFY_SEARCH);
940 }
941 else
942 {
943 self->press_state = MAFP_PRESS_WAIT_UP;
944 fpi_device_enroll_progress (dev, self->enroll_stage, NULL,
945 fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL));
946 fpi_ssm_jump_to_state (self->task_ssm, MAFP_ENROLL_VERIFY_GET_IMAGE);
947 }
948 }
949
950 static void
951 12 fp_enroll_gen_feature_cb (FpiDeviceMafpmoc *self,
952 mafp_cmd_response_t *resp,
953 GError *error)
954 {
955
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 12 times.
12 if (error)
956 {
957 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
958 return;
959 }
960
961 12 fp_dbg ("result: %d", resp->result);
962
963
1/2
✓ Branch 6 → 7 taken 12 times.
✗ Branch 6 → 11 not taken.
12 if (self->enroll_dupl_area_state == MAFP_ENROLL_DUPLICATE_AREA_DENY)
964 {
965 12 int device_stages = fp_device_get_nr_enroll_stages (FP_DEVICE (self));
966 12 int remain_stage = device_stages - self->enroll_stage;
967
968 /* check duplicate area in last 3 times */
969
2/2
✓ Branch 8 → 9 taken 3 times.
✓ Branch 8 → 11 taken 9 times.
12 if (remain_stage > 0 && remain_stage <= 3)
970 {
971 3 fpi_ssm_next_state (self->task_ssm);
972 3 return;
973 }
974 }
975 9 fp_enroll_once_complete_cb (self, resp);
976 }
977
978 static void
979 3 fp_enroll_verify_duparea_cb (FpiDeviceMafpmoc *self,
980 mafp_cmd_response_t *resp,
981 GError *error)
982 {
983
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 3 times.
3 if (error)
984 {
985 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
986 return;
987 }
988
989 3 fp_dbg ("result: %d", resp->result);
990
991
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 3 times.
3 if (resp->result != MAFP_SUCCESS)
992 resp->result = 1;
993 3 fp_enroll_once_complete_cb (self, resp);
994 }
995
996 static void
997 1 fp_enroll_save_tpl_info_cb (FpiDeviceMafpmoc *self,
998 mafp_cmd_response_t *resp,
999 GError *error)
1000 {
1001 1 FpDevice *dev = FP_DEVICE (self);
1002
1003
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 1 time.
1 if (error)
1004 {
1005 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
1006 return;
1007 }
1008
1009 1 fp_dbg ("result: %d", resp->result);
1010
1011
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 9 taken 1 time.
1 if (resp->result == MAFP_RE_TPL_NUM_OVERSIZE)
1012 {
1013 mafp_mark_failed (dev, self->task_ssm, FP_DEVICE_ERROR_DATA_FULL,
1014 "fingerprints total num reached max");
1015 return;
1016 }
1017
1/2
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 12 taken 1 time.
1 if (resp->result != MAFP_SUCCESS)
1018 {
1019 mafp_mark_failed (dev, self->task_ssm, FP_DEVICE_ERROR_GENERAL,
1020 "Failed to save template info, result: 0x%x", resp->result);
1021 return;
1022 }
1023 1 fpi_ssm_next_state (self->task_ssm);
1024 }
1025
1026 static void
1027 1 fp_enroll_save_tpl_cb (FpiDeviceMafpmoc *self,
1028 mafp_cmd_response_t *resp,
1029 GError *error)
1030 {
1031 1 FpDevice *dev = FP_DEVICE (self);
1032 1 FpPrint *print = NULL;
1033 1 GVariant *uid = NULL;
1034 1 GVariant *data = NULL;
1035 1 GVariant *dev_sn;
1036 1 unsigned user_id_len;
1037 1 unsigned serial_num_len;
1038 1 const char *user_id = NULL;
1039 1 const char *serial_num = NULL;
1040
1041
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
1 if (error)
1042 {
1043 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
1044 1 return;
1045 }
1046
1047 1 fp_dbg ("result: %d", resp->result);
1048
1049
1/2
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 22 not taken.
1 if (resp->result == MAFP_SUCCESS)
1050 {
1051 1 fpi_device_get_enroll_data (dev, &print);
1052
1053
1/2
✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 9 not taken.
1 user_id = self->enroll_user_id ? self->enroll_user_id : "";
1054 1 user_id_len = strnlen (user_id, TEMPLATE_UID_SIZE);
1055 1 fp_dbg ("user_id(%d): %s", user_id_len, user_id);
1056 1 uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, user_id, user_id_len, 1);
1057
1058
1/2
✓ Branch 11 → 12 taken 1 time.
✗ Branch 11 → 13 not taken.
1 serial_num = self->serial_number ? self->serial_number : "";
1059 1 serial_num_len = strnlen (serial_num, DEVICE_SN_SIZE);
1060 1 fp_dbg ("dev_sn(%d): %s", serial_num_len, serial_num);
1061 1 dev_sn = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, serial_num, serial_num_len, 1);
1062
1063 1 data = g_variant_new ("(q@ay@ay)", self->enroll_id, uid, dev_sn);
1064
1065 1 fpi_print_set_type (print, FPI_PRINT_RAW);
1066 1 fpi_print_set_device_stored (print, TRUE);
1067 1 g_object_set (print, "description", user_id, NULL);
1068 1 g_object_set (print, "fpi-data", data, NULL);
1069
1070 1 fpi_ssm_jump_to_state (self->task_ssm, MAFP_ENROLL_EXIT);
1071 1 return;
1072 }
1073 fpi_ssm_next_state (self->task_ssm);
1074 }
1075
1076 static void
1077 fp_enroll_del_tpl_info_cb (FpiDeviceMafpmoc *self,
1078 mafp_cmd_response_t *resp,
1079 GError *error)
1080 {
1081 FpDevice *dev = FP_DEVICE (self);
1082
1083 if (error)
1084 {
1085 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
1086 return;
1087 }
1088
1089 fp_dbg ("result: %d", resp->result);
1090 mafp_mark_failed (dev, self->task_ssm, FP_DEVICE_ERROR_GENERAL,
1091 "Failed to save template, result: 0x%x", resp->result);
1092 }
1093
1094 static void
1095 3 mafp_sleep_cb (FpiDeviceMafpmoc *self,
1096 mafp_cmd_response_t *resp,
1097 GError *error)
1098 {
1099
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 3 times.
3 if (error)
1100 {
1101 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
1102 return;
1103 }
1104 3 fpi_ssm_next_state (self->task_ssm);
1105 }
1106
1107 static void
1108 3 mafp_pwr_btn_shield_off_cb (FpiUsbTransfer *transfer,
1109 FpDevice *device,
1110 gpointer user_data,
1111 GError *error)
1112 {
1113 3 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
1114
1115
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 3 times.
3 if (error)
1116 {
1117 fpi_ssm_mark_failed (transfer->ssm, g_steal_pointer (&error));
1118 return;
1119 }
1120 3 uint8_t para = 0;
1121
1122 3 mafp_sensor_cmd (self, MOC_CMD_SLEEP, &para, 1, mafp_sleep_cb);
1123 }
1124
1125 static void
1126 3 mafp_pwr_btn_shield_on_cb (FpiUsbTransfer *transfer,
1127 FpDevice *device,
1128 gpointer user_data,
1129 GError *error)
1130 {
1131
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 3 times.
3 if (error)
1132 {
1133 fpi_ssm_mark_failed (transfer->ssm, g_steal_pointer (&error));
1134 return;
1135 }
1136 3 fpi_ssm_next_state (transfer->ssm);
1137 }
1138
1139 static void
1140 6 mafp_pwr_btn_shield_on (FpiDeviceMafpmoc *self, int on)
1141 {
1142 6 GError *pre_error = fpi_ssm_get_error (self->task_ssm);
1143
1144
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 8 taken 6 times.
6 if (g_error_matches (pre_error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_FAILED))
1145 {
1146 fpi_ssm_next_state (self->task_ssm);
1147 return;
1148 }
1149
1150
2/2
✓ Branch 8 → 9 taken 3 times.
✓ Branch 8 → 10 taken 3 times.
6 if (on)
1151 3 mafp_sensor_control (self, 0x8B, 0x01, mafp_pwr_btn_shield_on_cb, NULL, 1000);
1152 else
1153 3 mafp_sensor_control (self, 0x8B, 0x00, mafp_pwr_btn_shield_off_cb, NULL, 0);
1154 }
1155
1156 static void
1157 12 fp_enroll_int_check_cb (FpiDeviceMafpmoc *self,
1158 mafp_cmd_response_t *resp,
1159 GError *error)
1160 {
1161
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 12 times.
12 if (error)
1162 {
1163 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
1164 return;
1165 }
1166 12 fpi_ssm_next_state (self->task_ssm);
1167 }
1168
1169 static void
1170 12 fp_enroll_int_detect_cb (FpiDeviceMafpmoc *self,
1171 mafp_cmd_response_t *resp,
1172 GError *error)
1173 {
1174
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 12 times.
12 if (error)
1175 {
1176 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
1177 return;
1178 }
1179 12 fpi_ssm_next_state (self->task_ssm);
1180 }
1181
1182 static void
1183 fp_enroll_int_refresh_cb (FpiDeviceMafpmoc *self,
1184 mafp_cmd_response_t *resp,
1185 GError *error)
1186 {
1187 if (error)
1188 {
1189 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
1190 return;
1191 }
1192 self->capture_cnt = 0;
1193 fpi_ssm_jump_to_state (self->task_ssm, MAFP_ENROLL_VERIFY_GET_IMAGE);
1194 }
1195
1196 static void
1197 12 fp_enroll_enable_int_cb (FpiUsbTransfer *transfer,
1198 FpDevice *device,
1199 gpointer user_data,
1200 GError *error)
1201 {
1202
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 12 times.
12 if (error)
1203 {
1204 fpi_ssm_mark_failed (transfer->ssm, g_steal_pointer (&error));
1205 return;
1206 }
1207 12 fpi_ssm_next_state (transfer->ssm);
1208 }
1209
1210 static void
1211 12 fp_enroll_disable_int_cb (FpiUsbTransfer *transfer,
1212 FpDevice *device,
1213 gpointer user_data,
1214 GError *error)
1215 {
1216
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 12 times.
12 if (error)
1217 {
1218 fpi_ssm_mark_failed (transfer->ssm, g_steal_pointer (&error));
1219 return;
1220 }
1221 12 fpi_ssm_jump_to_state (transfer->ssm, MAFP_ENROLL_VERIFY_GET_IMAGE);
1222 }
1223
1224 static void
1225 12 fp_enroll_wait_int_cb (FpiUsbTransfer *transfer,
1226 FpDevice *device,
1227 gpointer user_data,
1228 GError *error)
1229 {
1230 12 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
1231
1232
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 10 taken 12 times.
12 if (error)
1233 {
1234 fp_dbg ("code %d", error->code);
1235 if (error->code == G_USB_DEVICE_ERROR_TIMED_OUT)
1236 {
1237 fpi_ssm_jump_to_state (self->task_ssm, MAFP_ENROLL_VERIFY_GET_IMAGE);
1238 g_clear_error (&error);
1239 return;
1240 }
1241
1242 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
1243 return;
1244 }
1245 12 fp_dbg ("actual_length %zd", transfer->actual_length);
1246
1/2
✓ Branch 11 → 12 taken 12 times.
✗ Branch 11 → 17 not taken.
12 if (transfer->actual_length == 2)
1247 {
1248
2/4
✓ Branch 12 → 13 taken 12 times.
✗ Branch 12 → 17 not taken.
✓ Branch 13 → 14 taken 12 times.
✗ Branch 13 → 17 not taken.
12 if (transfer->buffer[0] == 0x04 && transfer->buffer[1] == 0xe5)
1249 {
1250 12 fp_dbg ("int trigger");
1251 12 fpi_ssm_next_state (self->task_ssm);
1252 12 return;
1253 }
1254 }
1255 fpi_ssm_mark_failed (self->task_ssm, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
1256 }
1257
1258 static void
1259 12 fp_enroll_wait_int (FpiDeviceMafpmoc *self)
1260 {
1261 12 fp_dbg ("wait interrupt");
1262 12 FpiUsbTransfer *transfer = fpi_usb_transfer_new (FP_DEVICE (self));
1263
1264 12 fpi_usb_transfer_fill_interrupt (transfer, MAFP_EP_INT_IN, 2);
1265 12 fpi_usb_transfer_submit (transfer,
1266 30 * 1000,
1267 fpi_device_get_cancellable (FP_DEVICE (self)),
1268 fp_enroll_wait_int_cb,
1269 NULL);
1270 12 }
1271
1272 static void
1273 1 fp_empty_cb (FpiDeviceMafpmoc *self,
1274 mafp_cmd_response_t *resp,
1275 GError *error)
1276 {
1277
1/2
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 5 not taken.
1 if (error)
1278 {
1279 1 fp_dbg ("error: %s", error->message);
1280 1 g_clear_error (&error);
1281 }
1282 else
1283 {
1284 fp_dbg ("result: %d", resp ? resp->result : -1);
1285 }
1286
1287 1 fpi_ssm_next_state (self->task_ssm);
1288 1 }
1289
1290 static void
1291 1 mafp_check_empty (FpiDeviceMafpmoc *self)
1292 {
1293 1 mafp_sensor_cmd (self, MOC_CMD_EMPTY, NULL, 0, fp_empty_cb);
1294 1 }
1295
1296 static void
1297 132 fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
1298 {
1299 132 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
1300 132 uint8_t para[PACKAGE_DATA_SIZE_MAX] = { 0 };
1301 132 FpPrint *print = NULL;
1302 132 uint16_t range = 1000;
1303
1304
16/20
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 6 taken 1 time.
✓ Branch 3 → 8 taken 1 time.
✓ Branch 3 → 10 taken 1 time.
✓ Branch 3 → 12 taken 38 times.
✓ Branch 3 → 14 taken 12 times.
✓ Branch 3 → 16 taken 12 times.
✓ Branch 3 → 18 taken 12 times.
✓ Branch 3 → 20 taken 12 times.
✓ Branch 3 → 22 taken 12 times.
✗ Branch 3 → 24 not taken.
✓ Branch 3 → 27 taken 12 times.
✓ Branch 3 → 29 taken 3 times.
✓ Branch 3 → 31 taken 12 times.
✗ Branch 3 → 33 not taken.
✓ Branch 3 → 35 taken 1 time.
✓ Branch 3 → 40 taken 1 time.
✗ Branch 3 → 42 not taken.
✓ Branch 3 → 44 taken 1 time.
✗ Branch 3 → 46 not taken.
132 switch(fpi_ssm_get_cur_state (ssm))
1305 {
1306 1 case MAFP_ENROLL_PWR_BTN_SHIELD_ON:
1307 1 mafp_pwr_btn_shield_on (self, 1);
1308 1 break;
1309
1310 1 case MAFP_ENROLL_CHECK_EMPTY:
1311 1 mafp_check_empty (self);
1312 1 break;
1313
1314 1 case MAFP_ENROLL_TEMPLATE_TABLE:
1315 1 para[0] = 0; /* page no. */
1316 1 mafp_sensor_cmd (self, MOC_CMD_GET_TEMPLATE_TABLE, (const uint8_t *) &para, 1, fp_enroll_tpl_table_cb);
1317 1 break;
1318
1319 1 case MAFP_ENROLL_READ_TEMPLATE:
1320 1 mafp_sensor_cmd (self, MOC_CMD_GET_MAX_ID, NULL, 0, fp_enroll_read_tpl_cb);
1321 1 break;
1322
1323 38 case MAFP_ENROLL_VERIFY_GET_IMAGE:
1324 38 mafp_sensor_cmd (self, MOC_CMD_GET_IMAGE, NULL, 0, fp_enroll_get_image_cb);
1325 38 break;
1326
1327 12 case MAFP_ENROLL_CHECK_INT_PARA:
1328 12 para[0] = MAFP_SLEEP_INT_CHECK;
1329 12 mafp_sensor_cmd (self, MOC_CMD_SLEEP, para, 1, fp_enroll_int_check_cb);
1330 12 break;
1331
1332 12 case MAFP_ENROLL_DETECT_MODE:
1333 12 para[0] = MAFP_SLEEP_INT_WAIT;
1334 12 mafp_sensor_cmd (self, MOC_CMD_SLEEP, para, 1, fp_enroll_int_detect_cb);
1335 12 break;
1336
1337 12 case MAFP_ENROLL_ENABLE_INT:
1338 12 mafp_sensor_control (self, 0x89, 1, fp_enroll_enable_int_cb, NULL, 0);
1339 12 break;
1340
1341 12 case MAFP_ENROLL_WAIT_INT:
1342 12 fp_enroll_wait_int (self);
1343 12 break;
1344
1345 12 case MAFP_ENROLL_DISBALE_INT:
1346 12 mafp_sensor_control (self, 0x89, 0, fp_enroll_disable_int_cb, NULL, 0);
1347 12 break;
1348
1349 case MAFP_ENROLL_REFRESH_INT_PARA:
1350 fp_dbg ("refresh param");
1351 para[0] = MAFP_SLEEP_INT_REFRESH;
1352 mafp_sensor_cmd (self, MOC_CMD_SLEEP, para, 1, fp_enroll_int_refresh_cb);
1353 break;
1354
1355 12 case MAFP_ENROLL_VERIFY_GENERATE_FEATURE:
1356 12 para[0] = self->enroll_stage + 1; /* verify buffer id start from 1 */
1357 12 mafp_sensor_cmd (self, MOC_CMD_GEN_FEATURE, (const uint8_t *) &para, 1, fp_enroll_gen_feature_cb);
1358 12 break;
1359
1360 3 case MAFP_ENROLL_VERIFY_DUPLICATE_AREA:
1361 3 mafp_sensor_cmd (self, MOC_CMD_DUPAREA_TEST, NULL, 0, fp_enroll_verify_duparea_cb);
1362 3 break;
1363
1364 12 case MAFP_ENROLL_VERIFY_SEARCH:
1365 12 para[0] = 1; /* buffer id */
1366 12 para[1] = 0; /* start id high */
1367 12 para[2] = 0; /* start id low */
1368 12 para[3] = (range >> 8) & 0xff; /* range high */
1369 12 para[4] = range & 0xff; /* range low */
1370 12 mafp_sensor_cmd (self, MOC_CMD_SEARCH, (const uint8_t *) &para, 5, fp_enroll_verify_search_cb);
1371 12 break;
1372
1373 case MAFP_ENROLL_GET_TEMPLATE_INFO:
1374 para[0] = (self->search_id >> 8) & 0xff; /* fp id high */
1375 para[1] = self->search_id & 0xff; /* fp id low */
1376 mafp_sensor_cmd (self, MOC_CMD_GET_TEMPLATE_INFO, (const uint8_t *) &para, 2, fp_enroll_get_tpl_info_cb);
1377 break;
1378
1379 1 case MAFP_ENROLL_SAVE_TEMPLATE_INFO:
1380 1 fpi_device_get_enroll_data (device, &print);
1381 1 self->enroll_user_id = fpi_print_generate_user_id (print);
1382 1 para[0] = (self->enroll_id >> 8) & 0xff; /* fp id high */
1383 1 para[1] = self->enroll_id & 0xff; /* fp id low */
1384 1 memcpy (para + 2,
1385 self->enroll_user_id,
1386 1 MIN (strnlen (self->enroll_user_id, TEMPLATE_UID_SIZE), (gsize) TEMPLATE_UID_SIZE));
1387 1 fp_dbg ("user_id: %s", self->enroll_user_id);
1388 1 mafp_sensor_cmd (self, MOC_CMD_SAVE_TEMPLATE_INFO, (const uint8_t *) &para, 2 + TEMPLATE_UID_SIZE, fp_enroll_save_tpl_info_cb);
1389 1 break;
1390
1391 1 case MAFP_ENROLL_SAVE_TEMPLATE:
1392 1 para[0] = 1; /* buffer id */
1393 1 para[1] = (self->enroll_id >> 8) & 0xff; /* fp id high */
1394 1 para[2] = self->enroll_id & 0xff; /* fp id low */
1395 1 mafp_sensor_cmd (self, MOC_CMD_SAVE_TEMPLATE, (const uint8_t *) &para, 3, fp_enroll_save_tpl_cb);
1396 1 break;
1397
1398 case MAFP_ENROLL_DELETE_TEMPLATE_INFO_IF_FAILED:
1399 para[0] = (self->enroll_id >> 8) & 0xff; /* fp id high */
1400 para[1] = self->enroll_id & 0xff; /* fp id low */
1401 mafp_sensor_cmd (self, MOC_CMD_SAVE_TEMPLATE_INFO, (const uint8_t *) &para, 130, fp_enroll_del_tpl_info_cb);
1402 break;
1403
1404 1 case MAFP_ENROLL_EXIT:
1405 1 mafp_pwr_btn_shield_on (self, 0);
1406 1 break;
1407 }
1408 132 }
1409
1410 static void
1411 1 fp_enroll_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
1412 {
1413 1 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (dev);
1414 1 FpPrint *print = NULL;
1415
1416 1 self->task_ssm = NULL;
1417
1418
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 1 time.
1 if (error)
1419 {
1420 fp_dbg ("enroll done fail");
1421 fpi_device_enroll_complete (dev, NULL, g_steal_pointer (&error));
1422 return;
1423 }
1424
1425 1 fp_dbg ("enroll completed");
1426 1 fpi_device_get_enroll_data (dev, &print);
1427 1 fpi_device_enroll_complete (dev, g_object_ref (print), NULL);
1428 }
1429
1430
1431 static void
1432 2 fp_identify_tpl_table_cb (FpiDeviceMafpmoc *self,
1433 mafp_cmd_response_t *resp,
1434 GError *error)
1435 {
1436
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 2 times.
2 if (error)
1437 {
1438 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
1439 return;
1440 }
1441
1442 2 fp_dbg ("result: %d", resp->result);
1443
1444
1/2
✓ Branch 6 → 7 taken 2 times.
✗ Branch 6 → 8 not taken.
2 if (resp->result == MAFP_SUCCESS)
1445 2 mafp_load_enrolled_ids (self, resp);
1446 2 fpi_device_report_finger_status (FP_DEVICE (self), FP_FINGER_STATUS_NONE | FP_FINGER_STATUS_NEEDED);
1447 2 fpi_ssm_next_state (self->task_ssm);
1448 }
1449
1450 static void
1451 11 fp_identify_get_image_cb (FpiDeviceMafpmoc *self,
1452 mafp_cmd_response_t *resp,
1453 GError *error)
1454 {
1455 11 g_autoptr(GError) local_error = NULL;
1456 11 FpDevice *dev = FP_DEVICE (self);
1457 11 MapfIdentifyState nextState = MAPF_IDENTIFY_GET_IMAGE;
1458
1459
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 11 times.
11 if (error)
1460 {
1461 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
1462 return;
1463 }
1464
1465
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 9 taken 11 times.
11 if (g_cancellable_set_error_if_cancelled (fpi_device_get_cancellable (dev),
1466 &local_error))
1467 {
1468 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&local_error));
1469 return;
1470 }
1471
1472
2/2
✓ Branch 9 → 10 taken 2 times.
✓ Branch 9 → 16 taken 9 times.
11 if (self->press_state == MAFP_PRESS_WAIT_DOWN)
1473 {
1474 2 fp_dbg ("wait finger down state %d", resp->result);
1475
1/2
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 21 taken 2 times.
2 if (resp->result == MAFP_RE_GET_IMAGE_SUCCESS)
1476 {
1477 nextState = MAPF_IDENTIFY_GENERATE_FEATURE;
1478 }
1479 else if (resp->result == MAFP_RE_GET_IMAGE_NONE)
1480 {
1481 self->capture_cnt++;
1482 fp_dbg ("self->capture_cnt %d", self->capture_cnt);
1483 if (self->capture_cnt > MAFP_IMAGE_ERR_TRRIGER)
1484 nextState = MAPF_IDENTIFY_REFRESH_INT_PARA;
1485 else
1486 nextState = MAPF_IDENTIFY_DETECT_MODE;
1487 }
1488 }
1489
1/2
✓ Branch 16 → 17 taken 9 times.
✗ Branch 16 → 21 not taken.
9 else if (self->press_state == MAFP_PRESS_WAIT_UP)
1490 {
1491 9 fp_dbg ("wait finger up state %d", resp->result);
1492
2/2
✓ Branch 18 → 19 taken 2 times.
✓ Branch 18 → 21 taken 7 times.
9 if (resp->result == MAFP_RE_GET_IMAGE_SUCCESS)
1493 {
1494 nextState = MAPF_IDENTIFY_GET_IMAGE;
1495 }
1496
1/2
✓ Branch 19 → 20 taken 2 times.
✗ Branch 19 → 21 not taken.
2 else if (resp->result == MAFP_RE_GET_IMAGE_NONE)
1497 {
1498 2 self->press_state = MAFP_PRESS_WAIT_DOWN;
1499 2 fpi_device_report_finger_status (dev, FP_FINGER_STATUS_NONE | FP_FINGER_STATUS_NEEDED);
1500 2 nextState = MAPF_IDENTIFY_CHECK_INT_PARA;
1501 }
1502 }
1503
1504
1/2
✗ Branch 22 → 23 not taken.
✓ Branch 22 → 24 taken 11 times.
11 fpi_ssm_jump_to_state (self->task_ssm, nextState);
1505 }
1506
1507 static void
1508 2 fp_identify_gen_feature_cb (FpiDeviceMafpmoc *self,
1509 mafp_cmd_response_t *resp,
1510 GError *error)
1511 {
1512
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 2 times.
2 if (error)
1513 {
1514 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
1515 return;
1516 }
1517
1518 2 fp_dbg ("result: %d", resp->result);
1519
1520
1/2
✓ Branch 6 → 7 taken 2 times.
✗ Branch 6 → 8 not taken.
2 if (resp->result == MAFP_SUCCESS)
1521 {
1522 2 self->enroll_identify_index = 0;
1523 2 self->press_state = MAFP_PRESS_WAIT_UP;
1524 2 fpi_ssm_jump_to_state (self->task_ssm, MAPF_IDENTIFY_SEARCH_STEP);
1525 }
1526 else
1527 {
1528 self->press_state = MAFP_PRESS_WAIT_UP;
1529 fpi_ssm_jump_to_state (self->task_ssm, MAPF_IDENTIFY_GET_IMAGE);
1530 }
1531 }
1532
1533 static void
1534 mafp_scl_ctl_cb (FpiUsbTransfer *transfer,
1535 FpDevice *device,
1536 gpointer user_data,
1537 GError *error)
1538 {
1539 if (error)
1540 fp_dbg ("control transfer out fail, %s", error->message);
1541
1542 fpi_ssm_jump_to_state (transfer->ssm, MAPF_IDENTIFY_EXIT);
1543 }
1544
1545 static void
1546 2 fp_identify_get_tpl_info_cb (FpiDeviceMafpmoc *self,
1547 mafp_cmd_response_t *resp,
1548 GError *error)
1549 {
1550 2 g_autoptr(GError) local_error = NULL;
1551 2 FpDevice *dev = FP_DEVICE (self);
1552 2 FpPrint *new_scan = NULL;
1553 2 FpPrint *matching = NULL;
1554
1555
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 2 times.
2 if (error)
1556 {
1557 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
1558 return;
1559 }
1560
1561
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 9 taken 2 times.
2 if (g_cancellable_set_error_if_cancelled (fpi_device_get_cancellable (dev),
1562 &local_error))
1563 {
1564 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&local_error));
1565 return;
1566 }
1567
1568 2 fp_dbg ("result: %d", resp->result);
1569
1570
1/2
✓ Branch 10 → 11 taken 2 times.
✗ Branch 10 → 20 not taken.
2 if (resp->result == MAFP_SUCCESS)
1571 {
1572
2/4
✓ Branch 11 → 12 taken 2 times.
✗ Branch 11 → 20 not taken.
✓ Branch 12 → 13 taken 2 times.
✗ Branch 12 → 20 not taken.
2 if (resp->tpl_info.uid[0] == 'F' && resp->tpl_info.uid[1] == 'P')
1573 {
1574 2 mafp_template_t tpl;
1575
1576 2 tpl.id = self->search_id;
1577 2 memcpy (tpl.uid, resp->tpl_info.uid, sizeof (resp->tpl_info.uid));
1578 2 new_scan = mafp_print_from_template (self, &tpl);
1579 }
1580
1581
1/2
✓ Branch 14 → 15 taken 2 times.
✗ Branch 14 → 20 not taken.
2 if (new_scan != NULL)
1582 {
1583 2 GPtrArray *templates = NULL;
1584 2 guint matching_index;
1585
1586 2 fpi_device_get_identify_data (dev, &templates);
1587
1588
1/2
✓ Branch 17 → 18 taken 2 times.
✗ Branch 17 → 19 not taken.
2 if (g_ptr_array_find_with_equal_func (templates, new_scan,
1589 (GEqualFunc) fp_print_equal,
1590 &matching_index))
1591 2 matching = g_ptr_array_index (templates, matching_index);
1592 }
1593 }
1594
1595 2 self->identify_match_print = matching;
1596 2 self->identify_new_print = new_scan;
1597
1598
1/2
✗ Branch 20 → 21 not taken.
✓ Branch 20 → 23 taken 2 times.
2 if (!matching)
1599 {
1600 mafp_sensor_control (self, 0x8C, 0x00, mafp_scl_ctl_cb, NULL, 0);
1601 return;
1602 }
1603
1/2
✗ Branch 24 → 25 not taken.
✓ Branch 24 → 26 taken 2 times.
2 fpi_ssm_jump_to_state (self->task_ssm, MAPF_IDENTIFY_EXIT);
1604 }
1605
1606 static void
1607 2 fp_identify_search_step_cb (FpiDeviceMafpmoc *self,
1608 mafp_cmd_response_t *resp,
1609 GError *error)
1610 {
1611 2 GPtrArray *prints = NULL;
1612 2 FpDevice *dev = FP_DEVICE (self);
1613
1614
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 2 times.
2 if (error)
1615 {
1616 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
1617 return;
1618 }
1619
1620 2 fp_dbg ("result: %d", resp->result);
1621
1/2
✓ Branch 5 → 6 taken 2 times.
✗ Branch 5 → 8 not taken.
2 if (resp->result == MAFP_SUCCESS)
1622 {
1623 2 fp_dbg ("identify ok, search_id: %d", self->search_id);
1624 2 fpi_ssm_jump_to_state (self->task_ssm, MAPF_IDENTIFY_GET_TEMPLATE_INFO);
1625 }
1626 else
1627 {
1628 fp_dbg ("identify fail");
1629 fpi_device_get_identify_data (dev, &prints);
1630 self->enroll_identify_index++;
1631 if (self->enroll_identify_index < prints->len)
1632 {
1633 fpi_ssm_jump_to_state (self->task_ssm, MAPF_IDENTIFY_SEARCH_STEP);
1634 return;
1635 }
1636 self->search_id = G_MAXUINT16;
1637 fpi_ssm_jump_to_state (self->task_ssm, MAPF_IDENTIFY_GET_TEMPLATE_INFO);
1638 }
1639 }
1640
1641 static void
1642 2 mafp_get_startup_result_cb (FpiUsbTransfer *transfer,
1643 FpDevice *device,
1644 gpointer user_data,
1645 GError *error)
1646 {
1647 2 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
1648
1649
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 7 taken 2 times.
2 if (error)
1650 {
1651 fp_dbg ("error: %s", error->message);
1652 fpi_ssm_next_state (transfer->ssm);
1653 g_clear_error (&error);
1654 return;
1655 }
1656
1/2
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 13 taken 2 times.
2 if (transfer->actual_length >= 5)
1657 {
1658 fp_dbg ("0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x", transfer->buffer[0], transfer->buffer[1],
1659 transfer->buffer[2], transfer->buffer[3], transfer->buffer[4]);
1660 if (transfer->buffer[0])
1661 {
1662 self->search_id = transfer->buffer[2] * 256 + transfer->buffer[1];
1663 usleep (1000 * 1000);
1664 fpi_ssm_jump_to_state (transfer->ssm, MAPF_IDENTIFY_GET_TEMPLATE_INFO);
1665 return;
1666 }
1667 }
1668 2 fpi_ssm_next_state (transfer->ssm);
1669 }
1670
1671 static void
1672 2 fp_identify_int_check_cb (FpiDeviceMafpmoc *self,
1673 mafp_cmd_response_t *resp,
1674 GError *error)
1675 {
1676
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 2 times.
2 if (error)
1677 {
1678 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
1679 return;
1680 }
1681 2 fpi_ssm_next_state (self->task_ssm);
1682 }
1683
1684 static void
1685 2 fp_identify_int_detect_cb (FpiDeviceMafpmoc *self,
1686 mafp_cmd_response_t *resp,
1687 GError *error)
1688 {
1689
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 2 times.
2 if (error)
1690 {
1691 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
1692 return;
1693 }
1694 2 fpi_ssm_next_state (self->task_ssm);
1695 }
1696
1697 static void
1698 fp_identify_int_refresh_cb (FpiDeviceMafpmoc *self,
1699 mafp_cmd_response_t *resp,
1700 GError *error)
1701 {
1702 if (error)
1703 {
1704 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
1705 return;
1706 }
1707 self->capture_cnt = 0;
1708 fpi_ssm_jump_to_state (self->task_ssm, MAPF_IDENTIFY_GET_IMAGE);
1709 }
1710
1711 static void
1712 2 fp_identify_enable_int_cb (FpiUsbTransfer *transfer,
1713 FpDevice *device,
1714 gpointer user_data,
1715 GError *error)
1716 {
1717
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 2 times.
2 if (error)
1718 {
1719 fpi_ssm_mark_failed (transfer->ssm, g_steal_pointer (&error));
1720 return;
1721 }
1722 2 fpi_ssm_next_state (transfer->ssm);
1723 }
1724
1725 static void
1726 2 fp_identify_disable_int_cb (FpiUsbTransfer *transfer,
1727 FpDevice *device,
1728 gpointer user_data,
1729 GError *error)
1730 {
1731
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 2 times.
2 if (error)
1732 {
1733 fpi_ssm_mark_failed (transfer->ssm, g_steal_pointer (&error));
1734 return;
1735 }
1736 2 fpi_ssm_jump_to_state (transfer->ssm, MAPF_IDENTIFY_GET_IMAGE);
1737 }
1738
1739 static void
1740 2 fp_identify_wait_int_cb (FpiUsbTransfer *transfer,
1741 FpDevice *device,
1742 gpointer user_data,
1743 GError *error)
1744 {
1745 2 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
1746
1747
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 10 taken 2 times.
2 if (error)
1748 {
1749 fp_dbg ("code %d", error->code);
1750 if (error->code == G_USB_DEVICE_ERROR_TIMED_OUT)
1751 {
1752 fpi_ssm_jump_to_state (self->task_ssm, MAPF_IDENTIFY_GET_IMAGE);
1753 g_clear_error (&error);
1754 return;
1755 }
1756
1757 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
1758 return;
1759 }
1760 2 fp_dbg ("actual_length %zd", transfer->actual_length);
1761
1/2
✓ Branch 11 → 12 taken 2 times.
✗ Branch 11 → 17 not taken.
2 if (transfer->actual_length == 2)
1762 {
1763
2/4
✓ Branch 12 → 13 taken 2 times.
✗ Branch 12 → 17 not taken.
✓ Branch 13 → 14 taken 2 times.
✗ Branch 13 → 17 not taken.
2 if (transfer->buffer[0] == 0x04 && transfer->buffer[1] == 0xe5)
1764 {
1765 2 fp_dbg ("int trigger");
1766 2 fpi_ssm_next_state (self->task_ssm);
1767 2 return;
1768 }
1769 }
1770 fpi_ssm_mark_failed (self->task_ssm, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
1771 }
1772
1773 static void
1774 2 fp_identify_wait_int (FpiDeviceMafpmoc *self)
1775 {
1776 2 fp_dbg ("wait interrupt");
1777 2 FpiUsbTransfer *transfer = fpi_usb_transfer_new (FP_DEVICE (self));
1778
1779 2 fpi_usb_transfer_fill_interrupt (transfer, MAFP_EP_INT_IN, 2);
1780 2 fpi_usb_transfer_submit (transfer,
1781 30 * 60 * 1000,
1782 fpi_device_get_cancellable (FP_DEVICE (self)),
1783 fp_identify_wait_int_cb,
1784 NULL);
1785 2 }
1786
1787 static void
1788 35 fp_identify_sm_run_state (FpiSsm *ssm, FpDevice *device)
1789 {
1790 35 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
1791 35 uint8_t para[PACKAGE_DATA_SIZE_MAX] = { 0 };
1792 35 GPtrArray *prints = NULL;
1793 35 FpPrint *print = NULL;
1794
1795
13/15
✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 6 taken 2 times.
✓ Branch 3 → 8 taken 2 times.
✓ Branch 3 → 10 taken 11 times.
✓ Branch 3 → 12 taken 2 times.
✓ Branch 3 → 14 taken 2 times.
✓ Branch 3 → 16 taken 2 times.
✓ Branch 3 → 18 taken 2 times.
✓ Branch 3 → 20 taken 2 times.
✗ Branch 3 → 22 not taken.
✓ Branch 3 → 25 taken 2 times.
✓ Branch 3 → 27 taken 2 times.
✓ Branch 3 → 35 taken 2 times.
✓ Branch 3 → 39 taken 2 times.
✗ Branch 3 → 42 not taken.
35 switch(fpi_ssm_get_cur_state (ssm))
1796 {
1797 2 case MAPF_IDENTIFY_PWR_BTN_SHIELD_ON:
1798 2 mafp_pwr_btn_shield_on (self, 1);
1799 2 break;
1800
1801 2 case MAPF_IDENTIFY_TEMPLATE_TABLE:
1802 2 para[0] = 0; /* page no. */
1803 2 mafp_sensor_cmd (self, MOC_CMD_GET_TEMPLATE_TABLE, (const uint8_t *) &para, 1, fp_identify_tpl_table_cb);
1804 2 break;
1805
1806 2 case MAPF_IDENTIFY_GET_STARTUP_RESULT:
1807 2 mafp_sensor_control (self, 0x8D, 0x00, mafp_get_startup_result_cb, NULL, 0);
1808 2 break;
1809
1810 11 case MAPF_IDENTIFY_GET_IMAGE:
1811 11 mafp_sensor_cmd (self, MOC_CMD_GET_IMAGE, NULL, 0, fp_identify_get_image_cb);
1812 11 break;
1813
1814 2 case MAPF_IDENTIFY_CHECK_INT_PARA:
1815 2 para[0] = MAFP_SLEEP_INT_CHECK;
1816 2 mafp_sensor_cmd (self, MOC_CMD_SLEEP, para, 1, fp_identify_int_check_cb);
1817 2 break;
1818
1819 2 case MAPF_IDENTIFY_DETECT_MODE:
1820 2 para[0] = MAFP_SLEEP_INT_WAIT;
1821 2 mafp_sensor_cmd (self, MOC_CMD_SLEEP, para, 1, fp_identify_int_detect_cb);
1822 2 break;
1823
1824 2 case MAPF_IDENTIFY_ENABLE_INT:
1825 2 mafp_sensor_control (self, 0x89, 1, fp_identify_enable_int_cb, NULL, 0);
1826 2 break;
1827
1828 2 case MAPF_IDENTIFY_WAIT_INT:
1829 2 fp_identify_wait_int (self);
1830 2 break;
1831
1832 2 case MAPF_IDENTIFY_DISBALE_INT:
1833 2 mafp_sensor_control (self, 0x89, 0, fp_identify_disable_int_cb, NULL, 0);
1834 2 break;
1835
1836 case MAPF_IDENTIFY_REFRESH_INT_PARA:
1837 fp_dbg ("refresh param");
1838 para[0] = MAFP_SLEEP_INT_REFRESH;
1839 mafp_sensor_cmd (self, MOC_CMD_SLEEP, para, 1, fp_identify_int_refresh_cb);
1840 break;
1841
1842 2 case MAPF_IDENTIFY_GENERATE_FEATURE:
1843 2 para[0] = 1; /* buffer id */
1844 2 mafp_sensor_cmd (self, MOC_CMD_GEN_FEATURE, (const uint8_t *) &para, 1, fp_identify_gen_feature_cb);
1845 2 break;
1846
1847 2 case MAPF_IDENTIFY_SEARCH_STEP:
1848 2 fpi_device_get_identify_data (device, &prints);
1849
2/4
✓ Branch 28 → 29 taken 2 times.
✗ Branch 28 → 30 not taken.
✗ Branch 29 → 30 not taken.
✓ Branch 29 → 32 taken 2 times.
2 if (!prints || prints->len == 0)
1850 {
1851 self->search_id = G_MAXUINT16;
1852 fpi_ssm_jump_to_state (self->task_ssm, MAPF_IDENTIFY_GET_TEMPLATE_INFO);
1853 break;
1854 }
1855 2 print = g_ptr_array_index (prints, self->enroll_identify_index);
1856 2 mafp_template_t tpl = mafp_template_from_print (print);
1857 2 self->search_id = tpl.id;
1858 2 para[0] = (tpl.id >> 8) & 0xff;
1859 2 para[1] = tpl.id & 0xff;
1860 2 mafp_sensor_cmd (self, MOC_CMD_MATCH_WITHFID, (const uint8_t *) &para, 2, fp_identify_search_step_cb);
1861 2 break;
1862
1863 2 case MAPF_IDENTIFY_GET_TEMPLATE_INFO:
1864
1/2
✗ Branch 35 → 36 not taken.
✓ Branch 35 → 38 taken 2 times.
2 if (self->search_id == G_MAXUINT16)
1865 {
1866 mafp_cmd_response_t resp;
1867 resp.result = 1;
1868 fp_identify_get_tpl_info_cb (self, &resp, NULL);
1869 }
1870 else
1871 {
1872 2 para[0] = (self->search_id >> 8) & 0xff; /* fp id high */
1873 2 para[1] = self->search_id & 0xff; /* fp id low */
1874 2 mafp_sensor_cmd (self, MOC_CMD_GET_TEMPLATE_INFO, (const uint8_t *) &para, 2, fp_identify_get_tpl_info_cb);
1875 }
1876 break;
1877
1878 2 case MAPF_IDENTIFY_EXIT:
1879 2 mafp_pwr_btn_shield_on (self, 0);
1880 2 break;
1881 }
1882 35 }
1883
1884 static void
1885 2 fp_identify_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
1886 {
1887 2 fp_dbg ("identify completed");
1888 2 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (dev);
1889
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 7 taken 2 times.
2 g_autoptr(FpPrint) new_print = g_steal_pointer (&self->identify_new_print);
1890 2 FpPrint *match_print = g_steal_pointer (&self->identify_match_print);
1891
1892 2 self->task_ssm = NULL;
1893
1894
1/4
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 7 taken 2 times.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 8 not taken.
2 if (error && error->domain == FP_DEVICE_RETRY)
1895 {
1896 fpi_device_identify_report (dev, NULL, NULL, g_steal_pointer (&error));
1897
1898 return;
1899 }
1900
1901 2 if (error)
1902 {
1903 fpi_device_action_error (dev, g_steal_pointer (&error));
1904 return;
1905 }
1906
1907 2 fpi_device_identify_report (dev, match_print,
1908
1/2
✗ Branch 7 → 10 not taken.
✓ Branch 7 → 11 taken 2 times.
2 self->enroll_dupl_del_state ?
1909 g_steal_pointer (&new_print) : NULL,
1910 NULL);
1911
1/2
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 18 taken 2 times.
2 fpi_device_identify_complete (dev, NULL);
1912 }
1913
1914 static void
1915 1 fp_list_tpl_table_cb (FpiDeviceMafpmoc *self,
1916 mafp_cmd_response_t *resp,
1917 GError *error)
1918 {
1919 1 FpDevice *dev = FP_DEVICE (self);
1920
1921
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 1 time.
1 if (error)
1922 {
1923 fpi_device_list_complete (dev, NULL, g_steal_pointer (&error));
1924 return;
1925 }
1926
1927 1 fp_dbg ("result: %d", resp->result);
1928
1929
1/2
✓ Branch 6 → 7 taken 1 time.
✗ Branch 6 → 12 not taken.
1 if (resp->result == MAFP_SUCCESS)
1930 {
1931 1 mafp_load_enrolled_ids (self, resp);
1932
1933
1/2
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 11 taken 1 time.
1 if (self->templates->total_num == 0)
1934 {
1935 fpi_ssm_jump_to_state (self->task_ssm, MAPF_LIST_STATES);
1936 return;
1937 }
1938 1 fpi_ssm_next_state (self->task_ssm);
1939 }
1940 else
1941 {
1942 mafp_mark_failed (dev, self->task_ssm, FP_DEVICE_ERROR_GENERAL,
1943 "Failed to get fingerprints index, result: 0x%x", resp->result);
1944 }
1945 }
1946
1947 static void
1948 1 fp_list_get_tpl_info_cb (FpiDeviceMafpmoc *self,
1949 mafp_cmd_response_t *resp,
1950 GError *error)
1951 {
1952
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 1 time.
1 if (error)
1953 {
1954 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
1955 return;
1956 }
1957
1958 1 fp_dbg ("result: %d", resp->result);
1959
1960
1/2
✓ Branch 6 → 7 taken 1 time.
✗ Branch 6 → 17 not taken.
1 if (resp->result == MAFP_SUCCESS)
1961 {
1962 1 FpPrint *print;
1963 2 g_autofree char *uid = g_strndup (resp->tpl_info.uid, TEMPLATE_UID_SIZE);
1964 1 mafp_template_t *template = &self->templates->total_list[self->templates->index];
1965
1966 1 fp_dbg ("tpl_info: %s", uid);
1967
1968
2/4
✓ Branch 9 → 10 taken 1 time.
✗ Branch 9 → 12 not taken.
✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 12 not taken.
1 if (resp->tpl_info.uid[0] == 'F' && resp->tpl_info.uid[1] == 'P')
1969 1 memcpy (template->uid, resp->tpl_info.uid, sizeof (resp->tpl_info.uid));
1970 else
1971 strncpy (template->uid, "NOT-A-FPRINT-PRINT", sizeof (resp->tpl_info.uid));
1972
1973 1 print = mafp_print_from_template (self, template);
1974 1 g_ptr_array_add (self->templates->list, g_object_ref_sink (print));
1975 }
1976
1/2
✗ Branch 17 → 18 not taken.
✓ Branch 17 → 20 taken 1 time.
1 if (++self->templates->index < self->templates->total_num)
1977 {
1978 fpi_ssm_jump_to_state (self->task_ssm, MAPF_LIST_GET_TEMPLATE_INFO);
1979 return;
1980 }
1981 1 fpi_ssm_next_state (self->task_ssm);
1982 }
1983
1984 static void
1985 2 fp_list_run_state (FpiSsm *ssm, FpDevice *device)
1986 {
1987 2 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
1988 2 uint8_t para[PACKAGE_DATA_SIZE_MAX] = { 0 };
1989
1990
2/3
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 6 taken 1 time.
✗ Branch 3 → 8 not taken.
2 switch (fpi_ssm_get_cur_state (ssm))
1991 {
1992 1 case MAPF_LIST_TEMPLATE_TABLE:
1993 1 para[0] = 0; /* page no. */
1994 1 mafp_sensor_cmd (self, MOC_CMD_GET_TEMPLATE_TABLE, (const uint8_t *) &para, 1, fp_list_tpl_table_cb);
1995 1 break;
1996
1997 1 case MAPF_LIST_GET_TEMPLATE_INFO:
1998 1 para[0] = (self->templates->total_list[self->templates->index].id >> 8) & 0xff; /* fp id high */
1999 1 para[1] = self->templates->total_list[self->templates->index].id & 0xff; /* fp id low */
2000 1 mafp_sensor_cmd (self, MOC_CMD_GET_TEMPLATE_INFO, (const uint8_t *) &para, 2, fp_list_get_tpl_info_cb);
2001 1 break;
2002 }
2003 2 }
2004
2005 static void
2006 1 fp_list_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
2007 {
2008 1 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (dev);
2009
2010 1 self->task_ssm = NULL;
2011
2012
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 8 taken 1 time.
1 if (error)
2013 {
2014 fp_dbg ("list tpl fail");
2015 g_clear_pointer (&self->templates->list, g_ptr_array_unref);
2016 fpi_device_list_complete (dev, NULL, g_steal_pointer (&error));
2017 return;
2018 }
2019
2020 1 fpi_device_list_complete (FP_DEVICE (self), g_steal_pointer (&self->templates->list), NULL);
2021 }
2022
2023 static void
2024 1 fp_delete_tpl_table_cb (FpiDeviceMafpmoc *self,
2025 mafp_cmd_response_t *resp,
2026 GError *error)
2027 {
2028 1 FpDevice *dev = FP_DEVICE (self);
2029 1 FpPrint *print = NULL;
2030 1 gboolean id_exist = FALSE;
2031
2032
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
1 if (error)
2033 {
2034 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
2035 return;
2036 }
2037
2038 1 fp_dbg ("result: %d", resp->result);
2039
2040
1/2
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 14 not taken.
1 if (resp->result == MAFP_SUCCESS)
2041 {
2042 1 mafp_load_enrolled_ids (self, resp);
2043 1 fpi_device_get_delete_data (dev, &print);
2044 1 mafp_template_t tpl = mafp_template_from_print (print);
2045
2046
1/2
✓ Branch 12 → 10 taken 1 time.
✗ Branch 12 → 13 not taken.
2 for (int i = 0; i < self->templates->total_num; i++)
2047 {
2048
1/2
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 13 taken 1 time.
1 if (self->templates->total_list[i].id == tpl.id)
2049 {
2050 id_exist = true;
2051 break;
2052 }
2053 }
2054 }
2055
1/2
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 16 taken 1 time.
1 if (!id_exist)
2056 {
2057 fpi_ssm_jump_to_state (self->task_ssm, MAPF_DELETE_CLEAR_TEMPLATE_INFO);
2058 return;
2059 }
2060 1 fpi_ssm_next_state (self->task_ssm);
2061 }
2062
2063 static void
2064 1 fp_delete_get_tpl_info_cb (FpiDeviceMafpmoc *self,
2065 mafp_cmd_response_t *resp,
2066 GError *error)
2067 {
2068 1 FpDevice *dev = FP_DEVICE (self);
2069 1 FpPrint *print = NULL;
2070
2071
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
1 if (error)
2072 {
2073 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
2074 return;
2075 }
2076
2077 1 fp_dbg ("result: %d", resp->result);
2078
2079
1/2
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 23 not taken.
1 if (resp->result == MAFP_SUCCESS)
2080 {
2081 2 g_autofree char *uid = g_strndup (resp->tpl_info.uid, TEMPLATE_UID_SIZE);
2082
2083 1 fpi_device_get_delete_data (dev, &print);
2084 1 mafp_template_t tpl = mafp_template_from_print (print);
2085 1 fp_dbg ("target: %s/%s", tpl.uid, tpl.sn);
2086 1 fp_dbg ("find: %s/%s", uid, self->serial_number);
2087
1/2
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 1 time.
1 if (g_strcmp0 (self->serial_number, tpl.sn) != 0)
2088 {
2089 mafp_mark_failed (dev, self->task_ssm, FP_DEVICE_ERROR_GENERAL,
2090 "Failed to match device serial number");
2091 return;
2092 }
2093
1/2
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 17 taken 1 time.
1 if (!g_str_equal (uid, tpl.uid))
2094 {
2095 mafp_mark_failed (dev, self->task_ssm, FP_DEVICE_ERROR_GENERAL,
2096 "Failed to match template uid");
2097 return;
2098 }
2099 1 fpi_ssm_next_state (self->task_ssm);
2100 }
2101 else
2102 {
2103 mafp_mark_failed (dev, self->task_ssm, FP_DEVICE_ERROR_GENERAL,
2104 "Failed to get template info, result: 0x%x", resp->result);
2105 }
2106 }
2107
2108 static void
2109 1 fp_delete_clear_tpl_info_cb (FpiDeviceMafpmoc *self,
2110 mafp_cmd_response_t *resp,
2111 GError *error)
2112 {
2113 1 FpDevice *dev = FP_DEVICE (self);
2114
2115
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 1 time.
1 if (error)
2116 {
2117 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
2118 return;
2119 }
2120
2121 1 fp_dbg ("result: %d", resp->result);
2122
2123
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 9 taken 1 time.
1 if (resp->result != MAFP_SUCCESS)
2124 {
2125 mafp_mark_failed (dev, self->task_ssm, FP_DEVICE_ERROR_GENERAL,
2126 "Failed to delete template info, result: 0x%x", resp->result);
2127 return;
2128 }
2129 1 fpi_ssm_next_state (self->task_ssm);
2130 }
2131
2132 static void
2133 1 fp_delete_tpl_cb (FpiDeviceMafpmoc *self,
2134 mafp_cmd_response_t *resp,
2135 GError *error)
2136 {
2137 1 FpDevice *dev = FP_DEVICE (self);
2138
2139
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 1 time.
1 if (error)
2140 {
2141 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
2142 return;
2143 }
2144
2145 1 fp_dbg ("result: %d", resp->result);
2146
2147
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 9 taken 1 time.
1 if (resp->result != MAFP_SUCCESS)
2148 {
2149 mafp_mark_failed (dev, self->task_ssm, FP_DEVICE_ERROR_GENERAL,
2150 "Failed to delete template, result: 0x%x", resp->result);
2151 return;
2152 }
2153 1 fpi_ssm_next_state (self->task_ssm);
2154 }
2155
2156 static void
2157 4 fp_delete_run_state (FpiSsm *ssm, FpDevice *device)
2158 {
2159 4 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
2160 4 uint8_t para[PACKAGE_DATA_SIZE_MAX] = { 0 };
2161 4 FpPrint *print = NULL;
2162
2163 4 fpi_device_get_delete_data (device, &print);
2164 4 mafp_template_t delete_tpl = mafp_template_from_print (print);
2165
2166
4/5
✓ Branch 5 → 6 taken 1 time.
✓ Branch 5 → 8 taken 1 time.
✓ Branch 5 → 10 taken 1 time.
✓ Branch 5 → 12 taken 1 time.
✗ Branch 5 → 14 not taken.
4 switch (fpi_ssm_get_cur_state (ssm))
2167 {
2168 1 case MAPF_DELETE_TEMPLATE_TABLE:
2169 1 para[0] = 0; /* page no. */
2170 1 mafp_sensor_cmd (self, MOC_CMD_GET_TEMPLATE_TABLE, (const uint8_t *) &para, 1, fp_delete_tpl_table_cb);
2171 1 break;
2172
2173 1 case MAPF_DELETE_GET_TEMPLATE_INFO:
2174 1 para[0] = (delete_tpl.id >> 8) & 0xff; /* fp id high */
2175 1 para[1] = delete_tpl.id & 0xff; /* fp id low */
2176 1 mafp_sensor_cmd (self, MOC_CMD_GET_TEMPLATE_INFO, (const uint8_t *) &para, 2, fp_delete_get_tpl_info_cb);
2177 1 break;
2178
2179 1 case MAPF_DELETE_CLEAR_TEMPLATE_INFO:
2180 1 para[0] = (delete_tpl.id >> 8) & 0xff; /* fp id high */
2181 1 para[1] = delete_tpl.id & 0xff; /* fp id low */
2182 1 mafp_sensor_cmd (self, MOC_CMD_SAVE_TEMPLATE_INFO, (const uint8_t *) &para, 130, fp_delete_clear_tpl_info_cb);
2183 1 break;
2184
2185 1 case MAPF_DELETE_TEMPLATE:
2186 1 para[0] = (delete_tpl.id >> 8) & 0xff; /* tpl id high */
2187 1 para[1] = delete_tpl.id & 0xff; /* tpl id low */
2188 1 para[2] = 0; /* range high */
2189 1 para[3] = 1; /* range low */
2190 1 mafp_sensor_cmd (self, MOC_CMD_DELETE_TEMPLATE, (const uint8_t *) &para, 4, fp_delete_tpl_cb);
2191 1 break;
2192 }
2193 4 }
2194
2195 static void
2196 1 fp_delete_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
2197 {
2198 1 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (dev);
2199
2200 1 self->task_ssm = NULL;
2201
2202
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
1 if (error)
2203 fp_dbg ("delete tpl fail: %s", error->message);
2204 else
2205 1 fp_dbg ("delete tpl success");
2206
2207 1 fpi_device_delete_complete (dev, g_steal_pointer (&error));
2208 1 }
2209
2210 static void
2211 1 fp_delete_all_cb (FpiDeviceMafpmoc *self,
2212 mafp_cmd_response_t *resp,
2213 GError *error)
2214 {
2215 1 FpDevice *dev = FP_DEVICE (self);
2216
2217
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 5 taken 1 time.
1 if (error)
2218 {
2219 fpi_ssm_mark_failed (self->task_ssm, g_steal_pointer (&error));
2220 return;
2221 }
2222
2223 1 fp_dbg ("result: %d", resp->result);
2224
2225
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 9 taken 1 time.
1 if (resp->result != MAFP_SUCCESS)
2226 {
2227 mafp_mark_failed (dev, self->task_ssm, FP_DEVICE_ERROR_GENERAL,
2228 "Failed to empty templates, result: 0x%x", resp->result);
2229 return;
2230 }
2231 1 fpi_ssm_next_state (self->task_ssm);
2232 }
2233
2234 static void
2235 1 fp_delete_all_run_state (FpiSsm *ssm, FpDevice *device)
2236 {
2237 1 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
2238
2239
1/2
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 6 not taken.
1 switch (fpi_ssm_get_cur_state (ssm))
2240 {
2241 1 case MAPF_EMPTY_TEMPLATE:
2242 1 mafp_sensor_cmd (self, MOC_CMD_EMPTY, NULL, 0, fp_delete_all_cb);
2243 1 break;
2244 }
2245 1 }
2246
2247 static void
2248 1 fp_delete_all_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
2249 {
2250 1 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (dev);
2251
2252 1 self->task_ssm = NULL;
2253
2254
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
1 if (error)
2255 fp_dbg ("delete all fail: %s", error->message);
2256 else
2257 1 fp_dbg ("delete all success");
2258
2259 1 fpi_device_clear_storage_complete (dev, g_steal_pointer (&error));
2260 1 }
2261
2262 static void
2263 1 mafp_probe (FpDevice *device)
2264 {
2265 1 g_autoptr(GUsbInterface) interface = NULL;
2266 1 GUsbDevice *usb_dev;
2267
1/4
✗ Branch 46 → 47 not taken.
✗ Branch 46 → 48 not taken.
✓ Branch 53 → 54 taken 1 time.
✗ Branch 53 → 55 not taken.
1 g_autoptr(GError) error = NULL;
2268 1 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
2269
1/4
✗ Branch 44 → 45 not taken.
✗ Branch 44 → 46 not taken.
✗ Branch 51 → 52 not taken.
✓ Branch 51 → 53 taken 1 time.
1 g_autofree char *serial = NULL;
2270 1 uint64_t driver_data;
2271
2272 1 fp_dbg ("mafp_probe");
2273
2274 1 usb_dev = fpi_device_get_usb_device (device);
2275
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 1 time.
1 if (!g_usb_device_open (usb_dev, &error))
2276 {
2277 fpi_device_probe_complete (device, NULL, NULL, g_steal_pointer (&error));
2278 return;
2279 }
2280
2281 1 driver_data = fpi_device_get_driver_data (device);
2282 1 fp_dbg ("driver_data 0x%zx", driver_data);
2283 1 fp_dbg ("g_usb_device_reset");
2284
1/2
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 1 time.
1 if (!g_usb_device_reset (usb_dev, &error))
2285 goto err_close;
2286
2287 1 fp_dbg ("g_usb_device_get_interface");
2288 1 interface = g_usb_device_get_interface (usb_dev, MAFP_INTERFACE_CLASS,
2289 MAFP_INTERFACE_SUB_CLASS, MAFP_INTERFACE_PROTOCOL, &error);
2290
1/2
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 18 taken 1 time.
1 if (!interface)
2291 {
2292 fp_dbg ("interface null");
2293 goto err_close;
2294 }
2295 1 self->interface_num = g_usb_interface_get_number (interface);
2296 1 fp_dbg ("interface number %d", self->interface_num);
2297
2298 /* Claim usb interface */
2299
1/2
✗ Branch 21 → 22 not taken.
✓ Branch 21 → 23 taken 1 time.
1 if (!g_usb_device_claim_interface (usb_dev, self->interface_num, 0, &error))
2300 goto err_close;
2301
2302
1/2
✗ Branch 24 → 25 not taken.
✓ Branch 24 → 28 taken 1 time.
1 if (fpi_device_emulation_mode_enabled (device))
2303 {
2304 1 serial = g_strdup ("emulated-device");
2305 }
2306 else
2307 {
2308 serial = g_usb_device_get_string_descriptor (usb_dev,
2309 g_usb_device_get_serial_number_index (usb_dev),
2310 &error);
2311 if (error || !serial)
2312 {
2313 g_usb_device_release_interface (fpi_device_get_usb_device (device), 0, 0, NULL);
2314 goto err_close;
2315 }
2316 }
2317
2318
1/2
✗ Branch 34 → 35 not taken.
✓ Branch 34 → 36 taken 1 time.
1 g_clear_pointer (&self->serial_number, g_free);
2319 1 self->serial_number = g_strndup (serial, DEVICE_SN_SIZE - 1);
2320 1 fp_dbg ("serial: %s", serial);
2321
2322 1 g_usb_device_close (usb_dev, NULL);
2323 1 fpi_device_probe_complete (device, serial, NULL, NULL);
2324 1 return;
2325
2326 err_close:
2327 g_usb_device_close (usb_dev, NULL);
2328 fpi_device_probe_complete (device, NULL, NULL, g_steal_pointer (&error));
2329 }
2330
2331 static void
2332 1 mafp_init (FpDevice *device)
2333 {
2334 1 fp_dbg ("mafp_init");
2335 1 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
2336 1 g_autoptr(GError) error = NULL;
2337
1/4
✗ Branch 49 → 50 not taken.
✓ Branch 49 → 51 taken 1 time.
✗ Branch 54 → 55 not taken.
✗ Branch 54 → 56 not taken.
1 g_autofree char *serial = NULL;
2338 1 uint64_t driver_data;
2339
2340 1 driver_data = fpi_device_get_driver_data (device);
2341 1 fp_dbg ("driver_data 0x%zx", driver_data);
2342 1 fp_dbg ("g_usb_device_reset");
2343
1/2
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 11 taken 1 time.
1 if (!g_usb_device_reset (fpi_device_get_usb_device (device), &error))
2344 {
2345 fp_dbg ("g_usb_device_reset err: %s", error->message);
2346 fpi_device_open_complete (FP_DEVICE (self), g_steal_pointer (&error));
2347 return;
2348 }
2349
2350 /* Claim usb interface */
2351 1 fp_dbg ("g_usb_device_claim_interface");
2352
1/2
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 17 taken 1 time.
1 if (!g_usb_device_claim_interface (fpi_device_get_usb_device (device), 0, 0, &error))
2353 {
2354 fpi_device_open_complete (FP_DEVICE (self), g_steal_pointer (&error));
2355 return;
2356 }
2357
2358
1/2
✓ Branch 18 → 19 taken 1 time.
✗ Branch 18 → 20 not taken.
1 if (fp_device_has_feature (device, FP_DEVICE_FEATURE_STORAGE))
2359 1 fp_dbg ("device has storage");
2360 else
2361 fp_dbg ("device no storage");
2362
2363
1/2
✗ Branch 22 → 23 not taken.
✓ Branch 22 → 28 taken 1 time.
1 if (fpi_device_emulation_mode_enabled (device))
2364 {
2365 1 serial = g_strdup ("emulated-device");
2366 }
2367 else
2368 {
2369 g_autoptr(GError) serial_error = NULL;
2370
2371 serial = g_usb_device_get_string_descriptor (fpi_device_get_usb_device (device),
2372 g_usb_device_get_serial_number_index (fpi_device_get_usb_device (device)),
2373 &serial_error);
2374 if (serial_error)
2375 g_propagate_prefixed_error (&error,
2376 g_steal_pointer (&serial_error),
2377 "Failed to read device serial number: ");
2378 }
2379
2380
0/2
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 41 not taken.
1 if (!serial)
2381 {
2382 if (!error)
2383 error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
2384 "Failed to read device serial number");
2385 g_usb_device_release_interface (fpi_device_get_usb_device (device), 0, 0, NULL);
2386 fpi_device_open_complete (FP_DEVICE (self), g_steal_pointer (&error));
2387 return;
2388 }
2389
2390
1/2
✓ Branch 41 → 42 taken 1 time.
✗ Branch 41 → 43 not taken.
1 g_clear_pointer (&self->serial_number, g_free);
2391 1 self->serial_number = g_strndup (serial, DEVICE_SN_SIZE - 1);
2392
2393 1 self->templates = g_new0 (mafp_templates_t, 1);
2394 1 self->task_ssm = fpi_ssm_new (device, fp_init_run_state, MAPF_INIT_STATES);
2395
2396 1 if (!PRINT_SSM_DEBUG)
2397 1 fpi_ssm_silence_debug (self->task_ssm);
2398 1 fpi_ssm_start (self->task_ssm, fp_init_ssm_done);
2399 }
2400
2401 static void
2402 1 mafp_enroll (FpDevice *device)
2403 {
2404 1 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
2405
2406 1 self->enroll_stage = 0;
2407 1 self->finger_status = 0;
2408 1 self->press_state = MAFP_PRESS_WAIT_UP;
2409 1 self->capture_cnt = 0;
2410 1 self->enroll_identify_state = MAFP_ENROLL_IDENTIFY_ENABLED;
2411 1 self->enroll_dupl_del_state = MAFP_ENROLL_DUPLICATE_DELETE_ENABLED;
2412 1 self->enroll_dupl_area_state = MAFP_ENROLL_DUPLICATE_AREA_DENY;
2413 1 memset (self->templates, 0, sizeof (mafp_templates_t));
2414
2415 1 self->task_ssm = fpi_ssm_new_full (device, fp_enroll_sm_run_state,
2416 MAFP_ENROLL_STATES,
2417 MAFP_ENROLL_EXIT,
2418 "enroll");
2419
2420 1 if (!PRINT_SSM_DEBUG)
2421 1 fpi_ssm_silence_debug (self->task_ssm);
2422 1 fpi_ssm_start (self->task_ssm, fp_enroll_ssm_done);
2423 1 }
2424
2425 static void
2426 2 mafp_identify (FpDevice *device)
2427 {
2428 2 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
2429
2430 2 memset (self->templates, 0, sizeof (mafp_templates_t));
2431
2432 2 self->press_state = MAFP_PRESS_WAIT_UP;
2433 2 self->capture_cnt = 0;
2434 2 self->identify_match_print = NULL;
2435
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 2 times.
2 g_clear_object (&self->identify_new_print);
2436
2437 2 self->task_ssm = fpi_ssm_new_full (device, fp_identify_sm_run_state,
2438 MAPF_IDENTIFY_STATES,
2439 MAPF_IDENTIFY_EXIT,
2440 "identify");
2441
2442 2 if (!PRINT_SSM_DEBUG)
2443 2 fpi_ssm_silence_debug (self->task_ssm);
2444 2 fpi_ssm_start (self->task_ssm, fp_identify_ssm_done);
2445 2 }
2446
2447 static void
2448 1 mafp_template_list (FpDevice *device)
2449 {
2450 1 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
2451
2452 1 memset (self->templates, 0, sizeof (mafp_templates_t));
2453 1 self->templates->list = g_ptr_array_new_with_free_func (g_object_unref);
2454
2455 1 self->task_ssm = fpi_ssm_new (device, fp_list_run_state, MAPF_LIST_STATES);
2456 1 if (!PRINT_SSM_DEBUG)
2457 1 fpi_ssm_silence_debug (self->task_ssm);
2458 1 fpi_ssm_start (self->task_ssm, fp_list_ssm_done);
2459 1 }
2460
2461 static void
2462 1 mafp_template_delete (FpDevice *device)
2463 {
2464 1 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
2465
2466 1 self->task_ssm = fpi_ssm_new (device, fp_delete_run_state, MAPF_DELETE_STATES);
2467 1 if (!PRINT_SSM_DEBUG)
2468 1 fpi_ssm_silence_debug (self->task_ssm);
2469 1 fpi_ssm_start (self->task_ssm, fp_delete_ssm_done);
2470 1 }
2471
2472 static void
2473 1 mafp_template_delete_all (FpDevice *device)
2474 {
2475 1 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
2476
2477 1 self->task_ssm = fpi_ssm_new (device, fp_delete_all_run_state, MAPF_EMPTY_STATES);
2478 1 if (!PRINT_SSM_DEBUG)
2479 1 fpi_ssm_silence_debug (self->task_ssm);
2480 1 fpi_ssm_start (self->task_ssm, fp_delete_all_ssm_done);
2481 1 }
2482
2483 static void
2484 mafp_cancel (FpDevice *device)
2485 {
2486 fp_dbg ("mafp_cancel");
2487 }
2488
2489 static gboolean
2490 1 mafp_release_interface (FpiDeviceMafpmoc *self,
2491 GError **error)
2492 {
2493 /* Release usb interface */
2494 1 return g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (self)),
2495 0, 0, error);
2496 }
2497
2498 static void
2499 1 mafp_exit (FpDevice *device)
2500 {
2501 2 g_autoptr(GError) error = NULL;
2502
2503 1 fp_dbg ("mafp_exit");
2504 1 FpiDeviceMafpmoc *self = FPI_DEVICE_MAFPMOC (device);
2505
2506 1 mafp_release_interface (self, &error);
2507 1 fpi_device_close_complete (FP_DEVICE (self), g_steal_pointer (&error));
2508
1/2
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 7 not taken.
1 g_clear_pointer (&self->serial_number, g_free);
2509
1/2
✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 9 not taken.
1 g_clear_pointer (&self->enroll_user_id, g_free);
2510
1/2
✓ Branch 9 → 10 taken 1 time.
✗ Branch 9 → 12 not taken.
1 if (self->templates)
2511
1/2
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 1 time.
1 g_clear_pointer (&self->templates->list, g_ptr_array_unref);
2512
2/4
✓ Branch 12 → 13 taken 1 time.
✗ Branch 12 → 14 not taken.
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 16 taken 1 time.
1 g_clear_pointer (&self->templates, g_free);
2513 1 }
2514
2515 static void
2516 1 fpi_device_mafpmoc_init (FpiDeviceMafpmoc *self)
2517 {
2518 1 fp_dbg ("fpi_device_mafpmoc_init");
2519 1 }
2520
2521 static const FpIdEntry id_table[] = {
2522 { .vid = 0x3274, .pid = 0x8012, },
2523 { .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
2524 };
2525
2526 static void
2527 125 fpi_device_mafpmoc_class_init (FpiDeviceMafpmocClass *klass)
2528 {
2529 125 FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
2530 125 const char *env_enroll_samples;
2531
2532 125 dev_class->id = "mafpmoc";
2533 125 dev_class->full_name = "MAFP MOC Fingerprint Sensor";
2534 125 dev_class->type = FP_DEVICE_TYPE_USB;
2535 125 dev_class->scan_type = FP_SCAN_TYPE_PRESS;
2536 125 dev_class->id_table = id_table;
2537 125 dev_class->nr_enroll_stages = DEFAULT_ENROLL_SAMPLES;
2538 125 dev_class->temp_hot_seconds = -1;
2539
2540 125 dev_class->open = mafp_init;
2541 125 dev_class->close = mafp_exit;
2542 125 dev_class->probe = mafp_probe;
2543 125 dev_class->enroll = mafp_enroll;
2544 125 dev_class->cancel = mafp_cancel;
2545 125 dev_class->identify = mafp_identify;
2546 125 dev_class->delete = mafp_template_delete;
2547 125 dev_class->clear_storage = mafp_template_delete_all;
2548 125 dev_class->list = mafp_template_list;
2549
2550 125 env_enroll_samples = getenv (MAFP_ENV_ENROLL_SAMPLES);
2551
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 7 taken 125 times.
125 if (env_enroll_samples)
2552 {
2553 guint64 max_enroll_stage = g_ascii_strtoll (env_enroll_samples, NULL, 10);
2554
2555 if (max_enroll_stage > 0 && max_enroll_stage <= 30)
2556 dev_class->nr_enroll_stages = max_enroll_stage;
2557 }
2558
2559 125 fpi_device_class_auto_initialize_features (dev_class);
2560 125 }
2561