YstokCard - smart card API - Examples

The example logs below were copied from the Listener window (REPL console) on LispWorks 4.4 for Windows.

Simple interaction

;; Compile and load YstokCard
(asdf:operate 'asdf:load-op 'ycard)

;; Specify PC/SC dynamic library name and location on *nix
#-win32
(setq card:*pcsc-module* "libpcsclite.so")

;; If needed, specify the OmniKey Sync API module location
(setq card:*oksa-module-pathname* #P"E:/util/cards/scardsyn.dll")
(ffc:load-foreign-module :omnikey-sync-api)

;; Device database queries
(card:list-device-groups)
;=> ("My group" "SCard$DefaultReaders") 
(card:list-device-names)
;=> ("OMNIKEY CardMan 5x21 0" "OMNIKEY CardMan 5x21-CL 0") 

;; Initialize context, create device and card objects
(setq card:*context* (card:establish-context))
;=> #<Pointer: HANDLE = #xCD020000;>

(setq device (card:ensure-device (second (card:list-device-names
                                          "SCard$AllReaders"))))
;=> #<OMNIKEY "OMNIKEY CardMan 5x21-CL 0" (:PRESENT)>

(card:ask-device-state device)
;=> :PRESENT, NIL

(setq card (card:device-connect device))
;=> #<MIFARE-STD "Mifare Standard" EA010000>
; ATR: 3B 8F 80 01 80 4F 0C A0 00 00 03 06 03 00 01 00 00 00 00 6A

(card:uid card)
;=> 678011255

(card:card-empty-p card)
;=> T

;; Write and read file 4 record 1
;; In Mifare terms, the first block (16 bytes) of sector 4
(card:put-object card 4 (make-octet-vector 16 :initial-element 66)
     :record :first :key-kind :A :key card:+std-deliver-key+)
;=> T
(card:get-object card 4 t :record :first :key-kind :A :key card:+std-deliver-key+)
;=> #(66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66) 

;; Internal authentication
(card:authenticate-call card 4 (list card:+std-deliver-key+))
;=> #(255 255 255 255 255 255), (#(255 255 255 255 255 255))

;; Write and read in lower level
(card:card-update-binary card device #v"00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F"
     :file 4 :record :first)
;=> T
(card:card-read-binary card d :file 4 :record :first)
;=> #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)

;; Restore file 4 to the delivery (empty card) contents
(card:card-update-binary card device #16v0 :file 4 :record :first)

;; Release objects
(card:card-disconnect card)
(card:release-devices)
(card:release-context card:*context*)

Monitoring devices

To start monitoring, load the file examples/test-monitor.lisp included into the distribution package (its contents is as follows):

;; Switch logging on and direct log records to console
(pushnew :ycard yl:*log-options*)
(setq yl:*log-stream* *standard-output*)

;; Switch print ATR on and customize the list of known ATRs
(setq card:*monitor-print-atr* t)
;(setq card:*smartcard-list-pathname* #P"E:/util/cards/smartcard_list.txt")

(card:start-monitor
     :callback (lambda (device &key state mode atr)
                 (format t "~%** CALLBACK on ~s state ~s mode ~s"
                         device state mode)))
;(card:stop-monitor)

Windows supports the "ghost device" named "\\?PnP?\Notification". It helps monitoring plug-and-play events that occur when the USB connection cable of some real device is plugged or unplugged.

Start smart card monitoring at 2013-Dec-24 13:30:33.
Using PnP notification device mechanism.
Scanning attached devices...
Waiting for any device...
...found the following
Device \\?PnP?\Notification: state 20002
Scanning attached devices...
1: OMNIKEY CardMan 5x21 0
2: OMNIKEY CardMan 5x21-CL 0
Device OMNIKEY CardMan 5x21-CL 0: state :EMPTY
There is no card in the device.
Device OMNIKEY CardMan 5x21 0: state :EMPTY
There is no card in the device.
Device OMNIKEY CardMan 5x21-CL 0: state :PRESENT
There is a card in the device.
ATR: 3B 8F 80 01 80 4F 0C A0 00 00 03 06 03 00 01 00 00 00 00 6A
TS = 3B Direct Convention
T0 = 8F, Y(1): b8, K: 15 (historical bytes)
 TA(1) = NIL TA(1) = NIL TC(1) = NIL TD(1) = 80
 TA(2) = NIL TA(2) = NIL TC(2) = NIL TD(2) = 01
Historical bytes: 80 4F 0C A0 00 00 03 06 03 00 01 00 00 00 00
  Category indicator byte: 80 (compact TLV data object)
    Tag: 4, Len: 15
      Initial access data: 0C A0 00 00 03 06 03 00 01 00 00 00 00 "^L ..."Checksum = 6A
- Mifare Standard 1K (as per PCSC std part3)
- RFID - ISO 14443 Type A Part 3 (as per PCSC std part3)
- Philips MIFARE Standard (1 Kbytes EEPROM)
- http://www.nxp.com/#/pip/pip=[pfp=41863]|pp=[t=pfp,i=41863]
- RFID - ISO 14443 Type A - Transport for London Oyster
- ACOS5/1k Mirfare
- RFID - ISO 14443 Type A - NXP Mifare card with 1k EEPROM
- vivotech ViVOcard Contactless Test Card
- Bangkok BTS Sky SmartPass
Device OMNIKEY CardMan 5x21-CL 0: state :EMPTY
There is no card in the device.
Device OMNIKEY CardMan 5x21 0: state :PRESENT
There is a card in the device.
ATR: 3B 6E 00 00 00 31 C0 65 D3 C1 02 01 28 71 D6 8C 61 33
TS = 3B Direct Convention
T0 = 6E, Y(1): b6, K: 14 (historical bytes)
Historical bytes: 00 00 00 31 C0 65 D3 C1 02 01 28 71 D6 8C
  Category indicator byte: 00 (compact TLV data object)
    Tag: 0, Len: 0
      Value:  ""
    Tag: 0, Len: 0
      Value:  ""
    Tag: 3, Len: 1
      Card service data byte: C0
        - Application selection: by full DF name
        - Application selection: by partial DF name
        - EF.DIR and EF.ATR access services: by GET RECORD(s) command
        - Card with MF
    Tag: 6, Len: 5
      Data: D3 C1 02 01 28 "..^B^A("
    Mandatory status indicator (3 last bytes)
    LCS (life cycle status): 71 (Proprietary)
    SW: D6 8C
Extra bytes: 61 33
- SberBank Silver Debit Card (VISA)
Device OMNIKEY CardMan 5x21 0: state :EMPTY
There is no card in the device.
Device \\?PnP?\Notification: state 10002
Device OMNIKEY CardMan 5x21-CL 0: state :UNAVAILABLE
This device is not available for use.
Scanning attached devices...
Waiting for any device...
...found the following
Device \\?PnP?\Notification: state 2
Device OMNIKEY CardMan 5x21 0: state :UNKNOWN
The given device name is not recognized by the Card Manager.
Scanning attached devices...
Waiting for any device...

Cancel smart card monitoring at 2013-Dec-25 13:50:09.
Aborted monitoring at 2013-Dec-25 13:50:09.