SmartCard reader. PC is interface through USB or TCPport. SmartCard is interfaced through UART@ 1MHz, DIV372

Dependencies:   EthernetNetIf mbed

Files at this revision

API Documentation at this revision

Comitter:
bcalin1984
Date:
Sun Feb 27 22:20:40 2011 +0000
Commit message:

Changed in this revision

EthernetNetIf.lib Show annotated file Show diff for this revision Revisions of this file
SmartCardReader.cpp Show annotated file Show diff for this revision Revisions of this file
SmartCardReader.h Show annotated file Show diff for this revision Revisions of this file
TcpServer.cpp Show annotated file Show diff for this revision Revisions of this file
TcpServer.h Show annotated file Show diff for this revision Revisions of this file
commons.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EthernetNetIf.lib	Sun Feb 27 22:20:40 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mamezu/code/EthernetNetIf/#0f6c82fcde82
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartCardReader.cpp	Sun Feb 27 22:20:40 2011 +0000
@@ -0,0 +1,130 @@
+/*
+This file encapsulates logic for SmartCard Reader
+
+Author: Calin Bira
+Date: 28.02.2011
+*/
+
+#include "SmartCardReader.h"
+
+SmartCardReader::SmartCardReader(Serial *_dut, DigitalOut *_vcc, DigitalOut *_rst,PwmOut *_clock, char *_format)
+    {
+        int databits,stopbits;
+        Serial::Parity parity;
+        
+        freq = 1000*1000;
+        divfact = 372;
+                
+        dut = _dut;
+        rst = _rst;
+        vcc = _vcc;
+        clk = _clock;
+        
+        BytesToIgnore = 0;
+        ReceiveBufferIndex = 0;
+                
+        databits = _format[0] - '0';
+        switch (_format[1])
+        {
+            case 'E': {parity = Serial::Even; break;}
+            case 'O': {parity = Serial::Odd; break;}
+            default: {parity = Serial::None; break;}
+        }
+        
+        stopbits = _format[2] - '0';
+        dut->format(databits,parity,stopbits);
+        
+        setClock(freq);
+        clk->write(0.5);// 50% duty cycle
+        
+        
+    }
+    
+void SmartCardReader::setClock(int Hz)
+    {
+        freq = Hz;
+        clk->period_us(1000*1000/freq);
+        dut->baud(freq/divfact);
+    }
+
+void SmartCardReader::cold_reset()
+    {
+        *vcc = 0;
+        *rst = 0;
+        wait(0.1);
+        *vcc = 1;
+        wait(0.1);
+        
+        while (dut->readable())
+            dut->getc();
+        *rst = 1;
+    }
+    
+void SmartCardReader::warm_reset()
+    {
+        *rst = 0;
+        wait(0.1);
+        *rst = 1;
+    }
+
+/*    
+void SmartCardReader::Relay_PC_SC()
+        {
+            static char ignore=0;
+            
+            while (dut->readable()) //if there is data from smartcard
+            {
+                if (ignore>0)
+                {
+                    dut->getc();//ignore data: this is data from pc
+                    ignore--;
+                }
+                else pc->putc(dut->getc());//send to pc
+            }
+            
+            while (pc->readable()) //if there is data from pc
+            {
+                ignore++;
+                dut->putc(pc->getc());  //send data to smartcard
+            }    
+        }
+*/
+void SmartCardReader::send(char *buf, int len)
+{
+    while(len-- >0)
+    {
+        BytesToIgnore++;
+        dut->putc(*buf++);
+    }
+}
+
+int SmartCardReader::receive(char *buf)
+{
+    int OldIndex = ReceiveBufferIndex;
+    for (int i=0; i < ReceiveBufferIndex; i++)
+    {
+        buf[i] =  ReceiveBuffer[i];
+    }
+    ReceiveBufferIndex = 0;
+    return OldIndex;
+}
+
+void SmartCardReader::doEvents()
+    {
+        //Relay_PC_SC();
+          
+            while (dut->readable()) //if there is data from smartcard
+            {
+                if (BytesToIgnore > 0)
+                {
+                    dut->getc();//ignore data: this is data from previous send
+                    BytesToIgnore--;
+                }
+                else 
+                {
+                    if (ReceiveBufferIndex < ReceiveBufferLen)
+                        ReceiveBuffer[ReceiveBufferIndex++] = dut->getc();
+                    else dut->getc();//discard data, no space in buffer
+                }
+            }  
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmartCardReader.h	Sun Feb 27 22:20:40 2011 +0000
@@ -0,0 +1,43 @@
+#include "mbed.h"
+class SmartCardReader
+{
+    int freq;
+    int divfact;
+    char format[4];
+    int BytesToIgnore;
+    
+    #define ReceiveBufferLen 1024
+    char ReceiveBuffer[ReceiveBufferLen];
+    int ReceiveBufferIndex;
+    
+    //void (*onReceiveFromDut)(char* buf, int len);
+    Timer tim;
+    
+    Serial *dut;
+    DigitalOut *rst;
+    DigitalOut *vcc;
+    PwmOut *clk;
+
+    public: 
+    SmartCardReader(Serial *_dut, DigitalOut *_vcc, DigitalOut *_rst,PwmOut *_clock, char *_format);
+    void setClock(int Hz);
+    void cold_reset();
+    void warm_reset();
+    void doEvents();
+    
+    void send(char *buf, int len);
+    int receive(char *buf);
+    
+    /*
+    void SetReceivePcCallback(void (*f)(char*buf, int len))
+    {
+        onReceiveFromDut = f;
+    }*/
+    
+    private : 
+    void Relay_PC_SC();
+    
+};
+    
+  
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TcpServer.cpp	Sun Feb 27 22:20:40 2011 +0000
@@ -0,0 +1,190 @@
+/*
+A Tcp server based on the :
+// TCP Echo server
+// 2010/9/7
+
+Modified by Calin Bira
+Date: 28.02.2011
+*/
+
+
+
+
+#include "mbed.h"
+#include "TcpServer.h"
+#include <stdarg.h>
+
+//#define DEBUG
+
+#ifdef DEBUG
+    #define dprintf printf
+#else 
+    #define dprintf noprintf
+#endif
+    TcpServer::TcpServer(int port)
+    {
+        Setup(port);
+    }
+    
+    void TcpServer::onConnectedTCPSocketEvent(TCPSocketEvent e)
+    {
+       switch(e)
+        {
+        case TCPSOCKET_CONNECTED:
+            dprintf("TCP Socket Connected\r\n");
+            break;
+        case TCPSOCKET_WRITEABLE:
+          //Can now write some data...
+            dprintf("TCP Socket Writable\r\n");
+            break;
+        case TCPSOCKET_READABLE:
+          //Can now read dome data...
+            dprintf("TCP Socket Readable\r\n");
+           // Read in any available data into the buffer
+           
+           while ( int len = pConnectedSock->recv(buff, 256) ) 
+           {
+               onReceive(buff,len);
+               //pConnectedSock->send(buff, len);
+               //buff[len]=0; // make terminater
+               //dprintf("Received&Wrote:%s\r\n",buff);
+           }
+           break;
+        case TCPSOCKET_CONTIMEOUT:
+            dprintf("TCP Socket Timeout\r\n");
+            break;
+        case TCPSOCKET_CONRST:
+            dprintf("TCP Socket CONRST\r\n");
+            break;
+        case TCPSOCKET_CONABRT:
+            dprintf("TCP Socket CONABRT\r\n");
+            break;
+        case TCPSOCKET_ERROR:
+            dprintf("TCP Socket Error\r\n");
+            break;
+        case TCPSOCKET_DISCONNECTED:
+        //Close socket...
+            dprintf("TCP Socket Disconnected\r\n");        
+            pConnectedSock->close();
+            break;
+        default:
+            dprintf("DEFAULT\r\n"); 
+          }
+    }
+    
+    
+    void TcpServer::onListeningTCPSocketEvent(TCPSocketEvent e)
+    {
+        switch(e)
+        {
+        case TCPSOCKET_ACCEPT:
+        {
+            dprintf("Listening: TCP Socket Accepted\r\n");
+            // Accepts connection from client and gets connected socket.   
+            err=ListeningSock.accept(&client, &pConnectedSock);
+            if (err) {
+                dprintf("onListeningTcpSocketEvent : Could not accept connection.\r\n");
+                return; //Error in accept, discard connection
+            }
+            // Setup the new socket events
+            pConnectedSock->setOnEvent(this, &TcpServer::onConnectedTCPSocketEvent);
+            // We can find out from where the connection is coming by looking at the
+            // Host parameter of the accept() method
+            IpAddr clientIp = client.getIp();
+            dprintf("Listening: Incoming TCP connection from %d.%d.%d.%d\r\n", 
+               clientIp[0], clientIp[1], clientIp[2], clientIp[3]);
+           break;
+        }
+        // the following cases will not happen
+        case TCPSOCKET_CONNECTED:
+            dprintf("Listening: TCP Socket Connected\r\n");
+            break;
+        case TCPSOCKET_WRITEABLE:
+            dprintf("Listening: TCP Socket Writable\r\n");
+            break;
+        case TCPSOCKET_READABLE:
+            dprintf("Listening: TCP Socket Readable\r\n");
+            break;
+        case TCPSOCKET_CONTIMEOUT:
+            dprintf("Listening: TCP Socket Timeout\r\n");
+            break;
+        case TCPSOCKET_CONRST:
+            dprintf("Listening: TCP Socket CONRST\r\n");
+            break;
+        case TCPSOCKET_CONABRT:
+            dprintf("Listening: TCP Socket CONABRT\r\n");
+            break;
+        case TCPSOCKET_ERROR:
+            dprintf("Listening: TCP Socket Error\r\n");
+            break;
+        case TCPSOCKET_DISCONNECTED:
+        //Close socket...
+            dprintf("Listening: TCP Socket Disconnected\r\n");        
+            ListeningSock.close();
+            break;
+        default:
+            dprintf("DEFAULT\r\n"); 
+         };
+    }
+    
+    int TcpServer::Setup(int port) {
+      dprintf("\r\n");
+      dprintf("Setting up...\r\n");
+      EthernetErr ethErr = eth.setup();
+      if(ethErr)
+      {
+        dprintf("Error %d in setup.\r\n", ethErr);
+        return -1;
+      }
+      dprintf("Setup OK\r\n");
+    
+      IpAddr ip = eth.getIp();
+      dprintf("mbed IP Address is %d.%d.%d.%d\r\n", ip[0], ip[1], ip[2], ip[3]);
+    
+      
+      // Set the callbacks for Listening
+      ListeningSock.setOnEvent(this,&TcpServer::onListeningTCPSocketEvent); 
+      
+      // bind and listen on TCP
+      err=ListeningSock.bind(Host(IpAddr(), port));
+      dprintf("Binding..\r\n");
+      if(err)
+      {
+       //Deal with that error...
+        dprintf("Binding Error\n");
+      }
+       err=ListeningSock.listen(); // Starts listening
+       dprintf("Listening...\r\n");
+       if(err)
+       {
+        dprintf("Listening Error\r\n");
+       }
+       return 0;
+    }
+    
+    void TcpServer::doEvents()
+    {
+        Net::poll();
+    }
+    
+     void TcpServer::SetReceiveCallback(void (*f)(char*buf, int len))
+    {
+        onReceive = f;
+    }
+    
+    
+    void TcpServer::Tprintf(const char * format, ...)
+    {
+     	va_list ap;
+        va_start(ap, format);
+        vsprintf(buff, format, ap);
+        va_end(ap);
+    
+        pConnectedSock->send(buff, strlen(buff));
+    }
+    
+     void TcpServer::noprintf(const char * format, ...)
+    {
+     
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TcpServer.h	Sun Feb 27 22:20:40 2011 +0000
@@ -0,0 +1,33 @@
+#include "EthernetNetIf.h"
+#include "TCPSocket.h"
+    
+    class TcpServer
+    {
+        EthernetNetIf eth;
+        /*
+        EthernetNetIf eth(
+          IpAddr(192,168,0,25), //IP Address
+          IpAddr(255,255,255,0), //Network Mask
+          IpAddr(192,168,0,1), //Gateway
+          IpAddr(192,168,0,1)  //DNS
+        );*/
+        
+        
+        TCPSocket ListeningSock;
+        TCPSocket* pConnectedSock; // for ConnectedSock
+        Host client;
+        TCPSocketErr err;
+        char buff[256];
+        
+        void (*onReceive)(char* buf, int len);
+        int Setup(int port);
+        void onConnectedTCPSocketEvent(TCPSocketEvent e);
+        void onListeningTCPSocketEvent(TCPSocketEvent e);
+        
+        void noprintf(const char * format, ...);
+       public:
+        TcpServer(int port);
+        static void doEvents();
+        void Tprintf(const char * format, ...); 
+        void SetReceiveCallback(void (*f)(char*buf, int len));
+   };
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commons.h	Sun Feb 27 22:20:40 2011 +0000
@@ -0,0 +1,1 @@
+#define MAX_MSG_SIZE 256
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Feb 27 22:20:40 2011 +0000
@@ -0,0 +1,154 @@
+/*
+Main file: encapsulates the glue that links USB-serial or TCP port to the SmartCardReader
+
+Author: Calin Bira
+Date: 28.02.2011
+*/
+
+#include "mbed.h"
+#include "SmartCardReader.h"
+#include <string.h>
+#include "commons.h"
+#include "TcpServer.h"
+
+Serial computer(USBTX, USBRX); // tx, rx
+Serial smartcard(p13, p14); // tx, rx
+DigitalOut reset(p20);
+DigitalOut vcc(p18);
+PwmOut clk(p21);//clock line
+
+TcpServer TCPS(10779);
+#define SendToHost(x,y) \
+    computer.printf(x,y);\
+    TCPS.Tprintf(x,y)
+
+SmartCardReader SCR(&smartcard, &vcc, &reset, &clk, "8E1");
+
+static const int CommandBufferLen = 2*MAX_MSG_SIZE + 20;//two bytes per char, and extra 20 Bytes for other params
+static const int AnswerBufferLen = 2*MAX_MSG_SIZE + 20;//two bytes per char, and extra 20 Bytes for other params
+static char CommandBuffer[CommandBufferLen];
+static int CommandBufferIndex;
+static char AnswerBuffer[AnswerBufferLen];
+static char tmp[MAX_MSG_SIZE];
+
+#define CMD_ERR_INVALID_FORMAT  0x0001
+#define CMD_ERR_OK              0x0000
+#define CMD_ERR_RECEIVE_TIMEOUT 0x00CA
+
+void DecodeCommand(char* cmd, int len)
+{
+    int errorCode = CMD_ERR_OK;
+    char * pch;
+    pch = strtok (cmd," ");
+    
+    if (len < 6)
+    {
+        errorCode = CMD_ERR_INVALID_FORMAT;
+        SendToHost("ERR %04x\r\n",errorCode);
+    }
+    else if (strncmp(pch,"ISCR",4)==0)
+    {
+        SCR.cold_reset();
+        SendToHost("ISCR %04X\r\n",errorCode);
+    }
+    else if (strncmp(pch,"ISWR",4)==0)
+    {
+        SCR.warm_reset();
+        SendToHost("ISWR %04X\r\n",errorCode);
+    }
+    else if (strncmp(pch,"ISSB",4)==0)
+    {
+        pch = strtok (NULL, " ");//size
+        if (pch == NULL) {errorCode = CMD_ERR_INVALID_FORMAT; SendToHost("ERR %04X\r\n",errorCode); return;}
+        
+        int len = atoi(pch);
+        int len_copy = len;
+        pch = strtok (NULL, " ");//the other chars
+        if (pch == NULL) {errorCode = CMD_ERR_INVALID_FORMAT;SendToHost("ERR %04X\r\n",errorCode); return;}
+        
+        char *src = tmp;
+        while (len > 0)
+        {
+            sscanf(pch, "%2x", src++);
+            pch += 2;
+            len--;
+        }
+        
+        SCR.send(tmp,len_copy);
+        SendToHost("ISSB %04X\r\n",errorCode);
+    }
+    else if (strncmp(pch,"ISRB",4)==0)
+    {
+        char *dest;
+        char *src = tmp;
+        pch = strtok (NULL, " ");
+        int expectedLen = atoi(pch);
+        int len = SCR.receive(tmp);
+        if (expectedLen > len) errorCode = CMD_ERR_RECEIVE_TIMEOUT;
+        
+        sprintf(AnswerBuffer,"ISRB %04X %d ",errorCode,len);
+        dest = AnswerBuffer + strlen(AnswerBuffer);
+        while (len > 0)
+        {
+            sprintf(dest,"%02X",*src);
+            src++;dest+=2;len--;
+        }
+        *dest++ = '\r';        
+        *dest++ = '\n';
+        *dest++ = '\0';
+        
+        SendToHost("%s",AnswerBuffer);
+    }
+    
+    while (pch !=NULL)
+    {
+        pch = strtok (NULL, " ");
+    }
+}
+
+void AssembleCommand(char *buf, int len)
+{
+    for (int i=0; i<len; i++)
+    {
+       if (CommandBufferIndex < CommandBufferLen)
+       {
+        CommandBuffer[CommandBufferIndex] = buf[i];
+        if (CommandBuffer[CommandBufferIndex] == 10)
+           {
+                DecodeCommand(CommandBuffer, CommandBufferIndex);
+                CommandBufferIndex = 0;
+           }
+           else CommandBufferIndex++;
+       }
+       else 
+       {
+            CommandBufferIndex = 0;
+       }
+       
+    }
+    
+    
+    
+}
+
+
+//TcpServer TCPS(10779);
+int main() 
+{
+    char ch;
+    SCR.cold_reset();
+    TCPS.SetReceiveCallback(&AssembleCommand);
+    CommandBufferIndex = 0;
+    
+    while(1) 
+    {
+        while (computer.readable()) //if there is data from pc
+        {
+            ch = computer.getc();
+            AssembleCommand(&ch,1);
+        }  
+        
+        SCR.doEvents();      
+        TCPS.doEvents();
+    } 
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun Feb 27 22:20:40 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/63bcd7ba4912