amagovpt / autenticacao.gov

Middleware Oficial de Identificação Eletrónica em Portugal - Cartão de Cidadão, da Chave Móvel Digital e Sistema de Certificação de atributos profissionais
https://www.autenticacao.gov.pt
European Union Public License 1.2
173 stars 33 forks source link

Python Wrapper problema a compilar #52

Open AndreMPCosta opened 3 years ago

AndreMPCosta commented 3 years ago

As instruções estão direcionadas para ambiente UNIX, mas como costumo trabalhar em Windows tentei compilar para este OS.

Ao seguir as instruções deparo-me com os seguintes problemas:

PS D:\autenticacao.gov\pteid-mw-pt\_src\eidmw\eidlibPython_Wrapper> make
C:/Program Files (x86)/GnuWin32/bin/make -f Makefile.Release
make[1]: Entrando no diretório `D:/autenticacao.gov/pteid-mw-pt/_src/eidmw/eidlibPython_Wrapper'
g++ -c -fno-keep-inline-dllexport -fno-strict-aliasing -O2 -std=gnu++11 -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DPTEID_35 -DEIDMW_PREFIX=/usr/local -DEIDMW_CMN_EXPORT -DEIDMW_EIDLIB_EXPORTS -I. -IC:\OpenSSL-Win32\include -IC:\Python39\include -I. -I..\applayer -I..\dialogs -I..\common -I..\cardlayer -I..\eidlib -ID:\Qt\Qt5.12.10\5.12.10\mingw73_32\mkspecs\win32-g++  -o release\eidlibCard.o ..\eidlib\eidlibCard.cpp
In file included from ..\applayer/ScapSSLConnection.h:12:0,
                 from ..\eidlib\eidlibCard.cpp:42:
..\applayer/SSLConnection.h:44:17: error: function 'eIDMW::SSLConnection::SSLConnection()' definition is marked dllimport
   EIDMW_APL_API SSLConnection()
                 ^~~~~~~~~~~~~
..\applayer/SSLConnection.h:51:17: error: function 'eIDMW::SSLConnection::~SSLConnection()' definition is marked dllimport
   EIDMW_APL_API ~SSLConnection()
                 ^
In file included from ..\eidlib\eidlibCard.cpp:42:0:
..\applayer/ScapSSLConnection.h:20:17: error: function 'eIDMW::ScapSSLConnection::ScapSSLConnection()' definition is marked dllimport
   EIDMW_APL_API ScapSSLConnection() { };
                 ^~~~~~~~~~~~~~~~~
..\applayer/ScapSSLConnection.h:22:17: error: function 'eIDMW::ScapSSLConnection::~ScapSSLConnection()' definition is marked dllimport
   EIDMW_APL_API ~ScapSSLConnection() { /* CloseConnection(); */ }
                 ^
In file included from ..\eidlib\eidlibCard.cpp:43:0:
..\applayer/PDFSignature.h:87:24: error: function 'char* eIDMW::PDFSignature::getCitizenCertificateName()' definition is marked dllimport
   EIDMW_APL_API char * getCitizenCertificateName() { return m_citizen_fullname; };
                        ^~~~~~~~~~~~~~~~~~~~~~~~~
..\applayer/PDFSignature.h:89:24: error: function 'char* eIDMW::PDFSignature::getCitizenCertificateID()' definition is marked dllimport
   EIDMW_APL_API char * getCitizenCertificateID() { return m_civil_number; } ;
                        ^~~~~~~~~~~~~~~~~~~~~~~
In file included from ..\eidlib\eidlibCard.cpp:44:0:
..\applayer/SecurityContext.h:18:18: error: function 'eIDMW::SecurityContext::SecurityContext(eIDMW::APL_Card*)' definition is marked dllimport
    EIDMW_APL_API SecurityContext(APL_Card * card)

O meu .pro file tem estes includes e libs:

LIBS += -lpython3.9

INCLUDEPATH += C:/OpenSSL-Win32/include INCLUDEPATH += C:/Python39/include

Alguma ideia de como compilar isto para poder usar o wrapper de Python?

AndreMPCosta commented 3 years ago

Entretanto se alguém quiser usar o SDK em Python, descobri uma forma. Instalar o pythonnet (branch master), e usar o dll de dotnet.

Exemplo minimalista de funcionamento:

import sys
import clr

assembly_path = r"C:\Program Files\Portugal Identity Card\sdk\dotnet"
sys.path.append(assembly_path)

clr.AddReference("pteidlib_dotnet")

import pt.portugal.eid as pt
from pt import *

pt.PTEID_ReaderSet.initSDK()
readerSet = pt.PTEID_ReaderSet.instance()

context = None
card = None
for x in range(readerSet.readerCount()):
    context = readerSet.getReaderByNum(x)
    if context.isCardPresent():
        card = context.getEIDCard()

eid = card.getID()
name = eid.getGivenName()
nr_cc = eid.getDocumentNumber()
print(eid, name, nr_cc)

pt.PTEID_ReaderSet.releaseSDK()

Eu não estou familiarizado com dotnet, se alguém me puder ajudar na parte dos callbacks, por exemplo detetar um cartão:

import sys
import clr
from types import *
import System
from System import Int32

Action = getattr(System, "Action`3")

def card_events_callback(ret, state, data):
    card_state = state & 0x0000FFFF
    event_counter = state >> 16
    print(f"DEBUG: Card Event: cardState: {card_state} Event Counter: {event_counter}")

    if card_state & 0x0100 != 0:
        print("Card inserted")

    else:
        print("Card removed")

for x in range(readerSet.readerCount()):
    context = readerSet.getReaderByNum(x)
    if context.isCardPresent():
        card = context.getEIDCard()

callback = context.SetEventCallback(Action[Int32](card_events_callback), Action[Int32](None))

Acontece isto: callback = context.SetEventCallback(Action[Int32](card_events_callback), Action[Int32](None)) TypeError: argument must be callable

ACamposPT commented 3 years ago

Viva,

Efectivamente as instruções para usar o Python Wrapper estão feitas para Unix, e na verdade nós a equipa de desenvolvimento até ao momento só testamos em Linux.

Pedimos para começar por testar em ambiente Ubuntu por exemplo. Deixe aqui o seu feedback sobre os testes. Depois podemos ajudar / dar umas dicas para colocar a funcionar em Windows, se se justificar. Podemos saber qual o âmbito que pretende usar o Wrapper?

AndreMPCosta commented 3 years ago

Olá @ACamposPT Eu neste momento só tenho acesso a OSX e a Windows, Ubuntu só mesmo em servidor e não me dará grande jeito, dado que o meu use case será em máquinas Windows.

Usar o .dll de dotnet para já é suficiente, queria usar o callback para detetar a inserção do cartão, mas acho que se tal não for possível, usarei o https://github.com/LudovicRousseau/pyscard para conseguir essa parte.

O âmbito é trivial, é só ler os dados do cartão mesmo, sem operações de escrita nem nada do género.