EAS management for ICODE SLI/SLI-X (standard, type S and type L)

ICODE SLI are ISO 15693 compliant but feature proprietary extensions not implemented in the reader's firmware. However, you can use those features in transparent mode. The following post will focus on EAS management with this type of tag. The function entries described are available in the CSB6 SDK.


EAS management in the different ICODE SLI types 

The way to access to the EAS field depend on the type of ICODE used. With ICODE SLI/SLI-X type L and S, EAS field can be password protected. Once password protected, a "set password" command must be sent to the card once in the RF field or if the password is modified. It will allow the execution of most of the other commands. This security is not available on classic ICODE SLI/SLI-X.


Transparent mode APDU structure

Most of the frames sent to the card contains :

Flags (1 byte) :
Those are detailed in the ISO 15693 documentation.

Command ID (1 byte) :
Allows to identify the type of command sent.

IC manufacturing code (1 byte) :
It refers to the tag type and is contained in the UID of the tag. For NXP Semiconductors, This code is 04h.

UID (8 bytes).

Some other fields are command specific and will be detailed below.


Command available in the SDK

*** AVAILABLE FOR ALL ICODE SLI TYPES ***

Set EAS
Available with void set_EAS(BYTE snr[8]);  
Set EAS status to 1.                                                                        

Reset EAS
Available with void reset_EAS(BYTE snr[8]); 
Set
 EAS status to 1.

Lock EAS
Available with void lock_EAS(BYTE snr[8]); 
This field is commented in the source code. Once locked, EAS cannot be modified anymore.

AVAILABLE FOR ICODE SLI/SLI-X S and L types

Protect EAS
Available with void protect_EAS(BYTE snr[8]);
This command allows to protect the EAS field with a password. Once set, this field cannot be changed and you will have to use the "set password" command to modify the EAS status.

Get random number
Available with short get_random_nb(BYTE snr[8], BYTE * rd_nb)      
It will request a 2 bytes randomly generated code required for a proper use of the "set password" command.

Set password
Available with void set_password(BYTE snr[8], BYTE password[4])
This command requires specific fileds : a password ID to inform the card of which fields are needed to be unlocked, and the previously stored password XOR two random numbers acquired with the "get random number" command.

ex :  if the last password was (00 00 00 00)h, and the last "get random number" command return you (0A 25)h, the 4 bytes to pass as command parameters will be (0A 25 0A 25)h.

Write password
Available with void write_password(BYTE snr[8], BYTE password[4])
Write a new password in the card (if the password field has not been locked).

Lock password
Available with void lock_password(BYTE snr[8])
This function is commented in the source code. Once locked, the password cannot be changed.


 About the reference application

The application manual is available via the executable call.
A simple [EXECUTABLE NAME] [COM] [HELP] will display the commands available.

KitKat: Impact of the latest Android OS on card emulation

“Who controls the smartphone?” is the obvious question that can lead to generating profits from every transaction by the controlling parties.

NFC use on smartphones allows for 3 modes of operation:  tag reading/writing, peer-to-peer and card emulation. The card emulation mode is the most interesting mode for the companies involved in such developments because it immediately generates cash flow. The business model is simple: one just needs to replace the existing cards (payment, transportation, etc.). A fraction of the millions of transactions performed everyday by those cards can then be transformed into profit for those controlling the smartphone.

Since 2005-2006, when NFC made its start, we have been witnessing a war among manufacturers; between those controlling the hardware and/or controlling its operating system, neither of which have strong ties with final users; and the cellphone carriers who are controlling the SIM and have strong customer relations through subscription plans.

From each side of the battlefield, the same argument is always pointed out: a transaction implies security requirements, and a security requirement implies embedded applications in a secured processor. The cellphone carriers argue that the SIM card is the best choice, since it is a secured processor and it is already present without any additional cost. The manufacturers argue that a secured processor (Secure Element) has to be added on the motherboard, the extra cost being minimal and the user being able to freely change transaction service providers without having to transfer his or her telephone service to a new vendor requiring a new SIM card.

