This discussion is archived
5 Replies Latest reply: Mar 28, 2013 1:48 AM by fgrieu RSS

Reading big file from an aplet

995197 Newbie
Currently Being Moderated
I am writing an applet that stores 3 files of different sizes 5 Kb, 7 Kb and 11 Kb. I have got no problems with storing the files inside the applet. But when I try to read them back, I can only read the first two (smaller files).
The third file throws an exception:

javax.smartcardio.CardException: Could not obtain response+
     at sun.security.smartcardio.ChannelImpl.doTransmit(Unknown Source)
     at sun.security.smartcardio.ChannelImpl.transmit(Unknown Source)

I have tried to figure out the problem and I have found out it has to do with the size of the file. So I created a test file of size 7 Kb and incremented this file bit by bit.
It worked until I reached 7905 bytes. It means 7905 bytes is the maximum number of bytes I can read from the applet.
I am chaining the response using sample code written by Safarmer:
public void readFile(APDU apdu, short[] offset, short selectedFile, short MAX_APDU_SEN, byte OFFSET_SENT)* 
         {      
          byte[] file = getFile(selectedFile);   
                if (file == null) 
                {
                     ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND);
                }
        
                // work out how many bytes to send this time and how many will be left
                short remain = (short) (file.length - offset[OFFSET_SENT]);
                boolean chain = remain > MAX_APDU_SEN;
                short sendLen = chain ? MAX_APDU_SEN : remain;
                apdu.setOutgoing();
                apdu.setOutgoingLength(sendLen);
                apdu.sendBytesLong(file, offset[OFFSET_SENT], sendLen);
       
              // Check to see if there are more APDU's to send
              if (chain) 
              {
                     offset[OFFSET_SENT] += sendLen; // count the bytes sent
                     ISOException.throwIt(ISO7816.SW_BYTES_REMAINING_00); // indicate there are more bytes to come
              } 
              else 
              {
                     offset[OFFSET_SENT] = 0; // no more bytes to send
              }
     }  
I have tried two different types of cards i.e JC 2.2.1 (36Kb) and JC 2.2.2 (80Kb) compatible cards but they all behave the same.

Any help please?

Edited by: tinoo on 27-Mar-2013 09:05
  • 1. Re: Reading big file from an aplet
    fgrieu Newbie
    Currently Being Moderated
    Please fix the source code shown (there are + signs that do not make sense); perhaps use<tt>
     </tt>bracketing, per the FAQ
    https://forums.oracle.com/forums/help.jspa
    
    It might help to know:
    - the value of MAX_APDU_SEN (is 7905 a near multiple?);
    - what happens if you lower MAX_APDU_SEN slightly;
    - what Smart Card reader/driver you are using;
    - if it is operating in contact or contactless;
    - the ATR, or ATQA/ATQB, as applicable;
    - if you tried with a different reader/protocol;
    - what happens in a simulator.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
  • 2. Re: Reading big file from an aplet
    995197 Newbie
    Currently Being Moderated
    Here are some of the information I could extract. I am not sure about ATR, because I can't find a proper method to display values.

    The card reader has both contact and contactless inetfaces. The max_apdu_sent is 255. unfortunately, I only have access to this reader and I haven't tried the simulator.

    Terminal found : 2
    PC/SC terminal OMNIKEY CardMan 5x21 0
    PC/SC terminal OMNIKEY CardMan 5x21-CL 0
    ATR: 13 bytes
    Card Info : PC/SC card in OMNIKEY CardMan 5x21-CL 0, protocol T=1, state OK
  • 3. Re: Reading big file from an aplet
    fgrieu Newbie
    Currently Being Moderated
    The reformatted code is much clearer now, thanks. I do not spot anything in that code that could cause this behavior.

    Interestingly, 7905 (your experimental maximum size) is exactly 31*MAX_APDU_SEN. I assume you tried reading exactly 7650 bytes (30*MAX_APDU_SEN) to rule out the possibility of a bug for length multiple of MAX_APDU_SEN (but the code that you posted looks fine to me from this standpoint, and I can't foresee a problem on the PC side for this condition).

    It appears that you are using the contactless option of the reader, thus most likely ISO/IEC 14443-4. The maximum frame size for this protocol is negotiated per ISO/IEC 14443-3, and can not exceed 256 bytes (another common size is 128, and there's nothing in-between); that's including 1 to 3 bytes of headers depending on other negotiated option options, and 2 bytes of CRC. Therefore, an R-APDU of MAX_APDU_SEN+2 bytes is bound to use 2 frames if the limit is 256, and 3 frames is the limit is 128, with the last one conveying only a few bytes.

    I would thus try to lower MAX_APDU_SEN, say to 240,which will comfortably fit one frame if the limit is 256, and two frames if the limit is 128. This potentially could speed-up the transfer overall. Depending on the cause of the failure, this could lower or increase your size limit, and the new limit might tell something about the cause (which could well be on the PC side).
  • 4. Re: Reading big file from an aplet
    995197 Newbie
    Currently Being Moderated
    Thank you for the information. I finally got it working. I removed the chaining and made my host application reads small chunks of 256 bytes, and each time increase the offset by 256. It works fine. I even tried to read a 20 Kb file and the results were positive. So I assume chaining can not withstand very large files. I migh be wrong anyway.
  • 5. Re: Reading big file from an aplet
    fgrieu Newbie
    Currently Being Moderated
    Fine. That likely simplifies the applet, too.

    It remains that throughput could possibly be better with a chunk size slightly below 256, like 240 or 248: the number of exchanges between PC and reader is slightly increased, but the number of exchanges between reader and card is greatly decreased. Assuming a 256-byte frame buffer in the card, in which case a 248-byte chunk is near optimal: +3.2% in number of APDUs between PC and reader, but -46% in number of frames between reader and card. Should be easy to try.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points