ds.ov2.util
Class Card_protocol

java.lang.Object
  extended by ds.ov2.util.Card_protocol

public class Card_protocol
extends Object

Applet side of the OV-chip protocol implementation. This class is the heart of the OV-chip protocol on the card. Every applet should contain precisely one instance of this class. Under normal circumstances the user does not have to care about it, because this instance is created, maintained and used in Protocol_applet, see Protocol_applet.card_protocol.

The singleton instance in Protocol_applet.card_protocol processes all incomming APDU's with process. First it will be checked if the protocol identification, the step number and the batch meet the expectations. Then, for argument APDU's the data is transfered to the declared arguments of the current protocol step. If all arguments have been received the method of the current step is called. Finally the results are transfered back to the host with response APDU's.

So this class implements all protocol-layer related features, execpt for managing the registered protocols (see Registered_protocols) and selecting new protocols (see Protocol_applet.process and Registered_protocols.get_protocol).

The singleton instance in Protocol_applet.card_protocol keeps the current protocol and the current step in its local state. Additionally it remembers where to continue with argument deserialization or result serialization for the next APDU. All this internal state is updated appropriately when processing APDU's.

The implementation is just a matter of interpreting the data structures of the protocols and protocol steps. No big surprises here, it is only a bit cumbersome because Java Card 2.2.1 only guarantees an APDU buffer size of 32 bytes.

CPP Preprocessing
This class uses the following cpp defines: PACKAGE, PUBLIC, ASSERT, ASSERT_TAG
Execution Environment:
card
Author:
Hendrik Tews
Version:
$Revision: 1.13 $
Last Commit:
$Date: 2009-04-09 10:42:16 $ by $Author: tews $

Field Summary
private  byte batch
          The batch number.
private  short data_index
          The number of bytes of the current argument or result that have already been received or sent.
private  Protocol protocol
          The current protocol or null if no protocol is selected.
private  short protocol_step
          The number of the current protocol step.
private  short total_still_to_send
          Total number of result bytes still to send.
private  short variable_index
          The index of the argument or result that we are currentely working on.
 
Constructor Summary
Card_protocol()
          Constructor.
 
Method Summary
 void clear_protocol()
          Clears the current protocol selection.
private  void finish_step()
          Finish current protocol step.
private  void process_method(APDU apdu, byte[] buf, Protocol_step step)
          Call the method for the current step and start sending the results afterwards.
private  void process_receive(APDU apdu, byte[] buf, Protocol_step step)
          Process the next argument APDU.
private  void process_send(APDU apdu, byte[] buf, Protocol_step step)
          Start or continue to send the results to the host.
 void process(APDU apdu, byte[] buf)
          Process the next APDU in the currently selected protocol.
 boolean protocol_running()
          Returns true if a protocol is selected.
 void set_protocol(Protocol protocol)
          Set the next selected protocol.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

protocol

private Protocol protocol
The current protocol or null if no protocol is selected. Reset to null after the last result APDU of the last step of a protocol. Then the outside has to set the next current protocol with set_protocol. Normally this is done automatically in Protocol_applet.process.

The INS byte of the next incoming APDU must be equal to the protocol identification of this protocol.


protocol_step

private short protocol_step
The number of the current protocol step. Automatically increased after each step.

The P1 byte of the next incoming APDU must be equal to this number.


variable_index

private short variable_index
The index of the argument or result that we are currentely working on. If the batch is positive it is an index of an argument in the array of declared arguments of the current step. If the batch is negative it is an index of a result in the array of declared results or the current step.


data_index

private short data_index
The number of bytes of the current argument or result that have already been received or sent.


batch

private byte batch
The batch number. The batch counts the APDU's in one step. For argument APDU's the first bit is 0 and the batch counts the argument APDU's from 0 upwards. For result APDU's the first bit is 1 and the batch counts from -128 upwards. The first response is sent in the response APDU of the last argument APDU, therefore the first result APDU has batch -127.

The P2 byte of the next incomming APDU must be equal to the batch.


total_still_to_send

private short total_still_to_send
Total number of result bytes still to send. Used for checking the response length (LE byte) of the result APDU's. Not used when receiving arguments.

Constructor Detail

Card_protocol

