int32_t ICC_Async_CardWrite (struct s_reader *reader, unsigned char *command, uint16_t command_len, unsigned char *rsp, uint16_t *lr) { #ifdef HAVE_PCSC if (reader->typ == R_PCSC) return (pcsc_reader_do_api(reader, command, rsp, lr, command_len)); #endif *lr = 0; //will be returned in case of error int32_t ret; LOCK_SC8IN1; int32_t try = 1; do { switch (reader->protocol_type) { if (try > 1) cs_log("Warning: reader %s needed try nr %i, next ECM has some delay:", reader->label, try); case ATR_PROTOCOL_TYPE_T0: ret = Protocol_T0_Command (reader, command, command_len, rsp, lr); break; case ATR_PROTOCOL_TYPE_T1: ret = Protocol_T1_Command (reader, command, command_len, rsp, lr); if (ret != OK) { //try to resync unsigned char resync[] = { 0x21, 0xC0, 0x00, 0xE1 }; Protocol_T1_Command (reader, resync, sizeof(resync), rsp, lr); reader->ifsc = DEFAULT_IFSC; } break; case ATR_PROTOCOL_TYPE_T14: ret = Protocol_T14_ExchangeTPDU (reader, command, command_len, rsp, lr); break; default: cs_log("Error, unknown protocol type %i",reader->protocol_type); ret = ERROR; } try++; } while ((try < 3) && (ret != OK)); //always do one retry when failing UNLOCK_SC8IN1; if (ret) { cs_debug_mask(D_TRACE, "ERROR, function call Protocol_T0_Command returns error."); return ERROR; } cs_ddump_mask(D_READER, rsp, *lr, "answer from cardreader %s:", reader->label); return OK; } int32_t ICC_Async_SetTimings (struct s_reader * reader, uint32_t wait_etu) { reader->read_timeout = ETU_to_ms(reader, wait_etu); cs_debug_mask(D_IFD, "Setting timeout to %i", wait_etu); 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; }