ds.ov2.util
Class Host_protocol

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

public class Host_protocol
extends Object

Host driver for steps in the OV-chip protocol layer. On the host side the OV-chip protocol layer has a low and a high-level interface. The low level interface is provided by the method run_step of this class. For it, arguments and results must be passed as arrays of APDU_Serializable (thus the result containers must be allocated before running the step).

A more convenient high-level interface is generated by the IDL compiler, see the generated *_stub classes. The stub code does also create and maintain the necessary instances of this class. Normal host driver code should therefore not come in contact with this class.

This class is designed such that one instance must be created for every protocol step. These instance can live for the whole duration of the application. At creation time the parameters for progress and debug output are fixed.

CPP Preprocessing
no cpp preprocessing needed
Execution Environment:
host
Author:
Hendrik Tews
Version:
$Revision: 1.20 $
Last Commit:
$Date: 2009-05-20 11:02:38 $ by $Author: tews $

Field Summary
private  boolean apduscript
          Whether to print apduscript lines.
private static byte CLA
          The CLA byte for all the APDU's created here.
private static int max_receive_bytes
          The maximal value for the LE field, which indicates the expected number of bytes in the response APDU.
private static int max_send_bytes
          The maximal number of data bytes in one command APDU.
private  String name
          The name of the protocol step for the debugging output.
private  PrintWriter out
          The output channel for progess and debug messages.
private  byte protocol_id
          The protocol identification number for this instance.
private  Protocol_step protocol_step
          The protocol step for this instance.
private  byte step_id
          The protocol step number.
 
Constructor Summary
Host_protocol(Protocol protocol, Protocol_step step, PrintWriter out, boolean apduscript, String name)
          Create a new instance for running the protocol step step.
 
Method Summary
static void print_apdu_full(PrintWriter out, CommandAPDU apdu, String msg, boolean apduscript, String apdu_script_header)
          Print an APDU in human readable form to out.
static void print_apdu(PrintWriter out, CommandAPDU apdu, String msg)
          Print an APDU in human readable form to out.
 void run_step(CardChannel card_channel, APDU_Serializable[] arguments, APDU_Serializable[] results)
          Run the protocol step of this instance.
private  int send_apdu_message(CardChannel card_channel, CommandAPDU apdu, byte[] res, int index, int check_response_length)
          Send one APDU to the applet and expect check_response_length bytes in the response APDU.
private  byte[] send_long_apdu(CardChannel card_channel, byte[] args, int res_length)
          Send a long APDU to the card.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

CLA

private static final byte CLA
The CLA byte for all the APDU's created here. Has value 0.

See Also:
Constant Field Values

protocol_id

private final byte protocol_id
The protocol identification number for this instance.


protocol_step

private final Protocol_step protocol_step
The protocol step for this instance.


step_id

private final byte step_id
The protocol step number.


out

private final PrintWriter out
The output channel for progess and debug messages. Is null if these messages are disabled.


apduscript

private final boolean apduscript
Whether to print apduscript lines.


name

private final String name
The name of the protocol step for the debugging output.


max_send_bytes

private static final int max_send_bytes
The maximal number of data bytes in one command APDU. Has value 255.

See Also:
Constant Field Values

max_receive_bytes

private static final int max_receive_bytes
The maximal value for the LE field, which indicates the expected number of bytes in the response APDU. Has value 255.

See Also:
Constant Field Values
Constructor Detail

Host_protocol

public Host_protocol(Protocol protocol,
                     Protocol_step step,
                     PrintWriter out,
                     boolean apduscript,
                     String name)
Create a new instance for running the protocol step step. The protocol step of the new instance cannot be changed, so it is necessary to create one instance for every protocol step. The declared arguments and the declared results of the step are not cached in this instance, so they might be updated or changed after the creation of this instance (for instance for changing their size in test frames). If the declared arguments or results are changed, special care must be taken that the declared arguments and results in the applet are changed in the same way.

Asserts that the protocol identifier is less than 0x70. (The INS byte 0x70 is reserved for the manage channel command in the global platform.)

Throws also an assertion if the protocol identifier is less than 0, which usually happens if the protocol is not linked in some protocol array.

Parameters:
protocol - the protocol to which step belongs
step - the protocol step the new instance will run
out - if non-null print progress and debug messages on it
apduscript - if true print additional apduscript lines on out
name - name of the protocol step for the debugging output on out
Method Detail

print_apdu_full

public static void print_apdu_full(PrintWriter out,
                                   CommandAPDU apdu,
                                   String msg,
                                   boolean apduscript,
                                   String apdu_script_header)
Print an APDU in human readable form to out. Suppress printing if out is null. Produce apduscript lines if apduscript is true.

