static bool IO_Serial_WaitToWrite(struct s_reader *reader, uint32_t delay_us, uint32_t timeout_us) { struct pollfd ufds; struct timeb start, end; int32_t ret_val; int32_t out_fd; int64_t polltimeout = timeout_us / 1000; #if !defined(WITH_COOLAPI) if(reader->typ == R_INTERNAL) { return OK; } // needed for internal readers, otherwise error! #endif if(delay_us > 0) { cs_sleepus(delay_us); } // wait in us out_fd = reader->handle; ufds.fd = out_fd; ufds.events = POLLOUT; ufds.revents = 0x0000; cs_ftime(&start); // register start time while(1) { ret_val = poll(&ufds, 1, polltimeout); cs_ftime(&end); // register end time switch(ret_val) { case 0: rdr_log(reader, "ERROR: not ready to write, timeout=%"PRId64" ms", comp_timeb(&end, &start)); return ERROR; case -1: if(errno == EINTR || errno == EAGAIN) { cs_sleepus(1); if(timeout_us > 0) { polltimeout = (timeout_us / 1000) - comp_timeb(&end, &start); if(polltimeout < 0) { polltimeout = 0; } } continue; } rdr_log(reader, "ERROR: %s: timeout=%"PRId64" ms (errno=%d %s)", __func__, comp_timeb(&end, &start), errno, strerror(errno)); return ERROR; default: if(((ufds.revents) & POLLOUT) == POLLOUT) { return OK; } else { return ERROR; } } } }
static bool IO_Serial_WaitToWrite (struct s_reader * reader, uint32_t delay_us, uint32_t timeout_us) { struct pollfd ufds; int32_t ret_val; int32_t out_fd; #if !defined(WITH_COOLAPI) && !defined(WITH_AZBOX) if(reader->typ == R_INTERNAL) return OK; // needed for internal readers, otherwise error! #endif if (delay_us > 0) cs_sleepus (delay_us); // wait in us out_fd = reader->handle; ufds.fd = out_fd; ufds.events = POLLOUT; ufds.revents = 0x0000; while (1){ ret_val = poll(&ufds, 1, timeout_us / 1000); switch (ret_val){ case 0: return ERROR; case -1: if (errno == EINTR || errno == EAGAIN) continue; rdr_log(reader, "ERROR: %s: timeout=%d us (errno=%d %s)", __func__, timeout_us, errno, strerror(errno)); return ERROR; default: if (((ufds.revents) & POLLOUT) == POLLOUT) return OK; else return ERROR; } } }
bool IO_Serial_WaitToRead (struct s_reader * reader, uint32_t delay_us, uint32_t timeout_us) { struct pollfd ufds; int32_t ret_val; int32_t in_fd; if (delay_us > 0) cs_sleepus (delay_us); // wait in us in_fd = reader->handle; ufds.fd = in_fd; ufds.events = POLLIN; ufds.revents = 0x0000; while (1){ ret_val = poll(&ufds, 1, timeout_us / 1000); switch (ret_val){ case -1: if (errno == EINTR || errno == EAGAIN) continue; rdr_log(reader, "ERROR: %s: timeout=%d us (errno=%d %s)", __func__, timeout_us, errno, strerror(errno)); return ERROR; default: if (((ufds.revents) & POLLIN) == POLLIN) return OK; else return ERROR; } } }
bool IO_Serial_WaitToRead(struct s_reader *reader, uint32_t delay_us, uint32_t timeout_us) { struct pollfd ufds; struct timeb start, end; int32_t ret_val; int32_t in_fd; int64_t polltimeout = timeout_us / 1000; if(delay_us > 0) { cs_sleepus(delay_us); } // wait in us in_fd = reader->handle; ufds.fd = in_fd; ufds.events = POLLIN | POLLPRI; ufds.revents = 0x0000; cs_ftime(&start); // register start time while(1) { ret_val = poll(&ufds, 1, polltimeout); cs_ftime(&end); // register end time switch(ret_val) { case -1: if(errno == EINTR || errno == EAGAIN) { cs_sleepus(1); if(timeout_us > 0) { polltimeout = (timeout_us / 1000) - comp_timeb(&end, &start); if(polltimeout < 0) { polltimeout = 0; } } continue; } rdr_log(reader, "ERROR: %s: timeout=%"PRId64" ms (errno=%d %s)", __func__, comp_timeb(&end, &start), errno, strerror(errno)); return ERROR; default: if(ufds.revents & (POLLIN | POLLPRI)) { return OK; } else { return ERROR; } } } }
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; }