Changeset 1012

Show
Ignore:
Timestamp:
01/10/08 09:35:21 (11 months ago)
Author:
ludovic.rousseau
Message:

new patch for ruToken support from Andrew V. Stepanov

http://www.opensc-project.org/pipermail/opensc-devel/2008-January/010648.html

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/ifd/ifd-rutoken.c

    r1010 r1012  
    33 * 
    44 * Copyright (C) 2007, Pavel Mironchik <rutoken@rutoken.ru> 
    5  * Copyright (C) 2007, Eugene Hermann <e_herman@tut.by> 
     5 * Copyright (C) 2007, Eugene Hermann <e_herman@rutoken.ru> 
    66 */ 
    77 
     8#include <unistd.h> 
     9#include <string.h> 
    810#include "internal.h" 
    9 #include "stdio.h" 
    10 #include "unistd.h" 
    11 #include "string.h" 
    1211 
    1312#define MAX_BUF_T0_LEN  256 
    1413#define T0_HDR_LEN      5 
    15  
    1614 
    1715#define USB_ICC_POWER_ON        0x62 
     
    3230{ 
    3331        ifd_device_t *dev; 
     32        ifd_device_params_t params; 
     33 
    3434        ifd_debug(1, "rutoken_open - %s\n", device_name); 
    3535        ifd_debug(1, "%s:%d rutoken_open()", __FILE__, __LINE__); 
    3636 
    37         reader->name = "ruToken driver.\n"; 
     37        reader->name = "ruToken driver"; 
    3838        reader->nslots = 1; 
    3939        if (!(dev = ifd_device_open(device_name))) 
     
    4646        } 
    4747 
     48        params = dev->settings; 
     49        params.usb.interface = 0; 
     50        if (ifd_device_set_parameters(dev, &params) < 0) { 
     51                ct_error("ruToken driver: setting parameters failed", device_name); 
     52                ifd_device_close(dev); 
     53                return -1; 
     54        } 
     55 
    4856        reader->device = dev; 
    4957        dev->timeout = 1000; 
     
    6573} 
    6674 
    67 // Get Status 0 - OK 
    68 //              - ERROR 
    69 // 
    70 int rutoken_getstatus(ifd_reader_t * reader, char *status) 
    71 { 
    72         // TODO Chech for timeout 
     75static int rutoken_getstatus(ifd_reader_t * reader, unsigned char *status) 
     76{ 
    7377        //ifd_debug(1, ""); 
    74         if(!ifd_usb_control(reader->device, 0xc1, USB_ICC_GET_STATUS, 0, 0, status, 1, 1000) < 0 ) 
     78        if(ifd_usb_control(reader->device, 0xc1, USB_ICC_GET_STATUS,  
     79                                0, 0, status, 1, 1000) < 0 ) 
    7580                return -1; 
    7681        if((*status & 0xF0) == ICC_STATUS_BUSY_COMMON){ 
     82                unsigned char prev_status; 
    7783                int i; 
    78                 for(i = 0; i < 100000; i++) { 
    79                         if(!ifd_usb_control(reader->device, 0xc1, USB_ICC_GET_STATUS, 0, 0, status, 1, 1000) < 0 ) 
     84                for(i = 0; i < 200; i++) { // 2 s  (200 * 10 ms) 
     85                        do { 
     86                                usleep(10000); // 10 ms 
     87                                prev_status = *status; 
     88                                if(ifd_usb_control(reader->device, 0xc1,  
     89                                                        USB_ICC_GET_STATUS, 0, 0,  
     90                                                        status, 1, 1000) < 0 
     91                                ) 
    8092                                return -1; 
    8193                        if((*status & 0xF0) != ICC_STATUS_BUSY_COMMON) 
    82                                 return 0; 
    83                         usleep(1000); 
     94                                        return *status; 
     95                        } while((((prev_status & 0x0F) + 1) & 0x0F) == (*status & 0x0F)); 
    8496                } 
    8597                return -1; 
     
    100112                return -1; 
    101113        } 
    102         char status; 
     114        unsigned char status; 
    103115        if( rutoken_getstatus(reader, &status) < 0) 
    104116        { 
     
    110122                memset(buf, 0, OUR_ATR_LEN); 
    111123 
    112                 nLen = ifd_usb_control(reader->device, 0xc1, USB_ICC_POWER_ON, 0, 0, buf, OUR_ATR_LEN, 1000); 
     124                nLen = ifd_usb_control(reader->device, 0xc1, USB_ICC_POWER_ON, 0, 0,  
     125                                buf, OUR_ATR_LEN, 1000); 
    113126                if( nLen < 0 ) 
    114127                { 
     
    175188{ 
    176189        int ret; 
    177         char status; 
     190        unsigned char status; 
    178191        ifd_debug(3, "usb send %s len %d", ct_hexdump(buffer, len), len); 
    179         ret =  ifd_usb_control(reader->device, 0x41, USB_ICC_XFR_BLOCK, 0, 0, (void *)buffer, len, -1); 
     192        ret = ifd_usb_control(reader->device, 0x41, USB_ICC_XFR_BLOCK, 0, 0,  
     193                        (void *)buffer, len, -1); 
    180194 
    181195        if (rutoken_getstatus(reader, &status) < 0) 
     
    190204                unsigned char *buffer, size_t len, long timeout) 
    191205{ 
    192         char status; 
     206        unsigned char status; 
    193207        int ret = len; 
    194208        // USB_ICC_DATA_BLOCK 
    195         if( (ret = ifd_usb_control(reader->device, 0xc1, USB_ICC_DATA_BLOCK, 0, 0, buffer, len, timeout)) >= 0) 
     209        if( (ret = ifd_usb_control(reader->device, 0xc1, USB_ICC_DATA_BLOCK, 0, 0,  
     210                                        buffer, len, timeout)) >= 0) 
    196211                if (rutoken_getstatus(reader, &status) < 0) 
    197212                { 
     
    225240// sbuf - APDU bufer 
    226241// slen 
    227 static int rutoken_send_tpducomand(ifd_reader_t * reader, int dad, const void *sbuf, size_t slen, void *rbuf, size_t rlen, int iscase4) 
     242static int rutoken_send_tpducomand(ifd_reader_t * reader, int dad, const void *sbuf,  
     243                size_t slen, void *rbuf, size_t rlen, int iscase4) 
    228244{ 
    229245        ifd_debug(1, "send tpdu command %s, len: %d", ct_hexdump(sbuf, slen), slen); 
     
    278294                                if (rrecv < 0) 
    279295                                        return -2; 
    280                                 ifd_debug(1, "Get TPDU Anser %s", ct_hexdump(rbuf, iso.le)); 
     296                                ifd_debug(1, "Get TPDU Anser %s",  
     297                                                ct_hexdump(rbuf, iso.le)); 
    281298                        } 
    282299                        if (rutoken_recv_sw(reader, 0, sw) < 0) 
     
    290307                                memcpy(sbuftmp, sbuf, slen); 
    291308                                sbuftmp[4] = sw[1]; 
    292                                 return rutoken_send_tpducomand(reader, dad, sbuftmp, slen, rbuf,  rlen, 0); 
    293                         } 
    294  
     309                                return rutoken_send_tpducomand(reader, dad, sbuftmp,  
     310                                                slen, rbuf,  rlen, 0); 
     311                        } 
    295312                        break; 
    296313                case    IFD_APDU_CASE_3S: 
     
    299316                        if(rutoken_getstatus(reader, &status) == ICC_STATUS_READY_DATA) 
    300317                        { 
    301                                 ifd_debug(1, "Send TPDU Data %s", ct_hexdump(iso.data, iso.lc)); 
    302                                 if (rutoken_send(reader, 0, iso.data, iso.lc) < 0) return -4; 
     318                                ifd_debug(1, "Send TPDU Data %s",  
     319                                                ct_hexdump(iso.data, iso.lc)); 
     320                                if (rutoken_send(reader, 0, iso.data, iso.lc) < 0) 
     321                                        return -4; 
    303322                        } else return -3; 
    304323                        // get sw 
     
    315334                                hdr[4] = lx ; //lx (case 2) 
    316335                                if(iscase4) 
    317                                         return rutoken_send_tpducomand(reader, dad, hdr, T0_HDR_LEN, rbuf, rlen, 0); 
     336                                        return rutoken_send_tpducomand(reader, dad, hdr,  
     337                                                        T0_HDR_LEN, rbuf, rlen, 0); 
    318338                                else { 
    319                                         int recvtmp = rutoken_send_tpducomand(reader, dad, hdr, T0_HDR_LEN, rbuf, rlen, 0); 
     339                                        int recvtmp = rutoken_send_tpducomand(reader,dad, 
     340                                                        hdr, T0_HDR_LEN, rbuf, rlen, 0); 
    320341                                        rrecv = 0; 
    321                                         memcpy(sw, rbuf+recvtmp-2, 2); 
     342                                        memcpy(sw, (unsigned char*)rbuf+recvtmp-2, 2); 
    322343                                        break; 
    323344                                } 
     
    332353                                hdr[4] = iso.le; // le (case 2) 
    333354                                if(iscase4) 
    334                                         return rutoken_send_tpducomand(reader, dad, hdr, T0_HDR_LEN, rbuf, rlen, 0); 
     355                                        return rutoken_send_tpducomand(reader, dad, hdr,  
     356                                                        T0_HDR_LEN, rbuf, rlen, 0); 
    335357                        } 
    336358                        // NOT STANDART TPDU!!! END 
     
    345367        ifd_debug(1, "Recv %d bytes", rrecv); 
    346368        return rrecv; 
    347  
    348 } 
    349  
     369} 
    350370 
    351371static int rutoken_transparent( ifd_reader_t * reader, int dad, 
     
    363383                case    IFD_APDU_CASE_2S: 
    364384                case    IFD_APDU_CASE_3S: 
    365                         return rutoken_send_tpducomand(reader, dad, sbuf, slen, rbuf, rlen, 0); 
     385                        return rutoken_send_tpducomand(reader, dad, sbuf, slen,  
     386                                        rbuf, rlen, 0); 
    366387                        break; 
    367388                case    IFD_APDU_CASE_4S: 
    368389                        // make send case 4 command 
    369                         rrecv = rutoken_send_tpducomand(reader, dad, sbuf, slen-1, rbuf, rlen, 1); 
     390                        rrecv = rutoken_send_tpducomand(reader, dad, sbuf, slen-1,  
     391                                        rbuf, rlen, 1); 
    370392                        return rrecv; 
    371393                        break; 
     
    391413        ifd_driver_register("rutoken", &rutoken_driver); 
    392414} 
     415