Sunday, September 06, 2009

Linux Termios

I have been writing TCT smartcard reader module, using communication protocol that shipped with the reader, the reader actually provide API for Linux, the API is good, but not so good. It's closed code means we can't do more hacks. One thing that was a big issue which force me to write the module is API's ability to determine timeout I/O operation. For example, we send command to the reader, but let say the reader power has fail or something error occurred then the API will wait and block for uncertain of times because there are no respond from the reader.

Then i write the module from scratch, i got some weird problems, the reader will not reply for certain type of byte (character), 0xD (CR), 0xA (NL), 0x11 and 0x13. This problem has made me crazy and temporary ask me to use simple ASCII protocol. The termios structure contains input/output flags that determine serial communication characteristic.

By default (and at least i solve this problem, thanks you all), Linux serial API perform CR to NL and NL to CR for both input and output, so when i write a CR, it was actually converted to NL and vice versa, this translation also inherited for output. To remove this setting, do bit operation with control setting as follow:

struct termios opt;
/* open device and read current setting */
opt.c_iflag &= ~(INLCR | INCRNL);
opt.c_oflag &= ~(ONLCR | ONCRNL);

Now the CR-NL and NL-CR translation has been resolved, what now? i got another headaches, the same problem with character 0x11 and 0x13 on input, after do some man tcsetattr i see Linux also interpreting this as a special character, the XON/XOFF option flag has been enable by default, it's serial line hardware flow control, so i disable this in input control setting:

opt.c_iflag &= ~(IXON | IXOFF);

...and everything is fine, there are no unresponsive actions by the reader caused by invalid data sequence, hey.. i just beginner serial communication programmer, and thanks to the ACR-120 reader, thanks for let me know this issues.