GCC Code Coverage Report


Directory: ./
File: libfprint/drivers/synaptics/bmkt_message.c
Date: 2024-09-16 14:36:32
Exec Total Coverage
Lines: 86 173 49.7%
Functions: 5 10 50.0%
Branches: 19 58 32.8%

Line Branch Exec Source
1 /*
2 * Copyright (C) 2019 Synaptics Inc
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include <glib.h>
20 #include "bmkt_response.h"
21 #include "bmkt_message.h"
22
23 static uint8_t
24 12 extract8 (const uint8_t *buf, int *offset)
25 {
26 12 uint8_t ret = 0;
27 12 int off = 0;
28
29 12 if (offset)
30 off = *offset;
31
32 12 ret = *(buf + off);
33
34 12 if (offset)
35 *offset += 1;
36
37 12 return ret;
38 }
39
40
41 static int
42 1 parse_error_response (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
43 {
44 1 if (msg_resp->payload_len != 2)
45 return BMKT_UNRECOGNIZED_MESSAGE;
46
47 1 resp->result = (msg_resp->payload[0] << 8) | msg_resp->payload[1];
48
49 1 return BMKT_SUCCESS;
50 }
51
52 static int
53 1 parse_init_ok (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
54 {
55 1 bmkt_init_resp_t *init_resp = &resp->response.init_resp;
56
57 1 if (msg_resp->payload_len != 1)
58 return BMKT_UNRECOGNIZED_MESSAGE;
59
60 1 init_resp->finger_presence = extract8 (msg_resp->payload, NULL);
61
62 1 return BMKT_SUCCESS;
63 }
64
65
66 static int
67 parse_fps_mode_report (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
68 {
69 int offset = 0;
70 bmkt_fps_mode_resp_t *fps_mode_resp = &resp->response.fps_mode_resp;
71
72 if (msg_resp->payload_len != sizeof (bmkt_fps_mode_resp_t))
73 return BMKT_UNRECOGNIZED_MESSAGE;
74
75 fps_mode_resp->mode = extract8 (msg_resp->payload, &offset);
76 fps_mode_resp->level2_mode = extract8 (msg_resp->payload, &offset);
77 fps_mode_resp->cmd_id = extract8 (msg_resp->payload, &offset);
78 fps_mode_resp->finger_presence = extract8 (msg_resp->payload, &offset);
79
80 return BMKT_SUCCESS;
81 }
82
83 static int
84 9 parse_enroll_report (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
85 {
86 9 bmkt_enroll_resp_t *enroll_resp = &resp->response.enroll_resp;
87
88 9 if (msg_resp->payload_len != 1)
89 return BMKT_UNRECOGNIZED_MESSAGE;
90
91 9 enroll_resp->progress = extract8 (msg_resp->payload, NULL);
92
93 9 return BMKT_SUCCESS;
94 }
95
96 static int
97 1 parse_enroll_ok (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
98 {
99 1 bmkt_enroll_resp_t *enroll_resp = &resp->response.enroll_resp;
100
101
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (msg_resp->payload_len < 1 || msg_resp->payload_len > (BMKT_MAX_USER_ID_LEN + 1))
102 return BMKT_UNRECOGNIZED_MESSAGE;
103
104 1 enroll_resp->finger_id = msg_resp->payload[0];
105 1 memcpy (enroll_resp->user_id, &msg_resp->payload[1], msg_resp->payload_len - 1);
106
107 1 return BMKT_SUCCESS;
108 }
109
110 static int
111 1 parse_auth_ok (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
112 {
113 1 bmkt_identify_resp_t *id_resp = &resp->response.id_resp;
114
115
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (msg_resp->payload_len < 3 || msg_resp->payload_len > (BMKT_MAX_USER_ID_LEN + 3))
116 return BMKT_UNRECOGNIZED_MESSAGE;
117
118 1 id_resp->match_result = (double) msg_resp->payload[0] + 0.01 * (double) msg_resp->payload[1];
119 1 id_resp->finger_id = msg_resp->payload[2];
120 1 memcpy (id_resp->user_id, &msg_resp->payload[3], msg_resp->payload_len - 3);
121
122 1 return BMKT_SUCCESS;
123 }
124
125 static int
126 parse_security_level_report (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
127 {
128 bmkt_set_sec_level_resp_t *sec_level_resp = &resp->response.sec_level_resp;
129
130 if (msg_resp->payload_len != 1)
131 return BMKT_UNRECOGNIZED_MESSAGE;
132
133 sec_level_resp->sec_level = extract8 (msg_resp->payload, NULL);
134
135 return BMKT_SUCCESS;
136 }
137
138 static int
139 2 parse_del_all_users_progress_report (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
140 {
141 2 bmkt_del_all_users_resp_t *del_all_users_resp = &resp->response.del_all_users_resp;
142
143 2 if (msg_resp->payload_len != 1)
144 return BMKT_UNRECOGNIZED_MESSAGE;
145
146 2 del_all_users_resp->progress = extract8 (msg_resp->payload, NULL);
147
148 2 return BMKT_SUCCESS;
149 }
150
151 static int
152 parse_db_cap_report (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
153 {
154 bmkt_get_db_capacity_resp_t *db_cap_resp = &resp->response.db_cap_resp;
155 int offset = 0;
156
157 if (msg_resp->payload_len < 2 || msg_resp->payload_len > 4)
158 return BMKT_UNRECOGNIZED_MESSAGE;
159
160 db_cap_resp->total = extract8 (msg_resp->payload, &offset);
161 db_cap_resp->empty = extract8 (msg_resp->payload, &offset);
162
163 if (msg_resp->payload_len == 4)
164 {
165 db_cap_resp->bad_slots = extract8 (msg_resp->payload, &offset);
166 db_cap_resp->corrupt_templates = extract8 (msg_resp->payload, &offset);
167 }
168
169 return BMKT_SUCCESS;
170 }
171
172 static int
173 parse_get_enrolled_fingers_report (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
174 {
175 int offset = 0;
176 int i = 0;
177
178 if (msg_resp->payload_len < 2)
179 return BMKT_UNRECOGNIZED_MESSAGE;
180 /* 2 bytes per finger so calculate the total number of fingers to process*/
181 int num_fingers = (msg_resp->payload_len) / 2;
182
183 bmkt_enrolled_fingers_resp_t *get_enrolled_fingers_resp = &resp->response.enrolled_fingers_resp;
184
185 for (i = 0; i < num_fingers; i++)
186 {
187 get_enrolled_fingers_resp->fingers[i].finger_id = extract8 (msg_resp->payload, &offset);
188 get_enrolled_fingers_resp->fingers[i].template_status = extract8 (msg_resp->payload, &offset);
189
190 }
191 return BMKT_SUCCESS;
192 }
193 static int
194 parse_get_enrolled_users_report (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
195 {
196 int offset = 0;
197 int i = 0;
198
199 /* the payload is 2 bytes + template data */
200 if (msg_resp->payload_len < 2)
201 return BMKT_UNRECOGNIZED_MESSAGE;
202
203 bmkt_enroll_templates_resp_t *get_enroll_templates_resp = &resp->response.enroll_templates_resp;
204
205 get_enroll_templates_resp->total_query_messages = extract8 (msg_resp->payload, &offset);
206 get_enroll_templates_resp->query_sequence = extract8 (msg_resp->payload, &offset);
207
208 int n = 0;
209
210 for (n = 0; n < BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH; n++)
211 {
212 if (offset >= msg_resp->payload_len)
213 break;
214 get_enroll_templates_resp->templates[n].user_id_len = extract8 (msg_resp->payload, &offset) - 2;
215 if(get_enroll_templates_resp->templates[n].user_id_len > BMKT_MAX_USER_ID_LEN)
216 return BMKT_UNRECOGNIZED_MESSAGE;
217 get_enroll_templates_resp->templates[n].template_status = extract8 (msg_resp->payload, &offset);
218 get_enroll_templates_resp->templates[n].finger_id = extract8 (msg_resp->payload, &offset);
219 for (i = 0; i < get_enroll_templates_resp->templates[n].user_id_len; i++)
220 get_enroll_templates_resp->templates[n].user_id[i] = extract8 (msg_resp->payload, &offset);
221 get_enroll_templates_resp->templates[n].user_id[i] = '\0';
222 }
223
224 return BMKT_SUCCESS;
225 }
226
227 static int
228 parse_get_version_report (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
229 {
230 bmkt_get_version_resp_t *get_version_resp = &resp->response.get_version_resp;
231 int offset = 0;
232
233 if (msg_resp->payload_len != 15)
234 return BMKT_UNRECOGNIZED_MESSAGE;
235
236 memcpy (get_version_resp->part, msg_resp->payload, BMKT_PART_NUM_LEN);
237 offset += BMKT_PART_NUM_LEN;
238 get_version_resp->year = extract8 (msg_resp->payload, &offset);
239 get_version_resp->week = extract8 (msg_resp->payload, &offset);
240 get_version_resp->patch = extract8 (msg_resp->payload, &offset);
241 memcpy (get_version_resp->supplier_id, msg_resp->payload + offset, BMKT_SUPPLIER_ID_LEN);
242
243 return BMKT_SUCCESS;
244 }
245
246 int
247 7 bmkt_compose_message (uint8_t *cmd, int *cmd_len, uint8_t msg_id, uint8_t seq_num,
248 uint8_t payload_size, const uint8_t *payload)
249 {
250 7 int message_len = BMKT_MESSAGE_HEADER_LEN + payload_size;
251
252
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if (*cmd_len < message_len)
253 return BMKT_OUT_OF_MEMORY;
254
255 7 cmd[BMKT_MESSAGE_HEADER_ID_FIELD] = BMKT_MESSAGE_HEADER_ID;
256 7 cmd[BMKT_MESSAGE_SEQ_NUM_FIELD] = seq_num;
257 7 cmd[BMKT_MESSAGE_ID_FIELD] = msg_id;
258 7 cmd[BMKT_MESSAGE_PAYLOAD_LEN_FIELD] = payload_size;
259 7 memcpy (&cmd[BMKT_MESSAGE_PAYLOAD_FIELD], payload, payload_size);
260
261 7 *cmd_len = message_len;
262
263 7 return BMKT_SUCCESS;
264 }
265
266 int
267 52 bmkt_parse_message_header (uint8_t *resp_buf, int resp_len, bmkt_msg_resp_t *msg_resp)
268 {
269
1/2
✓ Branch 0 taken 52 times.
✗ Branch 1 not taken.
52 if (resp_buf[BMKT_MESSAGE_HEADER_ID_FIELD] != BMKT_MESSAGE_HEADER_ID)
270 return BMKT_CORRUPT_MESSAGE;
271
272 52 msg_resp->seq_num = resp_buf[BMKT_MESSAGE_SEQ_NUM_FIELD];
273 52 msg_resp->msg_id = resp_buf[BMKT_MESSAGE_ID_FIELD];
274 52 msg_resp->payload_len = resp_buf[BMKT_MESSAGE_PAYLOAD_LEN_FIELD];
275
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 14 times.
52 if (msg_resp->payload_len > 0)
276 38 msg_resp->payload = &resp_buf[BMKT_MESSAGE_PAYLOAD_FIELD];
277 else
278 14 msg_resp->payload = NULL;
279
280 return BMKT_SUCCESS;
281 }
282
283 int
284 52 bmkt_parse_message_payload (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
285 {
286 52 int ret = BMKT_SUCCESS;
287
288 52 memset (resp, 0, sizeof (bmkt_response_t));
289
290 52 resp->response_id = msg_resp->msg_id;
291
292
9/16
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 9 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 1 times.
52 switch(msg_resp->msg_id)
293 {
294 case BMKT_RSP_CONTINUOUS_IMAGE_CAPTURE_FAIL:
295 case BMKT_RSP_SENSOR_MODULE_TEST_FAIL:
296 case BMKT_RSP_FPS_INIT_FAIL:
297 case BMKT_RSP_FPS_MODE_FAIL:
298 case BMKT_RSP_SET_SECURITY_LEVEL_FAIL:
299 case BMKT_RSP_GET_SECURITY_LEVEL_FAIL:
300 case BMKT_RSP_CANCEL_OP_FAIL:
301 case BMKT_RSP_ENROLL_FAIL:
302 case BMKT_RSP_ID_FAIL:
303 case BMKT_RSP_VERIFY_FAIL:
304 case BMKT_RSP_QUERY_FAIL:
305 case BMKT_RSP_DEL_USER_FP_FAIL:
306 case BMKT_RSP_DEL_FULL_DB_FAIL:
307 case BMKT_RSP_REPEAT_LAST_BMKT_RSP_FAIL:
308 case BMKT_RSP_POWER_DOWN_FAIL:
309 case BMKT_RSP_GET_VERSION_FAIL:
310 case BMKT_RSP_DISABLE_PAIRING_FAIL:
311 case BMKT_RSP_QUERY_PAIRING_FAIL:
312 case BMKT_RSP_SENSOR_STATUS_FAIL:
313 case BMKT_RSP_RETRIEVE_FINAL_RESULT_FAIL:
314
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 ret = parse_error_response (msg_resp, resp);
315 1 resp->complete = 1;
316 1 break;
317
318 case BMKT_RSP_FPS_INIT_OK:
319
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 ret = parse_init_ok (msg_resp, resp);
320 1 resp->complete = 1;
321 1 break;
322
323 2 case BMKT_RSP_CANCEL_OP_OK:
324 case BMKT_RSP_DEL_FULL_DB_OK:
325 case BMKT_RSP_DEL_USER_FP_OK:
326 /* responses with a payload of 0
327 so the response indicates success */
328 2 resp->result = BMKT_SUCCESS;
329 2 resp->complete = 1;
330 2 break;
331
332 case BMKT_RSP_FPS_MODE_REPORT:
333 // parse_fps_mode
334 ret = parse_fps_mode_report (msg_resp, resp);
335 resp->complete = 1;
336 break;
337
338 case BMKT_RSP_GET_SECURITY_LEVEL_REPORT:
339 case BMKT_RSP_SET_SECURITY_LEVEL_REPORT:
340 /* parse security level result */
341 ret = parse_security_level_report (msg_resp, resp);
342 resp->complete = 1;
343 break;
344
345 case BMKT_RSP_DELETE_PROGRESS:
346
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 ret = parse_del_all_users_progress_report (msg_resp, resp);
347 break;
348
349 case BMKT_RSP_CAPTURE_COMPLETE:
350 resp->result = BMKT_SUCCESS;
351 break;
352
353 case BMKT_RSP_ENROLL_READY:
354 resp->result = BMKT_SUCCESS;
355 break;
356
357 case BMKT_RSP_ENROLL_REPORT:
358
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 ret = parse_enroll_report (msg_resp, resp);
359 break;
360
361 1 case BMKT_RSP_ENROLL_OK:
362 1 resp->complete = 1;
363 1 ret = parse_enroll_ok (msg_resp, resp);
364 1 break;
365
366 1 case BMKT_RSP_ID_OK:
367 case BMKT_RSP_VERIFY_OK:
368 1 ret = parse_auth_ok (msg_resp, resp);
369 1 resp->complete = 1;
370 1 break;
371
372 case BMKT_RSP_GET_ENROLLED_FINGERS_REPORT:
373 ret = parse_get_enrolled_fingers_report (msg_resp, resp);
374 resp->complete = 1;
375 break;
376
377 case BMKT_RSP_DATABASE_CAPACITY_REPORT:
378 resp->complete = 1;
379 ret = parse_db_cap_report (msg_resp, resp);
380 break;
381
382 case BMKT_RSP_TEMPLATE_RECORDS_REPORT:
383 ret = parse_get_enrolled_users_report (msg_resp, resp);
384 break;
385
386 case BMKT_RSP_QUERY_RESPONSE_COMPLETE:
387 resp->complete = 1;
388 break;
389
390 case BMKT_RSP_VERSION_INFO:
391 ret = parse_get_version_report (msg_resp, resp);
392 resp->complete = 1;
393 break;
394
395 1 case BMKT_RSP_POWER_DOWN_READY:
396 1 resp->complete = 1;
397 1 break;
398 }
399
400 52 return ret;
401 }
402