예제 #1
0
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;
}
예제 #2
0
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;
}