Parameters:
out - channel to print to, might be null to supress printing
apdu - APDU to print
msg - string to insert at the start of the output
apduscript - if true, additionally print apduscript lines
apdu_script_header - string to print before the apduscript line

print_apdu

public static void print_apdu(PrintWriter out,
                              CommandAPDU apdu,
                              String msg)
Print an APDU in human readable form to out. Suppress printing if out is null. Special version of print_apdu_full with apduscript line printing disabled.

Parameters:
out - channel to print to, might be null to supress printing
apdu - APDU to print
msg - string to insert at the start of the output

send_apdu_message

private int send_apdu_message(CardChannel card_channel,
                              CommandAPDU apdu,
                              byte[] res,
                              int index,
                              int check_response_length)
                       throws CardException
Send one APDU to the applet and expect check_response_length bytes in the response APDU. Store the response data in the res array at index index.

The response APDU must contain precisely check_response_length bytes, except for the case where check_response_length equals -1, in which 255 or 256 response bytes are accepted. If the applet returns a wrong number of bytes an protocol error is indicated by throwing an Card_response_error exception.

For a response status different from OK (ie, different from 0x9000) an Card_response_error exception is thrown too. This could be caused by an protocol error (eg., the applet expects a different step or a different amount of argument or result data) or any other problem in the applet (eg. a NullPointerException).

Parameters:
card_channel - communication channel to the applet
apdu - the CommandAPDU to send
res - byte array for the response data, must be non-null even if no response is expected and check_response_length is 0.
index - starting index in res to copy the response data
check_response_length - expected length of the data in the response APDU; if the applet returns a different amount of data an Card_response_error exception is thrown; as an exception the value -1 means to accept either 255 or 256 response bytes
Returns:
the number of bytes that have been copied into the res array; if check_response_length is -1 either 255 or 256, otherwise the return value does always equal check_response_length
Throws:
CardException - for card communication errors
Response_apdu.Card_response_error - if a protocol error occurs or the response status is different from 0x9000.

send_long_apdu

private byte[] send_long_apdu(CardChannel card_channel,
                              byte[] args,
                              int res_length)
                       throws CardException
Send a long APDU to the card. For the sake of this method a long APDU can hava more than 255 bytes of data in the command and the response APDU. The data to be send to the card is in the args byte array.

This method splits the data to be send into 255 byte APDU's and calls send_apdu_message to send everything to the applet. It issues sufficiently many response APDU's to retrieve all results and assembles them in one byte array. If the out argument of the constructor was non-null, appropriate progress and debugging messages will be generated on that PrintWriter.

If the response length is different from res_length a protocol error is indicated by throwing an Card_response_error exception. The same exception is thrown if the response status of a (small) APDU is not OK (ie., different from 0x9000). The latter could be caused by an protocol error (eg., the applet expects a different step or a different amount of argument or result data) or any other problem in the applet (eg. a NullPointerException).

Parameters:
card_channel - communication channel to the applet
args - data to be sent to the card, can be between 0 and 32640 bytes long
res_length - the expected amount of respose data, must be between 0 and 32640
Returns:
the respose data in a byte array of length res_length
Throws:
CardException - for card communication errors
Response_apdu.Card_response_error - if a protocol error occurs or the response status of one (short) APDU is different from 0x9000.

run_step

public void run_step(CardChannel card_channel,
                     APDU_Serializable[] arguments,
                     APDU_Serializable[] results)
              throws CardException,
                     IllegalArgumentException,
                     NullPointerException
Run the protocol step of this instance. Check the compatibility of the actual arguments and results against the declared arguments and results of the Protocol_step argument of the constructor. Serialize the arguments, split them into 255 byte APDU's and send everything to the applet. Issue sufficiently many response APDU's to retrieve all results and deserialize them into the provided result containers. If the out argument of the constructor was non-null, appropriate progress and debugging messages will be generated on that PrintWriter.

This method does the compatibility checks and serialization/deserialization. The remainder is done by send_long_apdu.

If the applet response does not meet the expectations a protocol error is indicated by throwing an Card_response_error exception. The same exception is thrown if the response status of one APDU is not OK (ie., different from 0x9000). The latter could be caused by an protocol error (eg., the applet expects a different step or a different amount of argument or result data) or any other problem in the applet (eg. a NullPointerException).

Parameters:
card_channel - communication channel to the applet
arguments - the arguments of this step
results - APDU_Serializable containers for the results
Throws:
IllegalArgumentException - if the compatibility check fails
NullPointerException - if one of the arrays contains a null reference
CardException - for card communication errors
Response_apdu.Card_response_error - if a protocol error occurs or the response status of one APDU is different from 0x9000.