GCC Code Coverage Report


Directory: ./
File: libfprint/drivers/goodixmoc/goodix_proto.c
Date: 2024-05-04 14:54:39
Exec Total Coverage
Lines: 179 190 94.2%
Functions: 10 10 100.0%
Branches: 65 106 61.3%

Line Branch Exec Source
1 /*
2 * Goodix Moc driver for libfprint
3 * Copyright (C) 2019 Shenzhen Goodix Technology Co., Ltd.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include <glib.h>
21 #include "goodix_proto.h"
22
23 /*
24 * Crc functions
25 */
26
27 #define WIDTH (8 * sizeof (uint32_t))
28 #define FINAL_XOR_VALUE 0xFFFFFFFF
29 #define REFLECT_DATA(X) ((uint8_t) reflect ((X), 8))
30 #define REFLECT_REMAINDER(X) ((unsigned int) reflect ((X), WIDTH))
31
32
33 uint8_t
34 55 gx_proto_crc8_calc (uint8_t *lubp_date, uint32_t lui_len)
35 {
36 55 const uint8_t *data = lubp_date;
37 55 unsigned int crc = 0;
38 55 int i, j;
39
40
2/2
✓ Branch 0 taken 330 times.
✓ Branch 1 taken 55 times.
385 for (j = lui_len; j; j--, data++)
41 {
42 330 crc ^= (*data << 8);
43
2/2
✓ Branch 0 taken 2640 times.
✓ Branch 1 taken 330 times.
2970 for (i = 8; i; i--)
44 {
45
2/2
✓ Branch 0 taken 1239 times.
✓ Branch 1 taken 1401 times.
2640 if (crc & 0x8000)
46 1239 crc ^= (0x1070 << 3);
47 2640 crc <<= 1;
48 }
49 }
50
51 55 crc >>= 8;
52 55 crc = ~crc;
53 55 return (uint8_t) crc;
54 }
55
56 typedef struct
57 {
58 uint32_t crc;
59 } gf_crc32_context;
60
61 static uint32_t s_crc_table[256] =
62 { 0x0, 0x4c11db7, 0x9823b6e, 0xd4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
63 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
64 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
65 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
66 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
67 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
68 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
69 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
70 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
71 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x18aeb13, 0x54bf6a4, 0x808d07d, 0xcc9cdca,
72 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
73 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
74 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
75 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
76 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
77 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
78 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
79 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
80 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
81 0x315d626, 0x7d4cb91, 0xa97ed48, 0xe56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
82 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
83 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
84 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
85 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
86 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
87 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
88 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x29f3d35, 0x65e2082, 0xb1d065b, 0xfdc1bec,
89 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
90 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
91 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
92 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
93 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4};
94
95 static uint32_t
96 3771 reflect (uint32_t data, uint8_t n_bits)
97 {
98 3771 unsigned long reflection = 0x00000000;
99 3771 uint8_t bit;
100
101 /*
102 * Reflect the data about the center bit.
103 */
104
4/4
✓ Branch 0 taken 5312 times.
✓ Branch 1 taken 166 times.
✓ Branch 2 taken 28840 times.
✓ Branch 3 taken 3605 times.
37923 for (bit = 0; bit < n_bits; ++bit)
105 {
106 /*
107 * If the LSB bit is set, set the reflection of it.
108 */
109
4/4
✓ Branch 0 taken 2668 times.
✓ Branch 1 taken 2644 times.
✓ Branch 2 taken 5590 times.
✓ Branch 3 taken 23250 times.
34152 if (data & 0x01)
110 8258 reflection |= (1 << ((n_bits - 1) - bit));
111
112 34152 data = (data >> 1);
113 }
114
115 3771 return reflection;
116
117 }
118
119 static void
120 166 crc32_init (gf_crc32_context *ctx)
121 {
122 166 ctx->crc = 0xFFFFFFFF;
123 }
124
125 static void
126 166 crc32_update (gf_crc32_context *ctx, const uint8_t *message, uint32_t n_bytes)
127 {
128 166 uint8_t data;
129 166 uint32_t byte;
130
131 /*
132 * Divide the message by the polynomial, a byte at a time.
133 */
134
2/2
✓ Branch 0 taken 3605 times.
✓ Branch 1 taken 166 times.
3771 for (byte = 0; byte < n_bytes; ++byte)
135 {
136 3605 data = REFLECT_DATA (message[byte]) ^ (ctx->crc >> (WIDTH - 8));
137 3605 ctx->crc = s_crc_table[data] ^ (ctx->crc << 8);
138 }
139 166 }
140
141 static void
142 166 crc32_final (gf_crc32_context *ctx, uint8_t *md)
143 {
144 166 uint32_t crc = 0;
145
146 166 ctx->crc = (REFLECT_REMAINDER (ctx->crc) ^ FINAL_XOR_VALUE);
147 166 crc = GUINT32_TO_LE (ctx->crc);
148 166 memcpy (md, &crc, 4);
149 166 }
150
151 uint8_t
152 166 gx_proto_crc32_calc (uint8_t *pchMsg, uint32_t wDataLen, uint8_t *pchMsgDst)
153 {
154 166 gf_crc32_context context = { 0 };
155
156
1/2
✓ Branch 0 taken 166 times.
✗ Branch 1 not taken.
166 if (!pchMsg)
157 return 0;
158
159 166 crc32_init (&context);
160
161 166 crc32_update (&context, pchMsg, wDataLen);
162
163 166 crc32_final (&context, pchMsgDst);
164
165
166 166 return 1;
167 }
168 /*
169 * protocol
170 *
171 */
172
173 static uint8_t dump_seq = 0;
174
175 static void
176 55 init_pack_header (
177 ppack_header pheader,
178 uint16_t len,
179 uint16_t cmd,
180 uint8_t packagenum
181 )
182 {
183
1/2
✓ Branch 0 taken 55 times.
✗ Branch 1 not taken.
55 g_assert (pheader);
184
185 55 memset (pheader, 0, sizeof (*pheader));
186 55 pheader->cmd0 = HIBYTE (cmd);
187 55 pheader->cmd1 = LOBYTE (cmd);
188 55 pheader->packagenum = packagenum;
189 55 pheader->reserved = dump_seq++;
190 55 pheader->len = GUINT16_TO_LE (len + PACKAGE_CRC_SIZE);
191 55 pheader->crc8 = gx_proto_crc8_calc ((uint8_t *) pheader, 6);
192 55 pheader->rev_crc8 = ~pheader->crc8;
193 55 }
194
195
196 int
197 55 gx_proto_build_package (uint8_t *ppackage,
198 uint32_t *package_len,
199 uint16_t cmd,
200 const uint8_t *payload,
201 uint32_t payload_size)
202 {
203 55 pack_header header;
204
205
1/2
✓ Branch 0 taken 55 times.
✗ Branch 1 not taken.
55 if (!ppackage || !package_len)
206 return -1;
207
208
1/2
✓ Branch 0 taken 55 times.
✗ Branch 1 not taken.
55 if(*package_len < (payload_size + PACKAGE_HEADER_SIZE + PACKAGE_CRC_SIZE))
209 return -1;
210
211 55 init_pack_header (&header, payload_size, cmd, 0);
212
213 55 memcpy (ppackage, &header, PACKAGE_HEADER_SIZE);
214 55 memcpy (ppackage + PACKAGE_HEADER_SIZE, payload, payload_size);
215
216 55 gx_proto_crc32_calc (ppackage, PACKAGE_HEADER_SIZE + payload_size, ppackage + PACKAGE_HEADER_SIZE + payload_size);
217
218 55 return 0;
219 }
220
221
222 int
223 110 gx_proto_parse_header (
224 uint8_t *buffer,
225 uint32_t buffer_len,
226 pack_header *pheader)
227 {
228
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 110 times.
110 if (!buffer || !pheader)
229 return -1;
230
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 110 times.
110 if (buffer_len < PACKAGE_HEADER_SIZE + PACKAGE_CRC_SIZE)
231 return -1;
232
233 110 memcpy (pheader, buffer, sizeof (pack_header));
234 110 pheader->len = GUINT16_FROM_LE (pheader->len);
235
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 110 times.
110 if (buffer_len < pheader->len + PACKAGE_HEADER_SIZE)
236 return -1;
237 110 pheader->len -= PACKAGE_CRC_SIZE;
238 110 return 0;
239 }
240
241 static int
242 3 gx_proto_parse_fingerid (
243 uint8_t * fid_buffer,
244 uint16_t fid_buffer_size,
245 ptemplate_format_t template
246 )
247 {
248 3 uint8_t * buffer = NULL;
249 3 uint16_t Offset = 0;
250
251
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!template || !fid_buffer)
252 return -1;
253
254
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (fid_buffer_size < G_STRUCT_OFFSET (template_format_t, payload) + sizeof (uint32_t))
255 return -1;
256
257 3 buffer = fid_buffer;
258 3 Offset = 0;
259
260
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (buffer[Offset++] != 67)
261 return -1;
262
263 3 template->type = buffer[Offset++];
264 3 template->finger_index = buffer[Offset++];
265 3 Offset++;
266 3 memcpy (template->accountid, &buffer[Offset], sizeof (template->accountid));
267 3 Offset += sizeof (template->accountid);
268 3 memcpy (template->tid, &buffer[Offset], sizeof (template->tid));
269 3 Offset += sizeof (template->tid); // Offset == 68
270 3 template->payload.size = buffer[Offset++];
271
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (template->payload.size > sizeof (template->payload.data))
272 return -1;
273
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (template->payload.size + Offset > fid_buffer_size)
274 return -1;
275 3 memset (template->payload.data, 0, template->payload.size);
276 3 memcpy (template->payload.data, &buffer[Offset], template->payload.size);
277
278 3 return 0;
279 }
280
281 int
282 110 gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint16_t buffer_len, pgxfp_cmd_response_t presp)
283 {
284 110 uint16_t offset = 0;
285 110 uint8_t *fingerlist = NULL;
286
287
1/2
✓ Branch 0 taken 110 times.
✗ Branch 1 not taken.
110 if (!buffer || !presp)
288 return -1;
289
1/2
✓ Branch 0 taken 110 times.
✗ Branch 1 not taken.
110 if (buffer_len < 1)
290 return -1;
291 110 presp->result = buffer[0];
292
12/12
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 14 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 12 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 3 times.
✓ Branch 10 taken 2 times.
✓ Branch 11 taken 11 times.
110 switch (HIBYTE (cmd))
293 {
294 55 case RESPONSE_PACKAGE_CMD:
295 {
296
1/2
✓ Branch 0 taken 55 times.
✗ Branch 1 not taken.
55 if (buffer_len < sizeof (gxfp_parse_msg_t) + 1)
297 return -1;
298 55 presp->parse_msg.ack_cmd = buffer[1];
299 }
300 55 break;
301
302 1 case MOC_CMD0_UPDATE_CONFIG:
303 {
304 1 presp->finger_config.status = buffer[0];
305
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buffer_len >= 3)
306 1 presp->finger_config.max_stored_prints = buffer[2];
307 else
308 /* to compatiable old version firmware */
309 presp->finger_config.max_stored_prints = FP_MAX_FINGERNUM;
310
311 }
312 break;
313
314 case MOC_CMD0_COMMITENROLLMENT:
315 case MOC_CMD0_DELETETEMPLATE:
316 /* just check result */
317 break;
318
319 6 case MOC_CMD0_PWR_BTN_SHIELD:
320 6 presp->power_button_shield_resp.resp_cmd1 = LOBYTE (cmd);
321
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (buffer_len >= 2)
322 {
323 6 uint8_t support_pwr_shield = buffer[1];
324
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (support_pwr_shield == 0xFF)
325 g_debug ("Power button shield feature not supported!\n");
326 }
327 break;
328
329 1 case MOC_CMD0_GET_VERSION:
330
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buffer_len < sizeof (gxfp_version_info_t) + 1)
331 return -1;
332 1 memcpy (&presp->version_info, buffer + 1, sizeof (gxfp_version_info_t));
333 1 break;
334
335 14 case MOC_CMD0_CAPTURE_DATA:
336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (LOBYTE (cmd) == MOC_CMD1_DEFAULT)
337 {
338
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 if (buffer_len < sizeof (gxfp_capturedata_t) + 1)
339 return -1;
340 14 presp->capture_data_resp.img_quality = buffer[1];
341 14 presp->capture_data_resp.img_coverage = buffer[2];
342 }
343 break;
344
345 1 case MOC_CMD0_ENROLL_INIT:
346
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buffer_len < sizeof (gxfp_enroll_create_t) + 1)
347 return -1;
348
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (presp->result == GX_SUCCESS)
349 1 memcpy (&presp->enroll_create.tid, &buffer[1], TEMPLATE_ID_SIZE);
350 break;
351
352 12 case MOC_CMD0_ENROLL:
353
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (buffer_len < sizeof (gxfp_enroll_update_t))
354 return -1;
355 12 presp->enroll_update.rollback = (buffer[0] < 0x80) ? false : true;
356 12 presp->enroll_update.img_overlay = buffer[1];
357 12 presp->enroll_update.img_preoverlay = buffer[2];
358 12 break;
359
360 1 case MOC_CMD0_CHECK4DUPLICATE:
361 1 presp->check_duplicate_resp.duplicate = (presp->result == 0) ? false : true;
362
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (presp->check_duplicate_resp.duplicate)
363 {
364 if (buffer_len < 3)
365 return -1;
366 uint16_t tid_size = GUINT16_FROM_LE (*(uint16_t *) (buffer + 1));
367 offset += 3;
368
369 if (buffer_len < tid_size + offset)
370 return -1;
371 if (gx_proto_parse_fingerid (buffer + offset, tid_size, &presp->check_duplicate_resp.template) != 0)
372 return -1;
373 }
374 break;
375
376 3 case MOC_CMD0_GETFINGERLIST:
377
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (presp->result != GX_SUCCESS)
378 break;
379
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (buffer_len < 2)
380 return -1;
381 3 presp->finger_list_resp.finger_num = buffer[1];
382 3 fingerlist = buffer + 2;
383
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 for(uint8_t num = 0; num < presp->finger_list_resp.finger_num; num++)
384 {
385 1 uint16_t fingerid_length;
386
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buffer_len < offset + 2)
387 return -1;
388 1 fingerid_length = GUINT16_FROM_LE (*(uint16_t *) (fingerlist + offset));
389 1 offset += 2;
390
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (buffer_len < fingerid_length + offset)
391 return -1;
392
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (gx_proto_parse_fingerid (fingerlist + offset,
393 fingerid_length,
394 1 &presp->finger_list_resp.finger_list[num]) != 0)
395 {
396 g_warning ("Failed to parse finger list");
397 return -1;
398 }
399 1 offset += fingerid_length;
400 }
401 break;
402
403 2 case MOC_CMD0_IDENTIFY:
404 {
405 2 uint32_t score = 0;
406 2 uint8_t study = 0;
407 2 uint16_t fingerid_size = 0;
408 2 presp->verify.match = (buffer[0] == 0) ? true : false;
409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (presp->verify.match)
410 {
411
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (buffer_len < 10)
412 return -1;
413 2 offset += 1;
414 2 presp->verify.rejectdetail = GUINT16_FROM_LE (*(uint16_t *) (buffer + offset));
415 2 offset += 2;
416 2 score = GUINT32_FROM_LE (*(uint32_t *) (buffer + offset));
417 2 offset += 4;
418 2 study = buffer[offset];
419 2 offset += 1;
420 2 fingerid_size = GUINT16_FROM_LE (*(uint16_t *) (buffer + offset));
421 2 offset += 2;
422
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (buffer_len < fingerid_size + offset)
423 return -1;
424
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (gx_proto_parse_fingerid (buffer + offset, fingerid_size, &presp->verify.template) != 0)
425 {
426 presp->result = GX_FAILED;
427 break;
428 }
429 2 g_debug ("match, score: %d, study: %d", score, study);
430 }
431 }
432 break;
433
434 11 case MOC_CMD0_FINGER_MODE:
435 11 presp->finger_status.status = buffer[0];
436 11 break;
437
438 default:
439 break;
440 }
441
442 return 0;
443 }
444
445 static uint8_t sensor_config[26] = {
446 0x00, 0x00, 0x64, 0x50, 0x0f, 0x41, 0x08, 0x0a, 0x18, 0x00, 0x00, 0x23, 0x00,
447 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x05, 0x05
448 };
449
450 int
451 1 gx_proto_init_sensor_config (pgxfp_sensor_cfg_t pconfig)
452 {
453 1 uint32_t crc32_calc = 0;
454
455
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!pconfig)
456 return -1;
457 1 memset (pconfig, 0, sizeof (*pconfig));
458
459 //NOTICE: Do not change any value!
460 1 memcpy (&pconfig->config, sensor_config, G_N_ELEMENTS (sensor_config));
461 1 pconfig->reserved[0] = 1;
462
463 1 gx_proto_crc32_calc ((uint8_t *) pconfig, sizeof (*pconfig) - PACKAGE_CRC_SIZE, (uint8_t *) &crc32_calc);
464
465 1 memcpy (pconfig->crc_value, &crc32_calc, PACKAGE_CRC_SIZE);
466
467 1 return 0;
468 }
469