import java.io.*;
import com.linuxnet.jpcsc.*;

public class ChipknipTerminal
{
   public ChipknipTerminal() {
      try {
         Context context = new Context();
         context.EstablishContext(PCSC.SCOPE_GLOBAL, null, null);
         String[] readers = context.ListReaders();
         if (readers.length <= 0) {
            System.err.println("No readers found...");
            return;
         }
         String reader = readers[askForReader(readers)];
         System.out.println("Using reader " + reader);
         Card card = context.Connect(reader);
         card.BeginTransaction();
         System.out.println("Chipknip balance: " +
            amountString(getBalance(card)));
         card.EndTransaction(PCSC.RESET_CARD);
         card.Disconnect();
         context.ReleaseContext();
      } catch (Exception e) {
         System.out.println("Error: " + e.getMessage());
      }
   }

   public int getBalance(Card card) {
      Apdu apdu = new Apdu((byte)0xE1, (byte)0xB4,
                           (byte)0x00, (byte)0x01, 0, null, 0, 5);
      byte[] data = card.Transmit(apdu);
      return ((data[0] & 0x000000FF) << 16) |
             ((data[1] & 0x000000FF) << 8) |
             (data[2] & 0x000000FF);
   }

   private int askForReader(String[] readers) throws IOException {
      System.out.println("Found the following readers: ");
      for (int i = 0; i < readers.length; i++) {
         System.out.println("   " + i + ": " + readers[i]);
      }
      System.out.print("Enter reader index: ");
      BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
      try {
         return Integer.parseInt(in.readLine());
      } catch (NumberFormatException nfe) {
         return 0;
      }
   }

   private static String amountString(int value) {
      return (value / 100) + "." + (((value % 100) < 10) ? "0" : "")
         + (value % 100);
   }

   public static void main(String[] arg) {
      new ChipknipTerminal();
   }
}

