goodixmoc: Fix some big/little endian support issues

Goodix driver is not working fine in BigEndian architectures. This
commit fixes some of these issues.

Related: #236
This commit is contained in:
fengqiangguo 2020-12-16 10:31:46 +08:00 committed by Benjamin Berg
parent 3b83157e9b
commit e0c41c5444
3 changed files with 58 additions and 33 deletions

View file

@ -127,7 +127,7 @@ fp_cmd_receive_cb (FpiUsbTransfer *transfer,
} }
gx_proto_crc32_calc (transfer->buffer, PACKAGE_HEADER_SIZE + header.len, (uint8_t *) &crc32_calc); gx_proto_crc32_calc (transfer->buffer, PACKAGE_HEADER_SIZE + header.len, (uint8_t *) &crc32_calc);
if(crc32_calc != *(uint32_t *) (transfer->buffer + PACKAGE_HEADER_SIZE + header.len)) if(crc32_calc != GUINT32_FROM_LE (*(uint32_t *) (transfer->buffer + PACKAGE_HEADER_SIZE + header.len)))
{ {
fpi_ssm_mark_failed (transfer->ssm, fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,

View file

@ -141,8 +141,11 @@ crc32_update (gf_crc32_context *ctx, const uint8_t *message, uint32_t n_bytes)
static void static void
crc32_final (gf_crc32_context *ctx, uint8_t *md) crc32_final (gf_crc32_context *ctx, uint8_t *md)
{ {
uint32_t crc = 0;
ctx->crc = (REFLECT_REMAINDER (ctx->crc) ^ FINAL_XOR_VALUE); ctx->crc = (REFLECT_REMAINDER (ctx->crc) ^ FINAL_XOR_VALUE);
memcpy (md, &ctx->crc, 4); crc = GUINT32_TO_LE (ctx->crc);
memcpy (md, &crc, 4);
} }
uint8_t uint8_t
@ -184,7 +187,7 @@ init_pack_header (
pheader->cmd1 = LOBYTE (cmd); pheader->cmd1 = LOBYTE (cmd);
pheader->packagenum = packagenum; pheader->packagenum = packagenum;
pheader->reserved = dump_seq++; pheader->reserved = dump_seq++;
pheader->len = len + PACKAGE_CRC_SIZE; pheader->len = GUINT16_TO_LE (len + PACKAGE_CRC_SIZE);
pheader->crc8 = gx_proto_crc8_calc ((uint8_t *) pheader, 6); pheader->crc8 = gx_proto_crc8_calc ((uint8_t *) pheader, 6);
pheader->rev_crc8 = ~pheader->crc8; pheader->rev_crc8 = ~pheader->crc8;
} }
@ -224,14 +227,14 @@ gx_proto_parse_header (
{ {
if (!buffer || !pheader) if (!buffer || !pheader)
return -1; return -1;
if (buffer_len < PACKAGE_HEADER_SIZE) if (buffer_len < PACKAGE_HEADER_SIZE + PACKAGE_CRC_SIZE)
return -1; return -1;
memcpy (pheader, buffer, sizeof (pack_header)); memcpy (pheader, buffer, sizeof (pack_header));
pheader->len = GUINT16_FROM_LE (pheader->len);
pheader->len = GUINT16_FROM_LE ( *(uint16_t *) (buffer + 4)); if (buffer_len < pheader->len + PACKAGE_HEADER_SIZE)
return -1;
pheader->len -= PACKAGE_CRC_SIZE; pheader->len -= PACKAGE_CRC_SIZE;
return 0; return 0;
} }
@ -248,7 +251,7 @@ gx_proto_parse_fingerid (
if (!template || !fid_buffer) if (!template || !fid_buffer)
return -1; return -1;
if (fid_buffer_size < 70) if (fid_buffer_size < G_STRUCT_OFFSET (template_format_t, payload) + sizeof (uint32_t))
return -1; return -1;
buffer = fid_buffer; buffer = fid_buffer;
@ -256,28 +259,30 @@ gx_proto_parse_fingerid (
if (buffer[Offset++] != 67) if (buffer[Offset++] != 67)
return -1; return -1;
fid_buffer_size--;
template->type = buffer[Offset++]; template->type = buffer[Offset++];
fid_buffer_size--;
template->finger_index = buffer[Offset++]; template->finger_index = buffer[Offset++];
fid_buffer_size--;
Offset++; Offset++;
memcpy (template->accountid, &buffer[Offset], sizeof (template->accountid));
memcpy (template->accountid, &buffer[Offset], 32); Offset += sizeof (template->accountid);
Offset += 32; memcpy (template->tid, &buffer[Offset], sizeof (template->tid));
Offset += sizeof (template->tid); // Offset == 68
memcpy (template->tid, &buffer[Offset], 32);
Offset += 32; // Offset == 68
template->payload.size = buffer[Offset++]; template->payload.size = buffer[Offset++];
memset (template->payload.data, 0, 56); if (template->payload.size > sizeof (template->payload.data))
return -1;
memset (template->payload.data, 0, template->payload.size);
memcpy (template->payload.data, &buffer[Offset], template->payload.size); memcpy (template->payload.data, &buffer[Offset], template->payload.size);
return 0; return 0;
} }
int int
gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint32_t buffer_len, pgxfp_cmd_response_t presp) gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint16_t buffer_len, pgxfp_cmd_response_t presp)
{ {
uint32_t offset = 0; uint16_t offset = 0;
uint8_t *fingerlist = NULL; uint8_t *fingerlist = NULL;
if (!buffer || !presp) if (!buffer || !presp)
@ -289,6 +294,8 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint32_t buffer_len, pgxfp_c
{ {
case RESPONSE_PACKAGE_CMD: case RESPONSE_PACKAGE_CMD:
{ {
if (buffer_len < sizeof (gxfp_parse_msg_t) + 1)
return -1;
presp->parse_msg.ack_cmd = buffer[1]; presp->parse_msg.ack_cmd = buffer[1];
} }
break; break;
@ -296,32 +303,46 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint32_t buffer_len, pgxfp_c
case MOC_CMD0_UPDATE_CONFIG: case MOC_CMD0_UPDATE_CONFIG:
{ {
presp->finger_config.status = buffer[0]; presp->finger_config.status = buffer[0];
presp->finger_config.max_stored_prints = buffer[2]; if (buffer_len >= 3)
presp->finger_config.max_stored_prints = buffer[2];
else
/* to compatiable old version firmware */
presp->finger_config.max_stored_prints = FP_MAX_FINGERNUM;
} }
break; break;
case MOC_CMD0_COMMITENROLLMENT: case MOC_CMD0_COMMITENROLLMENT:
case MOC_CMD0_DELETETEMPLATE: case MOC_CMD0_DELETETEMPLATE:
/* just check result */
break; break;
case MOC_CMD0_GET_VERSION: case MOC_CMD0_GET_VERSION:
if (buffer_len < sizeof (gxfp_version_info_t) + 1)
return -1;
memcpy (&presp->version_info, buffer + 1, sizeof (gxfp_version_info_t)); memcpy (&presp->version_info, buffer + 1, sizeof (gxfp_version_info_t));
break; break;
case MOC_CMD0_CAPTURE_DATA: case MOC_CMD0_CAPTURE_DATA:
if (LOBYTE (cmd) == MOC_CMD1_DEFAULT) if (LOBYTE (cmd) == MOC_CMD1_DEFAULT)
{ {
if (buffer_len < sizeof (gxfp_capturedata_t) + 1)
return -1;
presp->capture_data_resp.img_quality = buffer[1]; presp->capture_data_resp.img_quality = buffer[1];
presp->capture_data_resp.img_coverage = buffer[2]; presp->capture_data_resp.img_coverage = buffer[2];
} }
break; break;
case MOC_CMD0_ENROLL_INIT: case MOC_CMD0_ENROLL_INIT:
if (buffer_len < sizeof (gxfp_enroll_init_t) + 1)
return -1;
if (presp->result == GX_SUCCESS) if (presp->result == GX_SUCCESS)
memcpy (&presp->enroll_init.tid, &buffer[1], TEMPLATE_ID_SIZE); memcpy (&presp->enroll_init.tid, &buffer[1], TEMPLATE_ID_SIZE);
break; break;
case MOC_CMD0_ENROLL: case MOC_CMD0_ENROLL:
if (buffer_len < sizeof (gxfp_enroll_update_t))
return -1;
presp->enroll_update.rollback = (buffer[0] < 0x80) ? false : true; presp->enroll_update.rollback = (buffer[0] < 0x80) ? false : true;
presp->enroll_update.img_overlay = buffer[1]; presp->enroll_update.img_overlay = buffer[1];
presp->enroll_update.img_preoverlay = buffer[2]; presp->enroll_update.img_preoverlay = buffer[2];
@ -331,7 +352,11 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint32_t buffer_len, pgxfp_c
presp->check_duplicate_resp.duplicate = (presp->result == 0) ? false : true; presp->check_duplicate_resp.duplicate = (presp->result == 0) ? false : true;
if (presp->check_duplicate_resp.duplicate) if (presp->check_duplicate_resp.duplicate)
{ {
uint16_t tid_size = GUINT16_FROM_LE (*(buffer + 1)); if (buffer_len < 3)
return -1;
uint16_t tid_size = GUINT16_FROM_LE (*(uint16_t *) (buffer + 1));
if ((buffer_len < tid_size + 3) || (buffer_len > sizeof (template_format_t)) + 3)
return -1;
memcpy (&presp->check_duplicate_resp.template, buffer + 3, tid_size); memcpy (&presp->check_duplicate_resp.template, buffer + 3, tid_size);
} }
break; break;
@ -339,18 +364,16 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint32_t buffer_len, pgxfp_c
case MOC_CMD0_GETFINGERLIST: case MOC_CMD0_GETFINGERLIST:
if (presp->result != GX_SUCCESS) if (presp->result != GX_SUCCESS)
break; break;
if (buffer_len < 2)
return -1;
presp->finger_list_resp.finger_num = buffer[1]; presp->finger_list_resp.finger_num = buffer[1];
if (presp->finger_list_resp.finger_num > FP_MAX_FINGERNUM)
{
presp->finger_list_resp.finger_num = 0;
presp->result = GX_ERROR_NO_AVAILABLE_SPACE;
break;
}
fingerlist = buffer + 2; fingerlist = buffer + 2;
for(uint8_t num = 0; num < presp->finger_list_resp.finger_num; num++) for(uint8_t num = 0; num < presp->finger_list_resp.finger_num; num++)
{ {
uint16_t fingerid_length = GUINT16_FROM_LE (*(fingerlist + offset)); uint16_t fingerid_length = GUINT16_FROM_LE (*(uint16_t *) (fingerlist + offset));
offset += 2; offset += 2;
if (buffer_len < fingerid_length + offset + 2)
return -1;
if (gx_proto_parse_fingerid (fingerlist + offset, if (gx_proto_parse_fingerid (fingerlist + offset,
fingerid_length, fingerid_length,
&presp->finger_list_resp.finger_list[num]) != 0) &presp->finger_list_resp.finger_list[num]) != 0)
@ -372,14 +395,16 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint32_t buffer_len, pgxfp_c
presp->verify.match = (buffer[0] == 0) ? true : false; presp->verify.match = (buffer[0] == 0) ? true : false;
if (presp->verify.match) if (presp->verify.match)
{ {
if (buffer_len < sizeof (template_format_t) + 10)
return -1;
offset += 1; offset += 1;
presp->verify.rejectdetail = GUINT16_FROM_LE (*(buffer + offset)); presp->verify.rejectdetail = GUINT16_FROM_LE (*(uint16_t *) (buffer + offset));
offset += 2; offset += 2;
score = GUINT32_FROM_LE (*(buffer + offset)); score = GUINT32_FROM_LE (*(uint32_t *) (buffer + offset));
offset += 4; offset += 4;
study = GUINT16_FROM_LE (*(buffer + offset)); study = buffer[offset];
offset += 1; offset += 1;
fingerid_size = GUINT16_FROM_LE (*(buffer + offset)); fingerid_size = GUINT16_FROM_LE (*(uint16_t *) (buffer + offset));
offset += 2; offset += 2;
if (gx_proto_parse_fingerid (buffer + offset, fingerid_size, &presp->verify.template) != 0) if (gx_proto_parse_fingerid (buffer + offset, fingerid_size, &presp->verify.template) != 0)
{ {

View file

@ -89,7 +89,7 @@ typedef struct _gxfp_version_info
uint8_t interface[GX_VERSION_LEN]; uint8_t interface[GX_VERSION_LEN];
uint8_t protocol[GX_VERSION_LEN]; uint8_t protocol[GX_VERSION_LEN];
uint8_t flashVersion[GX_VERSION_LEN]; uint8_t flashVersion[GX_VERSION_LEN];
uint8_t reserved[62]; uint8_t reserved[38];
} gxfp_version_info_t, *pgxfp_version_info_t; } gxfp_version_info_t, *pgxfp_version_info_t;
@ -225,7 +225,7 @@ int gx_proto_parse_header (uint8_t *buffer,
int gx_proto_parse_body (uint16_t cmd, int gx_proto_parse_body (uint16_t cmd,
uint8_t *buffer, uint8_t *buffer,
uint32_t buffer_len, uint16_t buffer_len,
pgxfp_cmd_response_t presponse); pgxfp_cmd_response_t presponse);
int gx_proto_init_sensor_config (pgxfp_sensor_cfg_t pconfig); int gx_proto_init_sensor_config (pgxfp_sensor_cfg_t pconfig);