In the middle of the battle ground, a new contender has emerged: the TSM (Trusted Service Manager), provides a unique and portable service whatever the underlying technical context, for a fee of course.

Until last week, the position of each party had remained frozen since the war started in 2005-2006. And then KitKat arrived.

KitKat is the code name for Android’s new 4.4 Operating System. And in the presentation of KitKat, from the second paragraph, one can read:

Android 4.4 introduces new platform support for secure NFC-based transactions through Host Card Emulation (HCE), for payments, loyalty programs, card access, transit passes, and other custom services. With HCE, any app on an Android device can emulate an NFC smart card, letting users tap to initiate transactions with an app of their choice — no provisioned secure element (SE) in the device is needed.(http://developer.android.com/about/versions/android-4.4.html)

Technically nothing really new; BlackBerry offered the same principle in the latest version of its OS. But Android’s market share is significantly different from BlackBerry’s market share! With this support, developers of sector-specific applications (access control, loyalty) finally have a solution to develop the card emulation mode on smartphones easily and without depending on anyone.

A few technical points to keep in mind:

1.      Card emulation « within the host » (HCE) cannot work if the phone is turned off (deliberately turned off or out of battery), whereas within some SIM-centric or SE-centric architectures it is sometimes possible to perform a transaction with a turned off smartphone.

2.      The main processor of the smartphone (baseband) isn’t a secure processor. Applications requiring a critical level of security (i.e., whenever the profits from the fraud is higher than the cost of the fraud: payment, public transportation, high security level access control, ID cards...) shouldn’t be implemented in this mode.

3.      The transaction times may perform less well; furthermore, they may operate less consistently than a classic implementation within a secured processor – which by nature is independent from other applications running on the smartphone.

4.      The technical architecture is based on ISO 14443 layer 4, type A, ISO 7816-4 for APDUs formalism, and ISO 7816-5 for the application selection by the reader thanks to a unique AID. Any application out of this frame wouldn’t qualify for the HCE porting. This is especially the case of some French « public transportation » implementations for which the readers only implement ISO 14443 type B.

Now, how do you implement that in the real world?

Step one, own a smartphone or a tablet running Android 4.4. Step two, download the latest SDK (API version 19). Step three, start coding!

(http://developer.android.com/reference/android/nfc/cardemulation/HostApduService.html)

1.      Declare in the Manifest of your application that you want to create a HostApduService, and associate one or several AIDs,

2.      Implement the method processCommandApdu which receives the C-APDU from the reader – and has to return the R-APDU to be re-sent. The first C-APDU received is the SELECT AID that activated your application,

3.      Implement the method onDeactivated to perform the closing of the channel (reader lost, S-DESELECT reception, selection of another application).

JavaCard developers won’t be confused; the names are different but the overall mechanics are similar (except for the initial select).

Please note that processCommandApdu is called in the main thread of the application. If the answer isn’t immediately available (if it comes from a distant server or if a user input is needed, for example), the application logic has to return a “NULL”. In a second time the application will call the function sendResponseApdu to answer efficiently. In the meantime the OS and the NFC Chipset keep the reader waiting using S-WTX.

If you are interested in NFC applications, please check our NFC readers/encoders, H512 and NFC’Roll.

Firmware release 1.75 for H512 and NFC'Roll

A new firmware version (release 1.75.2) has just been published for SpringCard H512 and NFC'Roll.

This firmware improves the behaviour in card emulation and peer-to-peer (initiator) mode, allowing more reliable exchanges with most smartphones running either in reader or peer-to-peer (target) mode.

The same version will be released very soon for H663 and Prox'N'Roll PC/SC.

NFC'Roll

The new firmware is here: https://files.springcard.com/firmwares/springprox/1-75/2212_pn512_nfcroll-10_1-75.mot

The firmware upgrade procedure is here: https://tech.springcard.com/firmware-upgrade/csb6-firmware-upgrade/

H512

The new firmware is here: https://files.springcard.com/firmwares/springprox/1-75/uc3b0256_pn512_h512_1-75.hex

The firmware upgrade procedure is here: https://tech.springcard.com/firmware-upgrade/h663-h512-firmware-upgrade/

Using SCardControl under Linux and from a Java program

SCardControl is the PC/SC function that makes it possible for the application to invoke 'proprietary' functions, implemented either in the PC/SC reader itself (CSB6Prox’N'Roll PC/SCEasyFinger or CrazyWriter) , or in its driver running on the PC, or in the PC/SC middleware.

The prototype is:

LONG SCardControl(
  SCARDHANDLE hCard,
  DWORD dwControlCode,
  LPCVOID lpInBuffer,
  DWORD nInBufferSize,
  LPVOID lpOutBuffer,
  DWORD nOutBufferSize,
  LPDWORD lpBytesReturned
);

(see http://pcsclite.alioth.debian.org/api/group__API.html for the PCSC-Lite documentation, and http://msdn.microsoft.com/en-us/library/windows/desktop/aa379474%28v=vs.85%29.aspx for Microsoft's version).

The lpInbuffer / nInBufferSize parameters hold the command buffer that will be processed by either target -reader, driver, or PC/SC middleware-.

SpringCard PC/SC Readers do provide a few 'proprietary' functions (called 'Escape commands' in the USB CCID specification). For instance, an application would send the command 58 1E 01 00 to switch the reader's red LED ON. A question remains: what must the value of dwControlCode be, when the application wants to send the command right to the reader, bypassing both the PC/SC middleware and the driver? The answer varies with the operating system, which doesn't help implementing portable code.

Differences between Windows and PCSC-Lite implementations

Windows

In Microsoft's CCID driver (http://msdn.microsoft.com/en-us/library/windows/hardware/gg487509.aspx), the dwControlCode for the Escape command is defined as follows:

#define IOCTL_CCID_ESCAPE SCARD_CTL_CODE(3500)

SpringCard PC/SC Readers follow the CCID specification. SpringCard's CCID driver (SDD480) uses the same dwControlCode as Microsoft's.

Therefore, on Windows, the application would switch the red LED on this way:

#include <windows.h>
#include <winscard.h>

#define IOCTL_CCID_ESCAPE SCARD_CTL_CODE(3500)

(...)

const BYTE SET_RED_LED_ON[4] = { 0x58, 0x1E, 0x01, 0x00 };

SCARDCONTEXT hContext;
SCARDHANDLE hCard;
DWORD dwProtocol;
BYTE abResponse[256];
DWORD dwRespLen;
LONG rc;

(...)

/* Instanciate the winscard.dll library */
rc = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &amp;hContext);
if (rc != SCARD_S_SUCCESS) { /* TODO: handle error */ }

/* Get a direct connection to the reader (we don't need a card to send Escape commands) */
rc = SCardConnect(hContext, szReader, SCARD_SHARE_DIRECT, 0, &amp;hCard, &amp;dwProtocol);
if (rc != SCARD_S_SUCCESS) { /* TODO: handle error */ }

/* Send the command */
rc = SCardControl(hCard, IOCTL_CCID_ESCAPE, SET_RED_LED_ON, sizeof(SET_RED_LED_ON), abResponse, sizeof(abResponse), &amp;dwRespLen);
if (rc != SCARD_S_SUCCESS) { /* TODO: handle error */ }

SCardDisconnect(hCard, SCARD_LEAVE_CARD);
SCardReleaseContext(hContext);

 

Important notes:

Working with MS' CCID driver

With Microsoft's CCID driver, the Escape feature is disabled by default.

In order to send or receive an Escape command to a reader, the DWORD registry value EscapeCommandEnable must be added and set to a non-zero value under one of the following keys.

  • HKLM\SYSTEM\CCS\Enum\USB\Vid*Pid*\*\Device Parameters (prior to Windows 7).
  • HKLM\SYSTEM\CCS\Enum\USB\Vid*Pid*\*\Device Parameters\WUDFUsbccidDriver (Windows 7 and later).

This is clearly explained in the Developer's Manual for every PC/SC reader.

Using SpringCard's SDD480 CCID driver shall be preferred.

Early versions of SDD480

Branch -Ax of SpringCard's SDD480 CCID driver uses a different value for the dwControlCode parameter.

#define IOCTL_CCID_ESCAPE SCARD_CTL_CODE(2048)

Switching to the latest version of SpringCard's SDD480 CCID driver (branch -Bx and onwards) shall be preferred.

Linux, MacOS and other Unix*

In Ludovic Rousseau's open-source CCID driver (http://pcsclite.alioth.debian.org/ccid.html), the dwControlCode for the Escape command is defined as follows:

#define IOCTL_CCID_ESCAPE SCARD_CTL_CODE(1)

(See http://anonscm.debian.org/viewvc/pcsclite/trunk/Drivers/ccid/SCARDCONTOL.txt?view=markup for details)

Therefore, when working with PCSC-Lite, the application would switch the red LED on this way:

#ifdef __APPLE__
#include <pcsc/winscard.h>
#include <pcsc/wintypes.h>
#else
#include <winscard.h>
#endif

#define IOCTL_CCID_ESCAPE SCARD_CTL_CODE(1)

(...)

const BYTE SET_RED_LED_ON[4] = { 0x58, 0x1E, 0x01, 0x00 };

SCARDCONTEXT hContext;
SCARDHANDLE hCard;
DWORD dwProtocol;
BYTE abResponse[256];
DWORD dwRespLen;
LONG rc;

(...)

/* Instanciate the winscard.dll library */
rc = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
if (rc != SCARD_S_SUCCESS) { /* TODO: handle error */ }

/* Get a direct connection to the reader (we don't need a card to send Escape commands) */
rc = SCardConnect(hContext, szReader, SCARD_SHARE_DIRECT, 0, &hCard, &dwProtocol);
if (rc != SCARD_S_SUCCESS) { /* TODO: handle error */ }

/* Send the command */
rc = SCardControl(hCard, IOCTL_CCID_ESCAPE, SET_RED_LED_ON, sizeof(SET_RED_LED_ON), abResponse, sizeof(abResponse), &dwRespLen);
if (rc != SCARD_S_SUCCESS) { /* TODO: handle error */ }

SCardDisconnect(hCard, SCARD_LEAVE_CARD);
SCardReleaseContext(hContext);

Enabling the Escape commands

With this CCID driver, the Escape feature is also disabled by default.

You'll have to edit the CCID driver's Info.plist file to enable this feature:

  • Open /usr/local/lib/pcsc/drivers/ccid/Info.plist in edit mode with root priviledge,
  • Locate the line <key>ifdDriverOptions</key>,
  • The following line is typically <string>0000</string>,
  • Define the new value: <string>0001</string>,
  • Save the file and restard pcscd.

(More details on http://ludovicrousseau.blogspot.fr/2011/10/featureccidesccommand.html)

Writing portable code

The idea is only to use a #ifdef to compile the correct value:

#ifdef WIN32
#define IOCTL_CCID_ESCAPE SCARD_CTL_CODE(3500)
#else
#define IOCTL_CCID_ESCAPE SCARD_CTL_CODE(1)
#endif

Java

The javax.smartcardio API provides Java methods that are stricly bound to the underlying PC/SC subsystem. The Card.transmitControlCommand method is the wrapper for SCardControl. The prototype is coherent:

java decode:true">public abstract byte[] transmitControlCommand(
  int controlCode,
  byte[] command)
    throws CardException

Now the same question: what must the value of controlCode be? The answer is short: it depends on the PC/SC stack! SCARD_CTL_CODE(3500) for Windows, and SCARD_CTL_CODE(1) for PCSC-Lite. But with another difference: the macro SCARD_CTL_CODE is not computed the same way between both systems!

 

As a consequence, the Java application must detect the OS, and compute the controlCode parameter accordingly.

Same example to switch the red LED on:

java decode:true">import javax.smartcardio.*;

(...)

static boolean isWindows()
{
  String os_name = System.getProperty("os.name").toLowerCase();
  if (os_name.indexOf("windows") > -1) return true;
  return false;
}

static int SCARD_CTL_CODE(int code)
{
  int ioctl;
  if (isWindows())
  {
    ioctl = (0x31 < < 16 | (code) << 2);
  } else
  {
    ioctl = 0x42000000 + (code);
  }
  return ioctl;
}

static int IOCTL_CCID_ESCAPE()
{
  if (isWindows())
  {
    return SCARD_CTL_CODE(3500);
  } else
  {
    return SCARD_CTL_CODE(1);
  }
}

static final byte[] SET_RED_LED_ON = { (byte) 0x58, (byte) 0x1E, (byte) 0x01, (byte) 0x00 };

(...)

String readerName;

/* Note that the reader's name vary with the OS too!!! */
if (isWindows())
  readerName = "SpringCard Prox'N'Roll Contactless 0";
else
  readerName = "SpringCard Prox'N'Roll (00000000) 00 00";

CardTerminal terminal = CardTerminals.getTerminal(readerName);

Card virtualCard = terminal.connect("DIRECT");

virtualCard.transmitControlCommand(IOCTL_CCID_ESCAPE(), SET_RED_LED_ON);

virtualCard.disconnect(false);

Of course this code works only if the Escape feature is enable by the underlying CCID driver, as seen above.

SpringCard introduces new SDK for NFC-enabled PC/SC readers

It's now the final countdown before the launch of new SpringCard NFC products, H512 and NFC'Roll. Both products are not only able to read/write NFC Tags, but they also introduce NFC peer-to-peer communication and an innovative Card emulation mode.

The developers who already have an early release of either product, or who want to start evaluating the development process, are welcomed to download the first version of the SDK, which has been made available today, together with its documentation.

The NFC SDK for PC/SC includes
- NFcTool, a Tag read/write Utility,
- NFcBeam, implementing the NFC Forum 'Simple NDEF Exchange Protocol' (SNEP) on top of NFC Forum LLCP (Logical Link Control Protocol), itself on top of NFC-DEP, i.e. the NFCIP1 peer-to-peer layer (ISO 18092 chapter 12). A typical use-case would be to retrieve a contact entry (VCard) from an Android smartphone, or to push a SmartPoster from the PC to the smartphone,
- NfcTagEmul, showing how easy it is for either H512 or NFC'Roll to emulate a NFC Forum Tag (type 2 or type 4). This makes it possible to push a SmartPoster, URI, Text, VCard... from the PC to the smartphone, as smoothly as if the phone was reading a static Tag,
- and much more!

Edit 15/10/2013: starting with PC/SC SDK version 2.12, the NFC extensions are now included in the PC/SC SDK itself. Please read this article for details.

Those software are available with complete source (C# for .NET) in the SDK. Please download and read PMD2228: NFC SDK for PC/SC - Getting Started Guide for a guided tour and a few technical details.

Click here to download SpringCard NFC SDK for PC/SC

The reference manual for operating the readers from PC/SC applications is here: PMD2176: H512 (and NFC'Roll) Developer's Reference Manual.

An installer is also available (SQ2211: QuickStart for H512 and NFC'Roll) for people who want to try the products but don't need the full SDK.

Warning: a few changes have been on the specifications since the Alpha version of the firmware (1.6x branch). Products shall be updated to firmware v1.70 in order to be compliant with the final specifications, and to work with this SDK. Current 1.7x branch doesn't include peer-to-peer in Target mode (only Initiator mode is currently implemented). This will be added in 1.8x branch.

Retrieving the firmware version of your SpringCard PC/SC reader

In order to retrieve the firmware version of your SpringCard PC/SC reader (CSB6Prox’N’Roll PC/SCEasyFinger and CrazyWriter), you'll need the Springcard PC/SC Diagnostic Tool, available in our SDK (PcscDiag2.exe).

Once launched, the tool should display your smart card reader. In the following snapshots, the reader is a Prox’N’Roll PC/SC, but it would be same for other PC/SC readers (CSB6, CrazyWriter, CrazyWriter-HSP, CSB-HSP, H663, ...).

Right click on it, and choose Reader Info :

A pop-up window will then appear, indicating the firmware version (1-64 in this example):

Note: Instead of right clicking on the reader, you can also press Ctl+R to get the same information.

Print and encode simultaneously using SpringCard CrazyWriter and Evolis Zenius

Evolis Zenius is a color or monochrome card printer. Evolis offers SpringCard CrazyWriter PC/SC (ISO 14443, ISO 15693 + 2 SAM) as the contactless encoding option for Zenius -as well as for the other printers in its portfolio. Zenius plus CrazyWriter makes it easy to issue personalized cards on-the-field.

In this article we'll show how to synchronize the card encoding part (CrazyWriter PC/SC) with the card printing job using Evolis' SDK. Our sample project (C# source code available in the PC/SC SDK, under folder /samples/dotnet/ZeniusVCard) is a real-world example: we print a business card on a Desfire EV1 smartcard, and we store a vCard object into the Desfire, following NFC Forum standard known as 'NFC Forum Type 4 tag'. Doing so, the business card goes NFC and could be read by any compliant smartphone, that will automatically add the vCard data to its contact list! All you need to try the demo by yourself is a blank and virgin Desfire EV1 card, and, of course, an Evolis Zenius printer featuring SpringCard CrazyWriter.

In a nutshell

To print and encode a vCard, the process is as follows:

  1. Ask the printer to take one card in the feeder, and to put it in position for encoding (in front of the CrazyWriter's antenna),
  2. Recognize the card, format it if needed, write the data,
  3. Launch the print job,
  4. Optionnaly repeat the process, until there is no card left in the feeder.

The process always encodes a card before printing it. Doing so, should any problem append (not the expected type of card, card locked read-only...), the card is ejected immediately. No time nor ribbon has been waisted printing a useless card.

Architecture

There are two ways to communicate with an Evolis printer:

  • using the Windows spooler (as with any other printer),
  • using iomem.dll, a communication library supplied within Evolis' SDK.

Sending print jobs to the spooler is straightforward as all the steps of the printing are handled automatically by the system. Unfortunately, once the job is launched, the software has no way to know where the card actually is in the printer nor to stop it for a few seconds in front of the antenna..

On the other end, sending low level commands through iomem.dll offers a lot of flexibility, but lots of things have to be re-implemented in the printing software. This requires a specific expertise and can be time consuming.

So we'll take the best of the two worlds: iomem.dll will be used to drive the card in the printer until the CrazyWriter has done its job, and afterwards a print job will be sent to the spooler to actually print the card. We'll also have to use iomem.dll again to detect the end of the print job, so our software will not try to insert another card in the path until the previous card has been printed and ejected.

Step by step explanation of the sample project

Selecting the target printer and contactless coupler

The .NET PrintDialog object (System.Windows.Controls.PrintDialog) if the easiest way to select a printer. The name of the selected printer is returned in PrintDialog.PrinterSettings.PrinterName.

There's no immediate way to know which CrazyWriter (or in general which PC/SC reader) belongs to the selected printer. So we display our common 'Select PC/SC Reader' dialog to let the user find the reader. Default is to select the contactless interface of the first available CrazyWriter.

Controlling the printer through iomem.dll

First step is to gain access to iomem.dll's entry points from our C# application. The function used are:

  • OpenPebble
  • ClosePebble
  • ReadPebble
  • WritePebble
  • GetTimeout
  • SetTimeout


Please refer to Evolis' SDK for a detailed documentation of the DLL.

OpenPebble(PrinterName) gives use access to the printer, we then can use the couple WritePebble/ReadPebble to send arbitrary commands to the printer -and wait for its answer.

Here are the 3 only commands we need:

  • Rlr;h to check whether the feeder is empty,
  • Sic to load a card from the feeder, and to move it into position for encoding (in front of the CrazyWriter's antenna),
  • Se to eject the card (in case the encoding has failed).

If the encoding is successful, sending a print job to the spooler is enough to make the printer take the card from its current position (in front of the antenna), print it, and eject it.

To know whether the print job is terminated or still pending, we'll use a very simple trick: as the printer is not available to answer to iomem.dll commands while it is under control of the system's spooler, we'll send repeated dummy commands, and we'll know that the job is ended when we'll get an answer at last. The dummy command is:

  • Rfv read firmware version

Please also refer to Evolis' SDK for details regarding the printer's command set.

Encoding the vCard on the contactless card

This part is shared with the vCard part of NFCTool, another of our samples. The only difference is that NFCTool can also read cards, and implements a 'wake up on card arrival' scheme that doesn't have to be implemented in this sample. The card 'arrives' only after a successful invocation of the "Sic" control command.

We start by opening a PC/SC channel to the card: scard = new SCardChannel(ReaderName) (see the documentation of our PC/SC for .NET API for details).

Then we use the methods of our NfcTag object (NfcTag.IdentifyTagType, NfcTag.BackgroundRecognize) to check whether the card is a NFC Forum tag or not. It must be either already formatted (and offering enough memory space to store the vCard) or a Desfire EV1 that we know how to format and write. Note that BackgroundRecognize, as the name says, performs the recognition in a background thread and invoke a callback function once done. This is generally speaking a good practice to implement card-related stuff in a background thread so the application's window remains 'alive' even if the card takes its time to answer. At this step, the card is now for sure compliant with NFC Forum type 4 specification (or has been ejected if not, or if the user has chosen not to overwrite existing data).

Eventually, a new NfcVCard object is created, populated with the data entered by the user, and inserted as the content of the NfcTag objet. The the NfcTag.BackgroundWrite method is called, so the vCard content goes actually into the card. Once again this is done in a background thread.

Printing the layout on the card

At the end of the writing (that takes no more than one second anyway), the callback that is invoked launches the print job.

To print our business card, we process as follow:

  1. Create a PrintDocument object (System.Drawing.Printing.PrintDocument),
  2. Add to this PrintDocument object a PrintPageEventHandler function that will be invoked to actually draw the layout,
  3. Code the PrintPageEventHandler to implement the drawing of the business card from the data entered by the user,
  4. Invoke the PrintDocument.Print() method to send it to the spooler.

In this example, the PrintPageEventHandler is implemented in the FormatBusinnessCard function. The name and the title are printed in the middle of the card, respectively in Arial 16 and Arial 14; the contact information (business phone and e-mail) are in the down-left corner in Arial 10; the picture is printed in the up-right corner; etc... Of course this is the first thing you'll have to change to design your cards according your own layout.

Waiting for the end of the job

Once PrintDocument.Print() has been called, there's nothing else to do but wait. The spooler works in background, so the application is free to do anything else, but we can't start encoding another card until the current one has been printed and ejected. Therefore we implement a waiting loop, sending the "Rfv" command through iomem.dll repeatedly. Once the printer responds, we know that the job is over. We could then loop to go on with the next card.

PC/SC driver updated

We've just published a new release of our WHQL-certified driver for SpringCard PC/SC products. This new version (code name: SDD480-BB) fixes a few bugs that have been experienced with the earlier release:
- corrected a memory leakage that used to occur as a consequence of frequent SCardControl calls
- CSB6 now reports correctly "card mute" when a card is physically inserted but unresponsive
- improved overall stability on multi-slot readers thanks to a stricter synchronization of SCardTransmit calls

To download the driver, please go to http://www.springcard.com/download/find.php?file=sdd480. The installer now contains both x86 and x64 binaries, and select automatically the one adapted to your system. It will also be available through Windows Update in a few days.

As the previous one, this release targets all SpringCard USB CCID readers :
- CSB6
- CrazyWriter
- EasyFinger
- Prox'N'Roll PC/SC

Users are welcome to deploy this new release as soon as possible.