hi All,
Problem: I try to read the passport using RFID, i am facing problem..
Scenario 1: Actually we have many types of passports like TYPE A, Type B...
1. I have two applications like i) for to read the passport using desktop device ii) to read the passport using the WINCE mobile device reader
2. while reading with the desktop devices everything is fine no issues..
While reading with the Mobile devices i am facing the problem..
Problem: I have two kinds of passports which i mentioned above, while reading type A passports i don't have any problem, but while reading the Type B pass parts i means (the passport have BAC(Basic Authentication Context)) in this type B passports while reading i got the MRZ details correct, but while reading the Photo its corrupting...
i am giving the source code pls check give where is the problem...
the problem which i found while reading some bytes corrupting..some values are missing while each read...
BOOL MrtdSelectFile(MRTD_CTX_ST * ctx, BYTE dg)
{
BYTE buffer[258];
WORD recv_len;
WORD sw;
if (ctx == NULL)
return FALSE;
if (ctx->Bac.enabled)
{
printf("\r\n Entered MrtdSelectFile 1 ");
return MrtdBacSelectDG(ctx, dg);
}
buffer[0] = 0x00;
buffer[1] = 0xA4;
buffer[2] = 0x02;
buffer[3] = 0x0C;
buffer[4] = 0x02;
if (dg == 0)
{
buffer[5] = 0x01;
buffer[6] = 0x1E;
} else
if (dg <= 16)
{
buffer[5] = 0x01;
buffer[6] = dg;
} else
{
MrtdVerbose("MrtdSelectDG : Not implemented DG%d", dg);
MrtdSetLastError(ctx, MRTD_E_INVALID_PARAM);
return FALSE;
}
recv_len = sizeof(buffer);
if (!MrtdIccTransmit(ctx, buffer, 7, buffer, &recv_len))
{
MrtdVerbose("MrtdSelectDG(%d) : IccTransmit failed", dg);
return FALSE;
}
sw = MrtdIccStatusWord(ctx, buffer, recv_len);
if (sw != 0x9000)
{
if (sw == 0x6982)
{
MrtdVerbose("MrtdSelectDG(%d) : File needs BAC", dg);
if (!ctx->Bac.enabled)
{
if (!MrtdBacInitialize(ctx))
{
printf("\r\n Entered MrtdSelectFile 1 BAC failed ");
MrtdVerbose("MrtdSelectDG(%d) : BAC failed", dg);
return FALSE;
}
}
return MrtdBacSelectDG(ctx, dg);
}
if (sw == 0x6A82)
{
MrtdVerbose("MrtdSelectDG(%d) : File not found", dg);
MrtdSetLastError(ctx, MRTD_E_NO_FILE);
} else
{
MrtdVerbose("MrtdSelectDG(%d) : Bad status word %04X", dg, sw);
MrtdSetLastError(ctx, MRTD_E_CARD_ANSWER);
}
return FALSE;
}
return TRUE;
}
BOOL MrtdReadFileEx(MRTD_CTX_ST * ctx, BYTE * data, WORD offset, WORD * length)
{
BYTE buffer[258];
WORD recv_len;
WORD sw;
if (ctx == NULL)
return FALSE;
if (data == NULL)
return FALSE;
if (length == NULL)
return FALSE;
buffer[0] = 0x00;
buffer[1] = 0xB0;
buffer[2] = (BYTE) (offset / 0x0100);
buffer[3] = (BYTE) (offset % 0x0100);
if (*length <= 255)
{
buffer[4] = (BYTE) * length;
} else
if (*length == 256)
{
buffer[4] = 0x00;
} else
{
printf("\r\n Entered MrtdReadFileEx false 1");
return FALSE;
}
recv_len = sizeof(buffer);
if (!MrtdIccTransmit(ctx, buffer, 5, buffer, &recv_len))
{
MrtdVerbose("MrtdReadFileEx : IccTransmit failed");
printf("\r\n Entered MrtdReadFileEx false 2");
return FALSE;
}
sw = MrtdIccStatusWord(ctx, buffer, recv_len);
if (sw != 0x9000)
{
MrtdVerbose("MrtdReadFileEx(%d,%d) failed, SW=%04X", offset, *length);
printf("\r\n Entered MrtdReadFileEx(%d,%d) failed, SW=%04X", offset, *length);
printf("\r\n Entered MrtdReadFileEx false 3");
}
else
{
printf("\r\n Entered MrtdReadFileEx(%d,%d) pass, SW=%04X", offset, *length);
}
if (recv_len - 2 > *length)
{
MrtdVerbose("MrtdReadFileEx(%d,%d) failed, response too long (%d > %d)", offset, *length, recv_len - 2, *length);
MrtdSetLastError(ctx, MRTD_E_CARD_ANSWER);
printf("\r\n Entered MrtdReadFileEx false 4");
return FALSE;
}
if(recv_len>2)
*length = recv_len - 2;
if (data != NULL)
memcpy(data, buffer, *length);
return TRUE;
}
BOOL MrtdReadFileSize(MRTD_CTX_ST * ctx, WORD * filesize)
{
BYTE header[4];
WORD size;
if (filesize == NULL)
return FALSE;
size = 4;
if (ctx->Bac.enabled)
{
if (!MrtdBacReadFileEx(ctx, header, 0, &size))
return FALSE;
} else
{
if (!MrtdReadFileEx(ctx, header, 0, &size))
return FALSE;
}
if (size != 4)
return FALSE;
*filesize = TLVTotalSize(header);
return TRUE;
}
BOOL MrtdReadFile(MRTD_CTX_ST * ctx, BYTE * filedata, WORD filesize)
{
WORD buffer_size;
WORD remaining = filesize;
WORD offset = 0;
WORD size;
MrtdProgress(0, filesize);
if (ctx->Bac.enabled)
buffer_size = MAX_READ_SIZE_BAC;
else
buffer_size = MAX_READ_SIZE;
while (remaining)
{
if (remaining > buffer_size)
size = buffer_size;
else
size = remaining;
if (ctx->Bac.enabled)
{
if (!MrtdBacReadFileEx(ctx, &filedata[offset], offset, &size))
{
MrtdVerbose("MrtdBacReadFile : error at offset %d/%d\n", offset, filesize);
printf("\r\n Entered MrtdReadFile false 1");
return FALSE;
}
} else
{
if (!MrtdReadFileEx(ctx, &filedata[offset], offset, &size))
{
MrtdVerbose("MrtdReadFile : error at offset %d/%d\n", offset, filesize);
printf("\r\n Entered MrtdReadFile false 2");
return FALSE;
}
}
if (size > remaining)
{
MrtdVerbose("MrtdReadFile : invalid return size %d>%d at %d/%d\n", size, remaining, offset, filesize);
printf("\r\n Entered MrtdReadFile false 3");
return FALSE;
}
remaining -= size;
offset += size;
if (!MrtdProgress(offset, filesize))
{
MrtdSetLastError(ctx, MRTD_CANCELLED);
printf("\r\n Entered MrtdReadFile false 4");
return FALSE;
}
}
return TRUE;
}
BOOL MrtdSelectApplet(MRTD_CTX_ST * ctx)
{
BYTE pbSendBuffer[] = { 0x00, 0xA4, 0x04, 0x0C, 0x07, 0xA0, 0x00, 0x00, 0x02, 0x47, 0x10, 0x01 };
BYTE pbRecvBuffer[258];
WORD wRecvLength = sizeof(pbRecvBuffer);
WORD sw;
if (!MrtdIccTransmit (ctx, pbSendBuffer, sizeof(pbSendBuffer), pbRecvBuffer, &wRecvLength))
{
MrtdVerbose("MrtdSelectApplet : IccTransmit failed");
return FALSE;
}
sw = MrtdIccStatusWord(ctx, pbRecvBuffer, wRecvLength);
if (sw != 0x9000)
{
if (sw == 0x6A82)
{
MrtdVerbose("MrtdSelectApplet : LDS not found");
MrtdSetLastError(ctx, MRTD_E_NO_LDS);
} else
{
MrtdVerbose("MrtdSelectApplet : Bad status word %04X", sw);
MrtdSetLastError(ctx, MRTD_E_CARD_ANSWER);
}
return FALSE;
}
return TRUE;
}
BOOL MrtdReadPassportEx(MRTD_CTX_ST * ctx, DWORD want_dgs, const char *mrz_string)
{
DWORD total = 0;
DWORD have_dgs;
BYTE dg;
printf("\r\n Entered MrtdReadPassportEx ");
MrtdStatus("In MrtdReadPassportEx__1,mrz(%s)",mrz_string);
if (ctx == NULL)
{
printf("\r\n Entered MrtdReadPassportEx 2");
MrtdStatus("In MrtdReadPassportEx__2");
return FALSE;
}
if ((mrz_string != NULL) && strlen(mrz_string))
{
if (!MrtdAssignMrz(ctx, mrz_string))
{
printf("\r\n Entered MrtdReadPassportEx 3");
MrtdStatus("In MrtdReadPassportEx__2");
return FALSE;
}
}
MrtdStatus("Selecting ICAO/MRTD LDS applet");
if (!MrtdSelectApplet(ctx))
{
printf("\r\n Entered MrtdSelectApplet");
return FALSE;
}
for (dg = 0; dg <= 16; dg++) {
BYTE * filedata;
WORD filesize = 0;
if (dg == 0)
{
MrtdStatus("Reading EF.COM");
} else
{
if (!(have_dgs & (1 << dg))) continue;
if (!(want_dgs & (1 << dg))) continue;
if (ctx->Bac.enabled)
MrtdStatus("Reading DG%d (secure mode)...", dg);
else
MrtdStatus("Reading DG%d...", dg);
}
if (!MrtdSelectFile(ctx, dg))
{
MrtdVerbose("Error selecting DG %d", dg);
{
printf("\r\n Entered MrtdSelectFile");
return FALSE;
}
}
MrtdVerbose("Querying file size", dg);
if (!MrtdReadFileSize(ctx, &filesize))
{
MrtdVerbose("Failed to read header of DG%d", dg);
{
printf("\r\n Entered MrtdReadFileSize");
return FALSE;
}
}
filedata = malloc(filesize);
if (filedata == NULL)
{
MrtdVerbose("Out of memory");
MrtdSetLastError(ctx, MRTD_E_OUT_OF_MEMORY);
{
printf("\r\n Entered filedata");
return FALSE;
}
}
MrtdVerbose("Receiving file content", dg);
if (!MrtdReadFile(ctx, filedata, filesize))
{
free(filedata);
MrtdVerbose("Failed to read content of DG%d", dg);
{
printf("\r\n Entered MrtdReadFile");
return FALSE;
}
}
total += filesize;
ctx->DgSize[dg] = filesize;
ctx->DgData[dg] = filedata;
if (dg == 0)
{
MrtdVerbose("Parsing EF.COM");
if (!MrtdParseEFCOM(filedata, filesize, &have_dgs))
{
MrtdVerbose("Content of EF.COM is invalid");
MrtdSetLastError(ctx, MRTD_E_BAD_CONTENT);
printf("\r\n Entered MrtdParseEFCOM");
return FALSE;
}
}
}
MrtdStatus("Done");
return TRUE;
}