📄 tlp3cb.c
字号:
// is Le + 2 status bytes
//
bytesToSend = *requestLength;
bytesToRead = SmartcardExtension->T0.Le + 2;
SmartcardDebug(
DEBUG_TRACE,
(TEXT("%s!TLP3TransmitT0: Send %d and Received %d \n"),
szDriverName,bytesToSend,bytesToRead)
);
SmartcardExtension->SmartcardRequest.BufferLength = bytesToSend;
SmartcardExtension->SmartcardReply.BufferLength=bytesToRead;
status=StarIccCommand(0xe3,1,SmartcardExtension);
RETAILMSG(1,(TEXT("\r\n@@@@@@TLP3TransmitT0 status = %d\r\n"),status));
RETAILMSG(1,(TEXT("\r\n@@@@@@TLP3TransmitT0 replybuffer = %s\r\n"),SmartcardExtension->SmartcardReply.Buffer));
if(status!=STATUS_SUCCESS)
{
return status;
}
//lbq change
/*
//
// Send the first 5 bytes to the card
//
*requestLength = 5;
do {
UCHAR procByte;
//
// According to ISO 7816 a procedure byte of
// 60 should be treated as a request for a one time wait.
// In this case we do not write anything to the card
//
if (restartWorkWaitingTime == FALSE) {
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!TLP3TransmitT0: -> Sending %s (%ld bytes)\n"),
szDriverName,
(currentByte == 0 ? TEXT("header") : TEXT("data")),
*requestLength)
);
//
// Write to the card
//
*serialIoControlCode = SMARTCARD_WRITE;
SmartcardExtension->SmartcardRequest.Buffer = &requestBuffer[currentByte];
status = TLP3SerialIo(
SmartcardExtension
);
if (status != STATUS_SUCCESS)
leave;
//
// The TLP3 echos all sent bytes. We read the echo
// back into our send buffer
//
*serialIoControlCode = SMARTCARD_READ;
*replyLength = *requestLength;
SmartcardExtension->SmartcardReply.Buffer = &requestBuffer[currentByte];
status = TLP3SerialIo(
SmartcardExtension
);
if (status != STATUS_SUCCESS)
leave;
currentByte += *requestLength;
bytesToSend -= *requestLength;
}
// Read the 'Procedure byte'.
SmartcardExtension->SmartcardReply.Buffer = &procByte;
*serialIoControlCode = SMARTCARD_READ;
*replyLength = 1;
status = TLP3SerialIo(
SmartcardExtension
);
if (status != STATUS_SUCCESS)
leave;
restartWorkWaitingTime = FALSE;
//
// Check the procedure byte.
// Please take a look at ISO 7816 Part 3 Section 8.2.2
//
if (procByte == requestBuffer[1] ||
procByte == requestBuffer[1] + 1) {
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!TLP3TransmitT0: <- ACK (send all)\n"),
szDriverName)
);
// All remaining data bytes can be sent at once
*requestLength = bytesToSend;
} else if (procByte == (UCHAR) ~requestBuffer[1] ||
procByte == (UCHAR) ~(requestBuffer[1] + 1)) {
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!TLP3TransmitT0: <- ACK (send single)\n"),
szDriverName)
);
// We can send only one byte
*requestLength = 1;
} else if (procByte == 0x60 ||
SmartcardExtension->CardCapabilities.InversConvention &&
procByte == 0xf9) {
//
// We have to reset the wait time and try again to read
//
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!TLP3TransmitT0: <- NULL (%ldms)\n"),
szDriverName,
SmartcardExtension->CardCapabilities.T0.WT / 1000)
);
dwMilliSecond=(SmartcardExtension->CardCapabilities.T0.WT+MICROSECONDS_PER_MILLISECOND/2)/MICROSECONDS_PER_MILLISECOND;
if (dwMilliSecond) {
Sleep(dwMilliSecond);
}
//
// Set flag that we only should read the proc byte
// without writing data to the card
//
restartWorkWaitingTime = TRUE;
} else {
//
// The card returned a status byte.
// Status bytes are always two bytes long.
// Store this byte first and then read the next
//
replyBuffer[0] = procByte;
*serialIoControlCode = SMARTCARD_READ;
*replyLength = 1;
bytesToSend = 0;
bytesToRead = 0;
//
// Read in the second status byte
//
SmartcardExtension->SmartcardReply.Buffer =
&replyBuffer[1];
status = TLP3SerialIo(
SmartcardExtension
);
SmartcardExtension->SmartcardReply.BufferLength = 2;
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!TLP3TransmitT0: <- SW1=%02x SW2=%02x\n"),
szDriverName,
replyBuffer[0],
replyBuffer[1])
);
}
} while(bytesToSend || restartWorkWaitingTime);
if (status != STATUS_SUCCESS)
leave;
if (bytesToRead != 0) {
*serialIoControlCode = SMARTCARD_READ;
*replyLength = bytesToRead;
SmartcardExtension->SmartcardReply.Buffer =
replyBuffer;
status = TLP3SerialIo(
SmartcardExtension
);
#if DBG || DEBUG
if (status == STATUS_SUCCESS) {
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!TLP3TransmitT0: <- Data %ld bytes, SW1=%02x SW2=%02x\n"),
szDriverName,
bytesToRead,
replyBuffer[bytesToRead - 2],
replyBuffer[bytesToRead - 1])
);
}
#endif
}
}
finally {
// Restore pointers to their original location
SmartcardExtension->SmartcardRequest.Buffer =
requestBuffer;
SmartcardExtension->SmartcardReply.Buffer =
replyBuffer;
if (status == STATUS_TIMEOUT) {
// STATUS_TIMEOUT is not mapped to a Win32 error code
status = STATUS_IO_TIMEOUT;
}
if (status == STATUS_SUCCESS) {
status = SmartcardT0Reply(
SmartcardExtension
);
}
}
SmartcardDebug(
DEBUG_TRACE,
(TEXT("%s!TLP3TransmitT0: Exit(%lx)\n"),
szDriverName,
status)
);
*/
return status;
}
NTSTATUS
TLP3Transmit(
PSMARTCARD_EXTENSION SmartcardExtension
)
/*++
Routine Description:
This function is called by the smart card library whenever a transmission
is required.
Arguments:
SmartcardExtension - Pointer to smart card data struct.
Return Value:
NTSTATUS
--*/
{
NTSTATUS status;
SmartcardDebug(
DEBUG_TRACE,
(TEXT("%s!TLP3Transmit: Enter\n"),
szDriverName)
);
_try {
status=(PurgeComm(SmartcardExtension->ReaderExtension->hSerialPort,
PURGE_RXCLEAR | PURGE_TXCLEAR))?STATUS_SUCCESS:STATUS_UNSUCCESSFUL;
if (status != STATUS_SUCCESS)
leave;
do {
PUCHAR requestBuffer = SmartcardExtension->SmartcardRequest.Buffer;
PUCHAR replyBuffer = SmartcardExtension->SmartcardReply.Buffer;
PULONG requestLength = &SmartcardExtension->SmartcardRequest.BufferLength;
PULONG replyLength = &SmartcardExtension->SmartcardReply.BufferLength;
PULONG serialIoControlCode = &SmartcardExtension->ReaderExtension->SerialIoControlCode;
//
// Tell the lib function how many bytes I need for the prologue
//
// *requestLength = 0;
switch (SmartcardExtension->CardCapabilities.Protocol.Selected) {
case SCARD_PROTOCOL_RAW:
status = SmartcardRawRequest(SmartcardExtension);
break;
case SCARD_PROTOCOL_T0:
//
// T=0 requires a bit more work.
// So we do this in a seperate function.
//
status = TLP3TransmitT0(SmartcardExtension);
leave;
case SCARD_PROTOCOL_T1:
status = TLP3TransmitT0(SmartcardExtension);
leave;
// status = SmartcardT1Request(SmartcardExtension);
// break;
default:
status = TLP3TransmitT0(SmartcardExtension);
leave;
// status = STATUS_INVALID_DEVICE_REQUEST;
// leave;
}
if (status != STATUS_SUCCESS) {
leave;
}
//
// Write the command to the card
//
*replyLength = 0;
*serialIoControlCode = SMARTCARD_WRITE;
status = TLP3SerialIo(SmartcardExtension);
if (status != STATUS_SUCCESS) {
leave;
}
//
// The Bull reader always echos the bytes sent, so read that echo back
//
*serialIoControlCode = SMARTCARD_READ;
*replyLength = *requestLength;
status = TLP3SerialIo(SmartcardExtension);
if (status != STATUS_SUCCESS) {
leave;
}
switch (SmartcardExtension->CardCapabilities.Protocol.Selected) {
case SCARD_PROTOCOL_RAW:
status = SmartcardRawReply(SmartcardExtension);
break;
case SCARD_PROTOCOL_T1:
//
// Check if the card requested a waiting time extension
//
if (SmartcardExtension->T1.Wtx) {
DWORD dwMilliSecond=
(SmartcardExtension->T1.Wtx * SmartcardExtension->CardCapabilities.T1.BWT)
/MICROSECONDS_PER_MILLISECOND;
Sleep(dwMilliSecond);
}
//
// Read NAD, PCB and LEN fields
//
*replyLength = 3;
status = TLP3SerialIo(SmartcardExtension);
//
// Check for timeout first. If the card did not reply
// we need to send a resend request
//
if (status != STATUS_TIMEOUT) {
if (status != STATUS_SUCCESS) {
leave;
}
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -