00001
00002
00003
00004
00005
00006
00007 #include <ccid.h>
00008 #include "sim-internal.h"
00009 #include "bytesex.h"
00010
00011 static int do_select(struct _sim * s, uint16_t id)
00012 {
00013 xfr_reset(s->s_xfr);
00014 xfr_tx_byte(s->s_xfr, SIM_CLA);
00015 xfr_tx_byte(s->s_xfr, SIM_INS_SELECT);
00016 xfr_tx_byte(s->s_xfr, 0);
00017 xfr_tx_byte(s->s_xfr, 0);
00018 xfr_tx_byte(s->s_xfr, 2);
00019 xfr_tx_byte(s->s_xfr, (id >> 8));
00020 xfr_tx_byte(s->s_xfr, (id & 0xff));
00021 return chipcard_transact(s->s_cc, s->s_xfr);
00022 }
00023
00024 static int do_get_response(struct _sim * s, uint8_t le)
00025 {
00026 xfr_reset(s->s_xfr);
00027 xfr_tx_byte(s->s_xfr, SIM_CLA);
00028 xfr_tx_byte(s->s_xfr, SIM_INS_GET_RESPONSE);
00029 xfr_tx_byte(s->s_xfr, 0);
00030 xfr_tx_byte(s->s_xfr, 0);
00031 xfr_tx_byte(s->s_xfr, le);
00032 return chipcard_transact(s->s_cc, s->s_xfr);
00033 }
00034
00035 int _apdu_select(struct _sim *s, uint16_t id)
00036 {
00037 uint8_t sw1, sw2;
00038
00039 if ( !do_select(s, id) )
00040 return 0;
00041
00042 sw1 = xfr_rx_sw1(s->s_xfr);
00043 if ( sw1 != SIM_SW1_SHORT )
00044 return 0;
00045
00046 sw2 = xfr_rx_sw2(s->s_xfr);
00047 if ( !do_get_response(s, sw2) )
00048 return 0;
00049
00050 sw1 = xfr_rx_sw1(s->s_xfr);
00051 if ( sw1 != SIM_SW1_SUCCESS )
00052 return 0;
00053
00054 return 1;
00055 }
00056
00057 int _apdu_read_binary(struct _sim *s, uint16_t ofs, uint8_t len)
00058 {
00059 xfr_reset(s->s_xfr);
00060 xfr_tx_byte(s->s_xfr, SIM_CLA);
00061 xfr_tx_byte(s->s_xfr, SIM_INS_READ_BINARY);
00062 xfr_tx_byte(s->s_xfr, ofs >> 8);
00063 xfr_tx_byte(s->s_xfr, ofs & 0xff);
00064 xfr_tx_byte(s->s_xfr, len);
00065 if ( !chipcard_transact(s->s_cc, s->s_xfr) )
00066 return 0;
00067 return ( xfr_rx_sw1(s->s_xfr) == 0x90 );
00068 }
00069
00070 int _apdu_read_record(struct _sim *s, uint8_t rec, uint8_t len)
00071 {
00072 xfr_reset(s->s_xfr);
00073 xfr_tx_byte(s->s_xfr, SIM_CLA);
00074 xfr_tx_byte(s->s_xfr, SIM_INS_READ_RECORD);
00075 xfr_tx_byte(s->s_xfr, rec);
00076 xfr_tx_byte(s->s_xfr, 0x4);
00077 xfr_tx_byte(s->s_xfr, len);
00078 if ( !chipcard_transact(s->s_cc, s->s_xfr) )
00079 return 0;
00080 return ( xfr_rx_sw1(s->s_xfr) == 0x90 );
00081 }