> You cannot tell your driver to receive Le bytes, because only the card knows > how much it has to send. If you ask a different number, the card will say "I > cannot answer because you don't ask me the right question, and I have no > other way to tell it. Here is the correct length you have to ask me." > So it sends 61 or 6C. If you get that, you have to be happy with that and > return these bytes to the user even if he asked for more.
Yes, I agree. And that is the source of my problem - answer can be INS + Le + SW1SW2 or just 2 bytes. I do not know in advance. > > See how it's done at > http://hg.openjdk.java.net/jdk6/jdk6/jdk/file/2b1a7d4b9ac6/src/share/classes/sun/security/smartcardio/ChannelImpl.java > check doTransmit() at line 155. Note that the ScardTransmit method is called > more than once, in a loop. pcsclite and winscard do not manage the get > response command. so do the card drivers. > > A timeout is not acceptable because it would be too long and would not solve > your problem. FYI, I don't know any reader that have to rely on timeouts. When I say timeout I mean timeout between two consecutive characters, i.e. Work Waiting Time exceeded. That will tell my driver : "There is no more (valid)characters coming from the card. Get a hell out of your RX routine and give a chance to transport layer to analyze response that came so far". Is it too big ? WWT for ATR is 9600 ETUs and is protocol dependent and announced in TC2 of ATR. So - my question here is: Does the card have some internal timeout during Case 2 conversation or it gets stacked in the state machine, so that when it sends me 61 Luicc, and I wait 9600 ETUs, then go to transport layer and see that it send me 61 Luicc, then call drivers TX with [CLA INS P1 P2 Luicc] command that it will continue conversation normally (as it waits in the adequate state without timeout) ? BTW. If the card does not have internal timeout, what will happen if we start conversation from Terminal side, card responds with 61 XX but Terminal never responds back ? Card gets stacked, and we need to reset it before next conversation ? How will we know this ? > > If I understand correctly, in the case the card does not give you Le bytes, > you want to send the get response in the driver, just after the actual > command? No, this is not what I want. It will be the task of a transport layer. Here is what I want : 1) Transport layer form TPDU out of given APDU and gives a buffer and length to driver to send. 2) Driver blindly sends bytes in TX routine and exits back to transport layer. In the same time card starts sending response data. 3) Transport layer demands "read" from driver, gives it destination buffer and length of data expected. This has to be fast after TX demand, because card might overflow our RX FIFO inside USIM controller. Transport layer will later analyse received buffer, upon exit of driver's RX routine. 4) Driver enters RX routine and reads FIFO on every interrupt. Interrupts happens as rare as possible (because everything lives in an RT system), usually just before FIFO will overflow. Driver will manipulate interrupt masking for optimal performance. For this to be done, driver will expect known length of data to arrive. If it does not - driver will time out. This is because ***driver does not have internal mechanism of detecting END***. Only transport layer can determine if message is finished after 2 bytes. But driver does not exit after 2 bytes because - imagine the case when card will actually send Le bytes. If driver exits after 2 bytes to transport layer, for transport layer to determine that everything is OK and call back drivers RX for the rest of data, time is lost during this processing and when we come back to drivers RX FIFO might be already overflown, because card sends the data all this time. So, to be more precise : once entered drivers RX routine, I have fear to exit after 2 bytes and analyze them in transport layer. I can exit only in 2 cases : 1) I received all the chars I wanted 2) There is timeout > And what if the card DOES NOT have Le bytes at all? will you wait? > it will never come :-) then I'll time out. As soon as time between two consecutive chars is bigger than WWT, I will consider that message is finished. This will be "Message End" indication to my driver, who does not know protocol. > > I would not do that. If the first byte you get is 61 or 6C, just get SW2 and > return. The application will take care of the get response and send the > proper command. So, you are suggesting this approach : Inside the driver code insert check for the first character that comes : if (rx_char & 0xf0 == 0x60) { rx_len = 2; /* This will overwrite rx_len = Le demanded by transport layer */ } Like this driver will exit back to transport layer after 2 chars, as rx_len is now 2 and not Le. Is this what you suggesting, or I did not understand correctly ? BTW. I am hesitating about this solution, because I'll have to pollute my drivers code with T=0 protocol dependencies, which should be processed in transport layer (to which I can not exit before driver do all RX or time outs). Thanks for your answer and best regards, Drasko _______________________________________________ Muscle mailing list [email protected] http://lists.drizzle.com/mailman/listinfo/muscle
