aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Redon <kevredon@mail.tsaitgaist.info>2011-05-11 11:43:37 +0200
committerKevin Redon <kevredon@mail.tsaitgaist.info>2011-05-11 11:43:37 +0200
commitbf01f474ba53896b38de975d711728c5ac4d689b (patch)
treef7319ecc98d2391b9ed27ff6a461f7c347a77d1f
parent1f191d492cf08a24f50a1df5ca6c8709220cf0f5 (diff)
more usefull methods added (from SIMcopy)
-rw-r--r--src/lib/apdu.rb123
1 files changed, 123 insertions, 0 deletions
diff --git a/src/lib/apdu.rb b/src/lib/apdu.rb
index 86eb6ff..9e2904c 100644
--- a/src/lib/apdu.rb
+++ b/src/lib/apdu.rb
@@ -104,6 +104,10 @@ module APDU
CHV1 = [CLASS,0x20,0x00,0x01,0x08]
A38 = [CLASS,0x88,0x00,0x00,0x10]
+ # file hierarchie
+ DF_LEVELS = [0x3f,0x7f,0x5f]
+ EF_LEVELS = [nil,0x2f,0x6f,0x4f]
+
# file address (TS 51.011 10.7, page 105)
MF = [0x3F,0x00]
EF_ICCID = [0x2F,0xE2]
@@ -233,6 +237,125 @@ module APDU
return response
end
+
+ # decode data included in the select response
+ # based on 3GPP TS 11.11 9.2.1
+ def select_decode(response)
+
+ puts "decoding select response : #{response.to_hex_disp}"
+
+ # define type before interpreting
+ type = case response[6]
+ when 0
+ "RFU"
+ when 1
+ "MF"
+ when 2
+ "DF"
+ when 4
+ "EF"
+ else
+ "unknown"
+ end
+
+ if type=="MF" or type=="DF" then
+ puts " - RFU : #{response[0,2].to_hex_disp}"
+ puts " - unallocated memory : #{(response[2]<<8)+response[3]} Bytes (#{response[2,2].to_hex_disp})"
+ puts " - file ID : #{FILE_ID[(response[4]<<8)+response[5]]} (#{response[4,2].to_hex_disp})"
+ puts " - type of file : #{type} (#{response[6,1].to_hex_disp})"
+ puts " - RFU : #{response[7,5].to_hex_disp}"
+ puts " - GSM data length : #{response[12]} Bytes (#{response[12,1].to_hex_disp})"
+ charac = " - characteristics : "
+ charac += "clock stop "
+ clock_stop = (response[13]&0x01==1)
+ charac += clock_stop ? "allowed" : "not allowed"
+ charac += ", "
+ charac += case (response[13]>>2)&0x03
+ when 0
+ clock_stop ? "no prefered level" : ""
+ when 1
+ clock_stop ? "high level preferred" : "unless high level"
+ when 2
+ clock_stop ? "low level preferred" : "unless low level"
+ end
+ charac += ", "
+ charac += "AUTH/ENVELOPE freq >"
+ charac += (response[13]>>1)&0x01 ? "13/4" : "13/8"
+ charac += "MHz"
+ charac += ", "
+ charac += "CHV1 "
+ charac += (response[13]>>7)&0x01==0 ? "enabled" : "disabled"
+ charac += " (#{response[13,1].to_hex_disp})"
+ puts charac
+ puts " - # child DFs : #{response[14]} (#{response[14,1].to_hex_disp})"
+ puts " - # child EFs : #{response[15]} (#{response[15,1].to_hex_disp})"
+ puts " - # codes : #{response[16]} (#{response[16,1].to_hex_disp})"
+ puts " - RFU : #{response[17,1].to_hex_disp}"
+ codes = ["CHV1","unblock CHV1","CVH2","unblock CHV2"]
+ codes.each_index do |i|
+ puts " - #{codes[i]} : #{(response[18+i]>>7)&0x01==0 ? 'not initialised' : 'initialised'}, #{response[18+i]&0x0f} tries remaining (#{response[18+i,1].to_hex_disp})"
+ end
+ puts " - RFU : #{response[22,1].to_hex_disp}" if response.length>22
+ puts " - administrative : #{response[23..-1].to_hex_disp}" if response.length>23
+ elsif type=="EF" then
+ structure = case response[13]
+ when 0
+ "transparent"
+ when 1
+ "linear fixed"
+ when 3
+ "cyclic"
+ else
+ "unknown"
+ end
+ puts " - RFU : #{response[0,2].to_hex_disp}"
+ puts " - file size : #{(response[2]<<8)+response[3]} Bytes (#{response[2,2].to_hex_disp})"
+ puts " - file ID : #{FILE_ID[(response[4]<<8)+response[5]]} (#{response[4,2].to_hex_disp})"
+ puts " - type of file : #{type} (#{response[6,1].to_hex_disp})"
+ if structure=="cyclic" then
+ if (response[7]>>6)&0x01 then
+ puts " - INCREASE command allowed"
+ else
+ puts " - INCREASE command not allowed"
+ end
+ else
+ puts " - RFU : #{response[7,1].to_hex_disp}"
+ end
+ puts " - Access Conditions :"
+ nibble_index = 0
+ ["READ & SEEK","UPDATE","INCREASE","RFU","REHABILITATE","INVALIDATE"].each do |access|
+ nibble = ((response[8+nibble_index/2])>>(4*(1-(nibble_index%2))))&0x0f
+ condition = case nibble
+ when 0
+ "ALW"
+ when 1
+ "CHV1"
+ when 2
+ "CHV2"
+ when 3
+ "RFU"
+ when 0xf
+ "NEVER"
+ else
+ "ADM"
+ end
+ puts " #{access} : #{condition} (#{[nibble].to_hex_disp})"
+ nibble_index += 1
+ end
+ # file status
+ status = " - file status : "
+ status += response[11]&0x01==0 ? "invalidated" : "not invalidated"
+ status += ", "
+ status += (response[11]>>2)&0x01==0 ? "not readable or updatable when invalidated" : "readable when updatable when invalidated"
+ puts status
+ puts " - data length : #{response[12]} Bytes (#{response[12,1].to_hex_disp})"
+ puts " - structure : #{structure}"
+ puts " - record length : #{response[14]} Bytes (#{response[14,1].to_hex_disp})" if response.length>14
+ puts " - RFU : #{response[15..-1].to_hex_disp}" if response.length>15
+ else
+ puts " unknown file type"
+ end
+ end
# get the status (current directory)
def status