Card_protocol()
Constructor. There is only one instance of this class necessary in each applet. This is automatically created and maintained in Protocol_applet. This constructor does not initialize anything. Initialization happens in set_protocol.

Method Detail

protocol_running

public boolean protocol_running()
Returns true if a protocol is selected.

Returns:
true if a protocol is currently selected.

set_protocol

public void set_protocol(Protocol protocol)
Set the next selected protocol. (Re-)Initialize the local state to prepare for the first APDU of this protocol.

Parameters:
protocol - next selected protocol

clear_protocol

public void clear_protocol()
Clears the current protocol selection. Afterwards no protocol is selected.


finish_step

private void finish_step()
Finish current protocol step. Called as the last action in the last result APDU. Advances protocol_step and initializes the local state for the next step (set variable_index, data_index and batch all to 0). If the last step of a protocol is finished the current protocol selection is cleared.


process_send

private void process_send(APDU apdu,
                          byte[] buf,
                          Protocol_step step)
Start or continue to send the results to the host. This method is called in the last argument APDU, just after the step method has finished, and afterwards for all result APDU that follow.

This method serializes the declared results of the current step, advances data_index, variable_index, total_still_to_send and batch as needed and sends the serialized data to the host. After the last result byte has been sent the current step is finished with finish_step().

This method checks the expected response length (the LE byte) as far as this is possible. An ISOException is thrown for wrong values.

Parameters:
apdu - the incoming APDU
buf - the APDU buffer, must be equal to apdu.getBuffer().
step - the current protocol step, must be equal to protocol.steps[protocol_step]
Throws:
ISOException - with status SW_CORRECT_LENGTH_00 if the expected response length (the LE byte) is too small

process_method

private void process_method(APDU apdu,
                            byte[] buf,
                            Protocol_step step)
Call the method for the current step and start sending the results afterwards. This method only calls the step method and prepares the local state for sending the results (variable_index and data_index are reset to 0, batch is set to 0x80 and total_still_to_send is initialized to the total size of the declared results). Sending the first results is then done by process_send.

Parameters:
apdu - the incoming APDU
buf - the APDU buffer, must be equal to apdu.getBuffer().
step - the current protocol step, must be equal to protocol.steps[protocol_step]
Throws:
ISOException - with status SW_CORRECT_LENGTH_00 if the expected response length (the LE byte) of the last argument APDU is too small

process_receive

private void process_receive(APDU apdu,
                             byte[] buf,
                             Protocol_step step)
Process the next argument APDU. If there are still arguments to receive then deserialize the data of this APDU into the declared arguments. Divert to process_method after all arguments have been received. Advance variable_index, data_index and batch as needed.

Checks that the host does not send too much data. Throw an ISOException otherwise. (If the host sends too little data than the next incomming APDU will yield a batch mismatch error.)

Parameters:
apdu - the incoming APDU
buf - the APDU buffer, must be equal to apdu.getBuffer().
step - the current protocol step, must be equal to protocol.steps[protocol_step]
Throws:
ISOException - with status SW_BYTES_REMAINING_00 if the host has sent too much data
ISOException - with status SW_CORRECT_LENGTH_00 if the expected response length (the LE byte) of the last argument APDU is too small

process

public void process(APDU apdu,
                    byte[] buf)
Process the next APDU in the currently selected protocol. This method checks it the protocol identification number, the step number and the batch in the incoming APDU match our local state. If one of these checks fails an ISOException is thrown with an appropriate response status.

Depending on the batch the APDU is delegated to either process_receive or process_send.

Asserts that a current protocol is selected.

In case of any error the protocol selection is cleared and the current protocol aborted.

Parameters:
apdu - the incoming APDU
buf - the APDU buffer, must be equal to apdu.getBuffer().
Throws:
ISOException - with status OV_UNEXPECTED_PROTOCOL_ID for a protocol identification number mismatch
ISOException - with status OV_UNEXPECTED_PROTOCOL_STEP for a protocol step number mismatch
ISOException - with status OV_UNEXPECTED_BATCH for a batch mismatch
ISOException - with status SW_BYTES_REMAINING_00 if the host has sent too much data
ISOException - with status SW_CORRECT_LENGTH_00 if the expected response length (the LE byte) of the last argument APDU or an result APDU is too small