First commit
This commit is contained in:
commit
da07035f17
|
@ -0,0 +1,4 @@
|
|||
build/
|
||||
old/
|
||||
*.o
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
#include "CNS.h"
|
||||
|
||||
int read_CNS_hex_8(std::istringstream& stream) {
|
||||
char what[2];
|
||||
stream.read(what, 2);
|
||||
|
||||
std::string hexstring(what, 2);
|
||||
int actual_number = std::stoi(hexstring, nullptr, 16);
|
||||
|
||||
return actual_number;
|
||||
|
||||
}
|
||||
|
||||
CNS dati_CNS_to_cpp() {
|
||||
CNS data;
|
||||
|
||||
char* buffer;
|
||||
size_t len;
|
||||
int rv = read_dati_personali_c(&buffer, &len);
|
||||
std::clog << "[D] " << rv << std::endl;
|
||||
if (rv != 0) throw ExPCSC("can not read_dati_personali_c()");
|
||||
|
||||
//std::clog << "[D] " << len << '\t' << buffer << std::endl;
|
||||
|
||||
std::vector<std::string> field;
|
||||
|
||||
for (int i = 12; i < len; ) {
|
||||
if (buffer[i] == '\0') break;
|
||||
|
||||
std::string hexstring(&buffer[i], 2);
|
||||
int len = std::stoi(hexstring, nullptr, 16);
|
||||
i += 2;
|
||||
std::string fieldData(&buffer[i], len);
|
||||
i += len;
|
||||
|
||||
field.push_back(fieldData);
|
||||
}
|
||||
free(buffer);
|
||||
|
||||
for (int i = 0; i < field.size(); ++i) {
|
||||
std::clog << i << '\t' << field[i] << std::endl;
|
||||
switch (i) {
|
||||
case 0: data.dataRilascio = QDate::fromString(QString(field[i].data()), "ddMMyyyy"); break;
|
||||
case 1: data.dataScadenza = QDate::fromString(QString(field[i].data()), "ddMMyyyy"); break;
|
||||
case 2: data.cognome = QString(field[i].data()); break;
|
||||
case 3: data.nome = QString(field[i].data()); break;
|
||||
case 4: data.dataNascita = QDate::fromString(QString(field[i].data()), "ddMMyyyy"); break;
|
||||
case 5: data.sesso = field[i] == "F" ? Sex::F : Sex::M; break; /* TODO what about other genders? */
|
||||
case 7: data.codiceFiscale = QString(field[i].data()); break;
|
||||
case 9: data.comuneNascita = QString(field[i].data()); break;
|
||||
case 12: data.comuneResidenza = QString(field[i].data()); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return data;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef CONVERT_H
|
||||
#define CONVERT_H
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include <QDate>
|
||||
#include <QString>
|
||||
|
||||
#include "Ex.h"
|
||||
|
||||
#include "read_dati_personali.h"
|
||||
|
||||
namespace Sex {
|
||||
enum Sex {
|
||||
F,
|
||||
M
|
||||
};
|
||||
}
|
||||
|
||||
struct CNS {
|
||||
QString nome;
|
||||
QString cognome;
|
||||
QDate dataNascita;
|
||||
QString comuneNascita;
|
||||
QString comuneResidenza;
|
||||
QString codiceFiscale;
|
||||
Sex::Sex sesso;
|
||||
QDate dataRilascio;
|
||||
QDate dataScadenza;
|
||||
};
|
||||
|
||||
CNS dati_CNS_to_cpp(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#include "Ex.h"
|
||||
|
||||
Ex::Ex() {
|
||||
this->msg = std::string("generic exception");
|
||||
}
|
||||
|
||||
Ex::Ex(const char* msg) {
|
||||
this->msg = std::string(msg);
|
||||
}
|
||||
|
||||
/*
|
||||
Ex::Ex(const char* msg, int n) {
|
||||
this->msg = std::string(msg) + ": " + strerror(n);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Ex& e) {
|
||||
os << e.msg;
|
||||
return os;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef EXCEPTION_H
|
||||
#define EXCEPTION_H
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
/* `explicit` specifier forces constructors to not being implicitly called */
|
||||
class Ex {
|
||||
private:
|
||||
std::string msg;
|
||||
public:
|
||||
explicit Ex();
|
||||
explicit Ex(const char* msg);
|
||||
explicit Ex(const char* msg, int errn);
|
||||
friend std::ostream& operator<<(std::ostream&, const Ex&);
|
||||
};
|
||||
|
||||
/* Parent::Parent makes classes inherit their constructors from parents (C++11) */
|
||||
class ExPCSC : public Ex { using Ex::Ex; };
|
||||
|
||||
#endif
|
|
@ -0,0 +1,43 @@
|
|||
#----------------------------------------------------
|
||||
# CNS-Parser for Italian Carta Nazionale dei Servizi
|
||||
# adapted by giomba
|
||||
#----------------------------------------------------
|
||||
|
||||
QT += core
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = cnsparser
|
||||
TEMPLATE = app
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
# You can also make your code fail to compile if you use deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
SOURCES += \
|
||||
main.cpp \
|
||||
CNS.cpp \
|
||||
Ex.cpp \
|
||||
read_dati_personali.cpp
|
||||
|
||||
HEADERS += \
|
||||
CNS.h \
|
||||
Ex.h \
|
||||
read_dati_personali.h
|
||||
|
||||
QMAKE_CXXFLAGS += $(shell pkg-config --cflags libpcsclite)
|
||||
QMAKE_LFLAGS += $(shell pkg-config --libs libpcsclite)
|
||||
|
||||
# Default rules for deployment.
|
||||
qnx: target.path = /tmp/$${TARGET}/bin
|
||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
!isEmpty(target.path): INSTALLS += target
|
|
@ -0,0 +1,24 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "CNS.h"
|
||||
|
||||
int main(void) {
|
||||
CNS cns;
|
||||
int r = 0;
|
||||
|
||||
try {
|
||||
cns = dati_CNS_to_cpp();
|
||||
|
||||
std::clog << "Data Rilascio:\t";
|
||||
std::clog << cns.dataRilascio.year() << '-' << cns.dataRilascio.month() << '-' << cns.dataRilascio.day() << std::endl;
|
||||
std::clog << "Data Scadenza:\t";
|
||||
std::clog << cns.dataScadenza.year() << '-' << cns.dataScadenza.month() << '-' << cns.dataScadenza.day() << std::endl;
|
||||
|
||||
r = 0;
|
||||
} catch (Ex e) {
|
||||
std::cerr << "[E] exception: " << e << std::endl;
|
||||
r = 1;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
#include "read_dati_personali.h"
|
||||
|
||||
#define CHECK(f, rv) \
|
||||
if (SCARD_S_SUCCESS != rv) \
|
||||
{ \
|
||||
printf("[E] " f ": %s\n", pcsc_stringify_error(rv)); \
|
||||
return -1; \
|
||||
}
|
||||
|
||||
int read_dati_personali_c(char** output_buffer, size_t* len) {
|
||||
LONG rv;
|
||||
|
||||
SCARDCONTEXT hContext;
|
||||
LPTSTR mszReaders;
|
||||
SCARDHANDLE hCard;
|
||||
DWORD dwReaders, dwActiveProtocol, dwRecvLength;
|
||||
|
||||
SCARD_IO_REQUEST pioSendPci;
|
||||
BYTE pbRecvBuffer[1024];
|
||||
BYTE cmd[4][7];
|
||||
memcpy(cmd[0], "\x00\xA4\x00\x00\x02\03f\x00", 7);
|
||||
memcpy(cmd[1], "\x00\xA4\x00\x00\x02\x11\x00", 7);
|
||||
memcpy(cmd[2], "\x00\xA4\x00\x00\x02\x11\x02", 7);
|
||||
memcpy(cmd[3], "\x00\xB0\x00\x00\x00\x00", 6);
|
||||
|
||||
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
|
||||
CHECK("SCardEstablishContext", rv)
|
||||
|
||||
#ifdef SCARD_AUTOALLOCATE
|
||||
dwReaders = SCARD_AUTOALLOCATE;
|
||||
|
||||
rv = SCardListReaders(hContext, NULL, (LPTSTR)&mszReaders, &dwReaders);
|
||||
CHECK("SCardListReaders", rv)
|
||||
#else
|
||||
rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
|
||||
CHECK("SCardListReaders", rv)
|
||||
|
||||
mszReaders = calloc(dwReaders, sizeof(char));
|
||||
rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
|
||||
CHECK("SCardListReaders", rv)
|
||||
#endif
|
||||
/* printf("reader name: %s\n", mszReaders); */
|
||||
|
||||
rv = SCardConnect(hContext, mszReaders, SCARD_SHARE_SHARED,
|
||||
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
|
||||
CHECK("SCardConnect", rv)
|
||||
|
||||
switch(dwActiveProtocol) {
|
||||
case SCARD_PROTOCOL_T0:
|
||||
pioSendPci = *SCARD_PCI_T0;
|
||||
break;
|
||||
case SCARD_PROTOCOL_T1:
|
||||
pioSendPci = *SCARD_PCI_T1;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
dwRecvLength = sizeof(pbRecvBuffer);
|
||||
/* TODO: hardcoded packet length*/
|
||||
rv = SCardTransmit(hCard, &pioSendPci, cmd[j], ((j == 3) ? 6 : 7), NULL, pbRecvBuffer, &dwRecvLength);
|
||||
CHECK("SCardTransmit", rv)
|
||||
/*
|
||||
printf("response %d\tlen %d\t", j, dwRecvLength);
|
||||
printf("%.*s", dwRecvLength, pbRecvBuffer);
|
||||
printf("\n");
|
||||
*/
|
||||
}
|
||||
|
||||
/* send back last buffer read */
|
||||
*output_buffer = (char*)malloc(dwRecvLength);
|
||||
memcpy(*output_buffer, pbRecvBuffer, dwRecvLength);
|
||||
*len = dwRecvLength;
|
||||
|
||||
rv = SCardDisconnect(hCard, SCARD_LEAVE_CARD);
|
||||
CHECK("SCardDisconnect", rv)
|
||||
|
||||
#ifdef SCARD_AUTOALLOCATE
|
||||
rv = SCardFreeMemory(hContext, mszReaders);
|
||||
CHECK("SCardFreeMemory", rv)
|
||||
#else
|
||||
free(mszReaders);
|
||||
#endif
|
||||
|
||||
rv = SCardReleaseContext(hContext);
|
||||
|
||||
CHECK("SCardReleaseContext", rv)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef READ_DATI_PERSONALI_H
|
||||
#define READ_DATI_PERSONALI_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winscard.h>
|
||||
|
||||
int read_dati_personali_c(char** output_buffer, size_t* len);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue