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; }
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; }