Para desenvolver um aplicativo que funcionasse da maneira pedida pelos meus clientes, tive que alterar o código fonte dos dois aplicativos, a modo que a saída de erro pudesse ser capturada pela interface gráfica que eu desenvolvi. Não é nada muito complexo.
Edite o arquivo
enroll.c, localizado na pasta "examples".
Nesta parte eu editei a saída para uma maneira que eu pudesse capturar os erros, os nomeando de uma forma que se adequasse as minhas necessidades.
Procure esta parte do código e altere seguindo o meu exemplo:
switch (r) {
case FP_ENROLL_COMPLETE:
printf("FIM-OK\n");
break;
case FP_ENROLL_FAIL:
printf("FIM-FALHOU\n");
return NULL;
case FP_ENROLL_PASS:
printf("PASS\n");
break;
case FP_ENROLL_RETRY:
printf("FIM-NOVAMENTE\n");
break;
case FP_ENROLL_RETRY_TOO_SHORT:
printf("FIM-NOVAMENTE\n");
break;
case FP_ENROLL_RETRY_CENTER_FINGER:
printf("FIM-NOVAMENTE\n");
break;
case FP_ENROLL_RETRY_REMOVE_FINGER:
printf("FIM-NOVAMENTE\n");
break;
Esta parte é referente ao retorno do resultado do leitor, alterei o que o programa escrito em C retorna ao terminal.
Esta parte (fp_dev_open(ddev)) é referente a iniciar o leitor, depois que o programa testou a porta, e encontrou o mesmo. Comparando o original, você vai perceber que eu deletei uma parte do código, justamente a que pede que o usuário pressione enter para iniciar o dispositivo, nós não queremos que seja pedido que o dispositivo inicie somente após um "enter".
dev = fp_dev_open(ddev);
fp_dscv_devs_free(discovered_devs);
if (!dev) {
fprintf(stderr, "O FingerFx falhou ao abrir o dispositivo.\nFIM-DISP\n");
goto out;
}
printf("O FingerFx iniciou o dispositivo, vamos iniciar o cadastro.\n\n");
data = enroll(dev);
if (!data)
goto out_close;
r = fp_print_data_save(data, RIGHT_INDEX);
if (r < 0)
fprintf(stderr, "O FingerFx não conseguiu salvar os dados, erro: %d\n", r);
fp_print_data_free(data);
O mesmo foi feito com o
verify.c:
switch (r) {
case FP_VERIFY_NO_MATCH:
printf("A digital não bate com a principal\nFIM-ERRO\n");
return 0;
case FP_VERIFY_MATCH:
printf("A sua digital foi gravada \nFIM-OK\n");
return 0;
case FP_VERIFY_RETRY:
printf("Nao foi possível escanear, tente novamente.\nFIM-NOVAMENTE\n");
break;
case FP_VERIFY_RETRY_TOO_SHORT:
printf("Swipe was too short, please try again.\nFIM-NOVAMENTE\n");
break;
case FP_VERIFY_RETRY_CENTER_FINGER:
printf("Por favor, centralize a sua digital no sensor e tente novamente.\nFIM-NOVAMENTE\n");
break;
case FP_VERIFY_RETRY_REMOVE_FINGER:
printf("Por favor, remova seu dedo do sensor e tente novamente.\nFIM-NOVAMENTE\n");
break;
}
} while (1);
e na sequência:
r = fp_init();
if (s < 0) {
fprintf(stderr, "O FingerFX falhou ao iniciar o driver do leitor\nFIM-DISP\n");
exit(1);
}
discovered_devs = fp_discover_devs();
if (!discovered_devs) {
fprintf(stderr, "O FingerFx não consegue encontrar o leitor \nFIM-DISP\n");
goto out;
}
ddev = discover_device(discovered_devs);
if (!ddev) {
fprintf(stderr, "O FingerFX não encontrou nenhum leitor instalado!.\nFIM-DISP\n");
goto out;
}
dev = fp_dev_open(ddev);
fp_dscv_devs_free(discovered_devs);
if (!dev) {
fprintf(stderr, "O FingerFx não consegue abrir o dispositivo (leitor óptico).\nERRO-NCONECTADO\n");
goto out;
}
printf("O FingerFx esta comparando a digital do dispositivo contra a digital "
"armazenada...\n");
s = fp_print_data_load(dev, RIGHT_INDEX, &data);
if (s != 0) {
fprintf(stderr, "O FingerFx falhou ao carregar a digital armazenada com o erro %d\n", r);
fprintf(stderr, "Você realmente digitalizou seu dedo antes de executar esta "
"etapa?\n");
goto out_close;
}
printf("A digital armazenada foi carregada e esta pronta para ser testada!\n");
do {
char buffer[20];
verify(dev, data);
/* AQUI EU REMOVI COM UM COMENTÁRIO!!!
printf("Verify again? [Y/n]? ");
fgets(buffer, sizeof(buffer), stdin);
if (buffer[0] != '\n' && buffer[0] != 'y' && buffer[0] != 'Y')
*/
break;
} while (1);
Depois de todas estas alterações eu executo o sistema e ele me retorna assim:
# ./enroll.c | grep FIM
Se tudo OK com a leitura, o programa só retorna:
FIM-OK
Se der algo errado como por exemplo um erro de dispositivo ele retorna.
FIM-ERRO
ou FIM-(e o erro referente)
Você pode incluir o código dos arquivos diretamente no fonte do seu programa.
Assim você pode capturar até erros específicos utilizando estes códigos de erro personalizados!
Comparação da digital:
A
Libfprint ainda não compara várias digitais, no caso - não tenho certeza, estou deduzindo - o leitor compara via hardware uma digital salva com o comando enroll e retorna o resultado, pois eu já li toda a documentação da libfprint e em momento algum é mencionado alguma herança ou objeto do cabeçalho que exerça tal função.
O arquivo binário contendo os dados da digital para comparação é salvo dentro da pasta /.fprint/prints/0002/00000000 do diretório do usuário que executou o comando. O arquivo com a imagem da digital é salvo na pasta home do usuário. Se você quiser alterar o nome do arquivo que é gerado, pode mudar no fonte do enroll e verify.
Nós da
Linuxfx estamos desenvolvendo um aplicativo livre que pode comparar via software os binários salvos pela libfprint e retornar um boolean. Mas por enquanto ainda está em testes.
Eu gravei um vídeo demonstrando nosso sistema para automação de portaria utilizando a biometria digital, o
FingerFX:
Espero que este artigo ajude os programadores que estão tendo dor de cabeça para entender/utilizar a biblioteca libfprint no Linux.
Caso aja algum erro no documento ou algo que eu esqueci de mencionar, me mande um e-mail que eu corrijo.
Rafael Wagner - Programador e mantedor do Linuxfx.