static int32_t Cool_Transmit(struct s_reader *reader, unsigned char *sent, uint32_t size, uint32_t expectedlen, uint32_t UNUSED(delay), uint32_t UNUSED(timeout)) { struct cool_data *crdr_data = reader->crdr_data; int32_t ret; memset(crdr_data->cardbuffer, 0, 512); if(reader->protocol_type == ATR_PROTOCOL_TYPE_T0) { crdr_data->cardbuflen = expectedlen; ret = cnxt_smc_read_write(crdr_data->handle, 0, sent, size, crdr_data->cardbuffer, &crdr_data->cardbuflen, 0, NULL); } else { crdr_data->cardbuflen = 512; ret = cnxt_smc_read_write(crdr_data->handle, 0, sent, size, crdr_data->cardbuffer, &crdr_data->cardbuflen, 4000, NULL); } coolapi_check_error("cnxt_smc_read_write", ret); rdr_ddump_mask(reader, D_DEVICE, sent, size, "COOL Transmit:"); if(ret) { return ERROR; } return OK; }
int32_t reader_cmd2icc(struct s_reader * reader, const uchar *buf, const int32_t l, uchar * cta_res, uint16_t * p_cta_lr) { int32_t rc; *p_cta_lr=CTA_RES_LEN-1; //FIXME not sure whether this one is necessary rdr_ddump_mask(reader, D_READER, buf, l, "write to cardreader"); rc=ICC_Async_CardWrite(reader, (uchar *)buf, (uint16_t)l, cta_res, p_cta_lr); return rc; }
static int32_t Cool_Receive (struct s_reader *reader, unsigned char * data, uint32_t size, uint32_t UNUSED(delay), uint32_t UNUSED(timeout)) { if (size > specdev()->cardbuflen) size = specdev()->cardbuflen; //never read past end of buffer memcpy(data, specdev()->cardbuffer, size); specdev()->cardbuflen -= size; memmove(specdev()->cardbuffer, specdev()->cardbuffer+size, specdev()->cardbuflen); rdr_ddump_mask(reader, D_DEVICE, data, size, "COOL Receive:"); return OK; }
int32_t Cool_Receive (struct s_reader *reader, BYTE * data, uint32_t size) { if (size > specdev()->cardbuflen) size = specdev()->cardbuflen; //never read past end of buffer memcpy(data, specdev()->cardbuffer, size); specdev()->cardbuflen -= size; memmove(specdev()->cardbuffer, specdev()->cardbuffer+size, specdev()->cardbuflen); rdr_ddump_mask(reader, D_DEVICE, data, size, "COOL Receive:"); return OK; }
int32_t Cool_Transmit (struct s_reader *reader, BYTE * sent, uint32_t size) { specdev()->cardbuflen = 256;//it needs to know max buffer size to respond? int32_t ret = cnxt_smc_read_write(specdev()->handle, FALSE, sent, size, specdev()->cardbuffer, &specdev()->cardbuflen, specdev()->read_write_transmit_timeout, 0); coolapi_check_error("cnxt_smc_read_write", ret); rdr_ddump_mask(reader, D_DEVICE, sent, size, "COOL Transmit:"); return OK; }
bool IO_Serial_Write (struct s_reader * reader, uint32_t delay, uint32_t timeout, uint32_t size, const unsigned char * data) { if (timeout == 0){ // General fix for readers not communicating timeout and delay if (reader->char_delay != 0) timeout = reader->char_delay; else timeout = 1000000; rdr_debug_mask(reader, D_DEVICE,"Warning: write timeout 0 changed to %d us", timeout); } uint32_t count, to_send, i_w; unsigned char data_w[512]; to_send = (delay? 1: size); // calculate chars to send at one rdr_debug_mask(reader, D_DEVICE,"Write timeout %d us, write delay %d us, to send %d char(s), chunksize %d char(s)", timeout, delay, size, to_send); for (count = 0; count < size; count += to_send) { if (count + to_send > size){ to_send = size - count; } uint16_t errorcount=0, to_do=to_send; for (i_w=0; i_w < to_send; i_w++) data_w [i_w] = data [count + i_w]; rdr_ddump_mask(reader, D_DEVICE, data_w+(to_send-to_do), to_do, "Sending:"); AGAIN: if (!IO_Serial_WaitToWrite (reader, delay, timeout)) { while (to_do !=0){ int32_t u = write (reader->handle, data_w+(to_send-to_do), to_do); if (u < 1) { if (errno==EINTR) continue; //try again in case of Interrupted system call if (errno==EAGAIN) goto AGAIN; //EAGAIN needs a select procedure again errorcount++; int16_t written = count + to_send - to_do; if (u != 0) { rdr_log(reader, "ERROR: %s: Written=%d of %d (errno=%d %s)", __func__, written , size, errno, strerror(errno)); } if (errorcount > 10){ //exit if more than 10 errors return ERROR; } } else { to_do -= u; errorcount = 0; if (reader->crdr.read_written) reader->written += u; // these readers echo transmitted chars } } } else { rdr_log(reader, "Timeout in IO_Serial_WaitToWrite, delay=%d us, timeout=%d us", delay, timeout); return ERROR; } } return OK; }
static int32_t Cool_Receive(struct s_reader *reader, unsigned char *data, uint32_t size, uint32_t UNUSED(delay), uint32_t UNUSED(timeout)) { struct cool_data *crdr_data = reader->crdr_data; if(size > crdr_data->cardbuflen) { size = crdr_data->cardbuflen; } //never read past end of buffer memcpy(data, crdr_data->cardbuffer, size); crdr_data->cardbuflen -= size; memmove(crdr_data->cardbuffer, crdr_data->cardbuffer + size, crdr_data->cardbuflen); rdr_ddump_mask(reader, D_DEVICE, data, size, "COOL Receive:"); return OK; }
static int32_t Cool_Transmit (struct s_reader *reader, unsigned char * sent, uint32_t size, uint32_t UNUSED(delay), uint32_t timeout) { int32_t ret; specdev()->cardbuflen = 512;//it needs to know max buffer size to respond? if (specdev()->read_write_transmit_timeout == -1) ret = cnxt_smc_read_write(specdev()->handle, 0, sent, size, specdev()->cardbuffer, &specdev()->cardbuflen, timeout, NULL); else ret = cnxt_smc_read_write(specdev()->handle, 0, sent, size, specdev()->cardbuffer, &specdev()->cardbuflen, specdev()->read_write_transmit_timeout, NULL); coolapi_check_error("cnxt_smc_read_write", ret); rdr_ddump_mask(reader, D_DEVICE, sent, size, "COOL Transmit:"); return OK; }
int32_t ICC_Async_Transmit (struct s_reader *reader, uint32_t size, unsigned char * data, uint32_t delay, uint32_t timeout) { rdr_debug_mask(reader, D_IFD, "Transmit size %d bytes, delay %d us, timeout=%d us",size, delay, timeout); rdr_ddump_mask(reader, D_IFD, data, size, "Transmit:"); unsigned char *sent = data; if (reader->convention == ATR_CONVENTION_INVERSE && reader->crdr.need_inverse) { ICC_Async_InvertBuffer (size, sent); } call(reader->crdr.transmit(reader, sent, size, delay, timeout)); rdr_debug_mask(reader, D_IFD, "Transmit succesful"); if (reader->convention == ATR_CONVENTION_INVERSE && reader->crdr.need_inverse) { // revert inversion cause the code in protocol_t0 is accessing buffer after transmit ICC_Async_InvertBuffer (size, sent); } return OK; }
bool IO_Serial_Read (struct s_reader * reader, uint32_t delay, uint32_t timeout, uint32_t size, unsigned char * data) { uint32_t count = 0; if (timeout == 0){ // General fix for readers not communicating timeout and delay if (reader->read_timeout != 0) timeout = reader->read_timeout; else timeout = 9990000; // hope 99990000 is long enough! rdr_debug_mask(reader, D_DEVICE,"Warning: read timeout 0 changed to %d us", timeout); } rdr_debug_mask(reader, D_DEVICE,"Read timeout %d us, read delay %d us, to read %d char(s), chunksize %d char(s)", timeout, delay, size, size); if (reader->crdr.read_written && reader->written > 0) { // these readers need to read all transmitted chars before they can receive! unsigned char buf[256]; rdr_debug_mask(reader, D_DEVICE,"Reading %d echoed transmitted chars...", reader->written); int32_t n = reader->written; reader->written=0; if(IO_Serial_Read (reader, 0, 9990000, n, buf)) // use 9990000 = aprox 10 seconds (since written chars could be hughe!) return ERROR; rdr_debug_mask(reader, D_DEVICE,"Reading of echoed transmitted chars done!"); } #if defined(WITH_STAPI) || defined(__SH4__) //internal stapi and sh4 readers need special treatment as they don't respond correctly to poll and some sh4 boxes only can read 1 byte at once if(reader->typ == R_INTERNAL){ int32_t readed; #if defined(WITH_STAPI) const int32_t chunksize = INT_MAX; #elif defined(__SH4__) const int32_t chunksize = 1; #endif struct timeval tv, tv_spent; gettimeofday(&tv,0); memcpy(&tv_spent,&tv,sizeof(struct timeval)); readed=0; while((((tv_spent.tv_sec-tv.tv_sec)*1000000) + ((tv_spent.tv_usec-tv.tv_usec)/1000000L)) < (time_t)(timeout)) { readed = read(reader->handle, &data[count], size-count>=chunksize?chunksize:size-count); gettimeofday(&tv_spent,0); if(readed > 0) count +=readed; if(count < size){ if(readed < chunksize) cs_sleepus(1); continue; } else break; } if(count < size) { rdr_ddump_mask(reader, D_DEVICE, data, count, "Receiving:"); return ERROR; } } else #endif // read all chars at once for all other boxes { while(count < size){ int32_t readed = -1, errorcount=0; AGAIN: if(IO_Serial_WaitToRead (reader, delay, timeout)) { rdr_debug_mask(reader, D_DEVICE, "Timeout in IO_Serial_WaitToRead, timeout=%d us", timeout); return ERROR; } while (readed <0 && errorcount < 10) { readed = read (reader->handle, &data[count], size-count); if (readed < 0) { if (errno == EINTR) continue; // try again in case of interrupt if (errno == EAGAIN) goto AGAIN; //EAGAIN needs select procedure again rdr_log(reader, "ERROR: %s (errno=%d %s)", __func__, errno, strerror(errno)); errorcount++; } } if (readed == 0) { rdr_ddump_mask(reader, D_DEVICE, data, count, "Receiving:"); rdr_debug_mask(reader, D_DEVICE, "Received End of transmission"); return ERROR; } count +=readed; } } rdr_ddump_mask(reader, D_DEVICE, data, count, "Receiving:"); return OK; }
int32_t ICC_Async_CardWrite(struct s_reader *reader, unsigned char *command, uint16_t command_len, unsigned char *rsp, uint16_t *lr) { int32_t ret; *lr = 0; //will be returned in case of error if(reader->crdr.card_write) { call(reader->crdr.card_write(reader, command, rsp, lr, command_len)); return OK; } if(reader->crdr.lock) { reader->crdr.lock(reader); } int32_t try = 1; uint16_t type = 0; do { switch(reader->protocol_type) { if(try > 1) rdr_log(reader, "Warning: needed try nr %i, next ECM has some delay", try); case ATR_PROTOCOL_TYPE_T0: ret = Protocol_T0_Command(reader, command, command_len, rsp, lr); type = 0; break; case ATR_PROTOCOL_TYPE_T1: ret = Protocol_T1_Command(reader, command, command_len, rsp, lr); type = 1; if(ret != OK && !reader->crdr.skip_t1_command_retries) { //try to resync rdr_log(reader, "Resync error: readtimeouts %d/%d (max/min) us, writetimeouts %d/%d (max/min) us", reader->maxreadtimeout, reader->minreadtimeout, reader->maxwritetimeout, reader->minwritetimeout); unsigned char resync[] = { 0x21, 0xC0, 0x00, 0xE1 }; ret = Protocol_T1_Command(reader, resync, sizeof(resync), rsp, lr); if(ret == OK) { //reader->ifsc = DEFAULT_IFSC; //tryfix cardtimeouts: ifsc is setup at card init, on resync it should not return to default_ifsc rdr_log(reader, "T1 Resync command succesfull ifsc = %i", reader->ifsc); ret = ERROR; } else { rdr_log(reader, "T1 Resync command error, trying to reactivate!"); ATR atr; ICC_Async_Activate(reader, &atr, reader->deprecated); if(reader->crdr.unlock) { reader->crdr.unlock(reader); } return ERROR; } } break; case ATR_PROTOCOL_TYPE_T14: ret = Protocol_T14_ExchangeTPDU(reader, command, command_len, rsp, lr); type = 14; break; default: rdr_log(reader, "ERROR: Unknown protocol type %i", reader->protocol_type); type = 99; // use 99 for unknown. ret = ERROR; } try++; } while((try < 3) && (ret != OK)); //always do one retry when failing if(reader->crdr.unlock) { reader->crdr.unlock(reader); } if(ret) { rdr_debug_mask(reader, D_TRACE, "ERROR: Protocol_T%d_Command returns error", type); return ERROR; } rdr_ddump_mask(reader, D_READER, rsp, *lr, "Answer from cardreader:"); return OK; } int32_t ICC_Async_GetTimings(struct s_reader *reader, uint32_t wait_etu) { int32_t timeout = ETU_to_us(reader, wait_etu); rdr_debug_mask(reader, D_IFD, "Setting timeout to %i ETU (%d us)", wait_etu, timeout); return timeout; }
bool IO_Serial_Write(struct s_reader *reader, uint32_t delay, uint32_t timeout, uint32_t size, const unsigned char *data) { if(timeout == 0) // General fix for readers not communicating timeout and delay { if(reader->char_delay != 0) { timeout = reader->char_delay; } else { timeout = 1000000; } rdr_debug_mask(reader, D_DEVICE, "Warning: write timeout 0 changed to %d us", timeout); } uint32_t count, to_send, i_w; unsigned char data_w[512]; to_send = (delay ? 1 : size); // calculate chars to send at one rdr_debug_mask(reader, D_DEVICE, "Write timeout %d us, write delay %d us, to send %d char(s), chunksize %d char(s)", timeout, delay, size, to_send); for(count = 0; count < size; count += to_send) { if(count + to_send > size) { to_send = size - count; } uint16_t errorcount = 0, to_do = to_send; for(i_w = 0; i_w < to_send; i_w++) { data_w [i_w] = data [count + i_w]; } rdr_ddump_mask(reader, D_DEVICE, data_w + (to_send - to_do), to_do, "Sending:"); AGAIN: if(!IO_Serial_WaitToWrite(reader, delay, timeout)) { while(to_do != 0) { int32_t u = write(reader->handle, data_w + (to_send - to_do), to_do); if(u < 1) { if(errno == EINTR) { continue; } //try again in case of Interrupted system call if(errno == EAGAIN) { goto AGAIN; } //EAGAIN needs a select procedure again errorcount++; int16_t written = count + to_send - to_do; if(u != 0) { rdr_log(reader, "ERROR: %s: Written=%d of %d (errno=%d %s)", __func__, written , size, errno, strerror(errno)); } if(errorcount > 10) //exit if more than 10 errors { return ERROR; } } else { to_do -= u; errorcount = 0; if(reader->crdr.read_written) { reader->written += u; } // these readers echo transmitted chars } } } else { rdr_log(reader, "Timeout in IO_Serial_WaitToWrite, delay=%d us, timeout=%d us", delay, timeout); if(reader->crdr.read_written && reader->written > 0) // these readers need to read all transmitted chars before they can receive! { unsigned char buf[256]; rdr_debug_mask(reader, D_DEVICE, "Reading %d echoed transmitted chars...", reader->written); int32_t n = reader->written; if(IO_Serial_Read(reader, 0, 9990000, n, buf)) // use 9990000 = aprox 10 seconds (since written chars could be hughe!) { return ERROR; } reader->written = 0; rdr_debug_mask(reader, D_DEVICE, "Reading of echoed transmitted chars done!"); } return ERROR; } } if(reader->crdr.read_written && reader->written > 0) // these readers need to read all transmitted chars before they can receive! { unsigned char buf[256]; rdr_debug_mask(reader, D_DEVICE, "Reading %d echoed transmitted chars...", reader->written); int32_t n = reader->written; if(IO_Serial_Read(reader, 0, 9990000, n, buf)) // use 9990000 = aprox 10 seconds (since written chars could be hughe!) { return ERROR; } reader->written = 0; rdr_debug_mask(reader, D_DEVICE, "Reading of echoed transmitted chars done!"); } return OK; }
bool IO_Serial_Read(struct s_reader *reader, uint32_t delay, uint32_t timeout, uint32_t size, unsigned char *data) { uint32_t count = 0; if(timeout == 0) // General fix for readers not communicating timeout and delay { if(reader->read_timeout != 0) { timeout = reader->read_timeout; } else { timeout = 9990000; } // hope 99990000 is long enough! rdr_debug_mask(reader, D_DEVICE, "Warning: read timeout 0 changed to %d us", timeout); } rdr_debug_mask(reader, D_DEVICE, "Read timeout %d us, read delay %d us, to read %d char(s), chunksize %d char(s)", timeout, delay, size, size); #if defined(WITH_STAPI) || defined(__SH4__) //internal stapi and sh4 readers need special treatment as they don't respond correctly to poll and some sh4 boxes only can read 1 byte at once if(reader->typ == R_INTERNAL) { int32_t readed; #if defined(WITH_STAPI) const uint32_t chunksize = INT_MAX; #elif defined(__SH4__) const uint32_t chunksize = 1; #endif struct timeb start, end; cs_ftime(&start); end = start; int64_t gone = 0; int32_t timeout_ms = timeout / 1000; readed = 0; while(gone < timeout_ms) { readed = read(reader->handle, &data[count], size - count >= chunksize ? chunksize : size - count); cs_ftime(&end); if(readed > 0) { count += readed; cs_ftime(&start); // Reset timer end = start; } gone = comp_timeb(&end, &start); if(count < size) { if(readed < (int32_t)chunksize) { cs_sleepus(1); } continue; } else { break; } } if(count < size) { rdr_ddump_mask(reader, D_DEVICE, data, count, "Receiving:"); return ERROR; } } else #endif // read all chars at once for all other boxes { while(count < size) { int32_t readed = -1, errorcount = 0; AGAIN: if(IO_Serial_WaitToRead(reader, delay, timeout)) { rdr_debug_mask(reader, D_DEVICE, "Timeout in IO_Serial_WaitToRead, timeout=%d us", timeout); return ERROR; } while(readed < 0 && errorcount < 10) { readed = read(reader->handle, &data[count], size - count); if(readed < 0) { if(errno == EINTR) { continue; } // try again in case of interrupt if(errno == EAGAIN) { goto AGAIN; } //EAGAIN needs select procedure again rdr_log(reader, "ERROR: %s (errno=%d %s)", __func__, errno, strerror(errno)); errorcount++; } } if(readed == 0) { rdr_ddump_mask(reader, D_DEVICE, data, count, "Receiving:"); rdr_debug_mask(reader, D_DEVICE, "Received End of transmission"); return ERROR; } count += readed; } } rdr_ddump_mask(reader, D_DEVICE, data, count, "Receiving:"); return OK; }