Пример #1
0
void get_peer_shipset(const int sock)
{
  for (int i=0; i<NUM_SHIPS; ++i) {
    PeerShipset[i].x = recv_byte(sock);
    PeerShipset[i].y = recv_byte(sock);
    PeerShipset[i].direction = recv_byte(sock);
  }
}
Пример #2
0
bool verify_client(const int sock)
{
  /* Handshake: recv a 42, send a 47 back, recv a 49 in return. */
  if (recv_byte(sock) != 42) return false;
  send_byte(sock, 47);
  if (recv_byte(sock) != 49) return false;

  return true;
}
Пример #3
0
/*
 * This function does the actual read of the EEPROM. It needs the buffer into which the
 * read data is copied, the size of the EEPROM being read and the buffer size
 */
int read_eeprom(char *buffer, int eeprom_size, int size)
{
	int	i = 0, err;

	send_start();
	send_byte(W_HEADER);
	recv_ack();

	/* EEPROM with size of more than 2K need two byte addressing */
	if (eeprom_size > 2048) {
		send_byte(0x00);
		recv_ack();
	}

	send_start();
	send_byte(R_HEADER);
	err = recv_ack();
	if (err == -1)
		return err;

	for (i = 0; i < size; i++) {
		*buffer++ = recv_byte();
		send_ack();
	}

	/* Note : We should do some check if the buffer contains correct information */

	send_stop();
}
Пример #4
0
int read_nonblock( int fd, void *buffer, size_t nbytes )
{
    size_t  i;
    char    *buf;
    int     err;

    buf = (char*)buffer;
    for( i = 0; i < nbytes; i++, buf++ )
    {
        // Stop reading if we would block
        if( !can_recv() )   break;
        
        // Get the next byte
        err = recv_byte( buf );
        if( err != 0 )  return err;

        // Exit when the line ends
        if( *buf == '\n' || *buf == '\r' || *buf == 0x04 || *buf == 0x1A )
        {
            i += 1;
            *(++buf) = 0;
            break;
        }
    }

    if( i == 0 )    { errno = EAGAIN; return -1; }
    else            { return i; }
}
Пример #5
0
int read_block( int fd, void *buffer, size_t nbytes )
{
    size_t  i;
    char    *buf;
    int     err;

    buf = (char*)buffer;
    for( i = 0; i < nbytes; i++, buf++ )
    {
        // Get the next byte
        err = recv_byte( buf );
        if( err != 0 )  return err;

        // Translate '\r\n' to '\n'
        //if( *buf == '\r' )  *buf = '\n';
        //if( i > 0 && *buf == '\n' && *(buf-1) == '\r' ) *(buf-1) = *buf--;

        // Exit when the line ends
        if( *buf == '\n' || *buf == '\r' || *buf == 0x04 || *buf == 0x1A )
        {
            i += 1;
            *(++buf) = 0;
            break;
        }
    }

    return i;
}
Пример #6
0
// 通过SPI 总线向 THM3060 读出 num 长度个字节
static void receive_buff(unsigned char *buf,unsigned int num)
{
	if ((buf== NULL)||(num ==0)) return;
	while(num--)
	{
		*buf++ = recv_byte();	
	 }
}
Пример #7
0
bool verify_server(const int sock)
{
  /* Handshake: send a 42, recv a 47 in return, send a 49 back. */
  send_byte(sock, 42);
  if (recv_byte(sock) != 47) return false;
  send_byte(sock, 49);

  return true;
}
Пример #8
0
uint8_t ds1302_read(uint8_t addr)
{
    uint8_t c;

    start();
    send_byte((addr << 1) | CMDREAD);
    c = recv_byte();
    stop();

    return c;
}
Пример #9
0
/* Imple */
static ssize_t stdin_read(void * opaque, void * buf, size_t count) {
    int i=0, endofline=0, last_chr_is_esc;
    char *ptrbuf=buf;
    char ch;
    while(i < count&&endofline!=1){
	ptrbuf[i]=recv_byte();
	switch(ptrbuf[i]){
		case '\r':
		case '\n':
			ptrbuf[i]='\0';
			endofline=1;
			break;
		case '[':
			if(last_chr_is_esc){
				last_chr_is_esc=0;
				ch=recv_byte();
				if(ch>=1&&ch<=6){
					ch=recv_byte();
				}
				continue;
			}
		case ESC:
			last_chr_is_esc=1;
			continue;
		case BACKSPACE:
			last_chr_is_esc=0;
			if(i>0){
				send_byte('\b');
				send_byte(' ');
				send_byte('\b');
				--i;
			}
			continue;
		default:
			last_chr_is_esc=0;
	}
	send_byte(ptrbuf[i]);
	++i;
    }
    return i;
}
Пример #10
0
/*
 The following code does:
     * receive address (2 bytes), add them to CRC
     * transmit anything from this address onwards until
       0x8F is reached
     * send the 2 crc bytes.

     This is all very straightforward, except that the CRC calculation
 for the first byte to transmit is delayed somewhat:
 the time between recv_byte_in() and xmit_byte() is only a bit wide,
 which may not be enough time to add a CRC byte.
 */
void do_read_pio(void)
{
	u_short crc = 0;
	u_short adr;
	u_char bcrc = 1;
	u_char b;
	
	recv_byte();
	crc = crc16(crc,0xF0);
	b = recv_byte_in();			// address low byte
	recv_byte();
	crc = crc16(crc, b);
	adr = b;
	b = recv_byte_in();			// address high byte
	adr |= b<<8;

	/* note: bcrc is only true for the first byte to transmit */
#define XMIT(val) do { \
	xmit_byte(val); \
	if(bcrc) { crc = crc16(crc, b); bcrc = 0; } \
	crc = crc16(crc,val); \
} while(0)

	while(adr < 0x88) { XMIT(0); adr++; }
	switch(adr) {
	case 0x88: XMIT(pio_logic);
	case 0x89: XMIT(pio_output_latch);
	case 0x8A: XMIT(pio_activity_latch);
	case 0x8B: XMIT(cond_search_mask);
	case 0x8C: XMIT(cond_polarity_mask);
	case 0x8D: XMIT(control_status);
	case 0x8E: XMIT(0xFF);
	case 0x8F: XMIT(0xFF);
		crc = ~crc;
		xmit_byte(crc);
		xmit_byte(crc >> 8);
	default:
		while(1)
			XMIT(0xFF);
	}
}
Пример #11
0
void ds1302_read_clock(uint8_t __idata *p)
{
    uint8_t i;

    start();
    /* send_byte(0xBF); */
    send_byte((0x1F << 1) | CMDREAD);
    for (i = 7; i != 0; p++, i--) {
        *p = recv_byte();
    }
    stop();
}
Пример #12
0
/* 消耗 len 个字节 */
int eat_byte(int sock, int len)
{
    int rc;
    int byte;
    char buf[32];
    for (byte = 0; len-byte > 32; byte += rc) {
        rc = recv(sock, buf, 32, MSG_NOSIGNAL);
        if (rc == 0) break;
        if (rc < 0 && errno != EINTR) return -1;
    }
    if (rc != 0) byte += recv_byte(sock, buf, len-byte);
    return byte;
}
Пример #13
0
UINT8 ncr5380n_device::dma_r()
{
	// drop DRQ
	drq_clear();

	// set up to receive our next byte if still in DMA mode
	scsi_bus->ctrl_w(scsi_refid, 0, S_ACK);
	if (m_mode & MODE_DMA)
	{
		recv_byte();
	}
	return m_dmalatch;
}
Пример #14
0
/* 接收字符串 */
int recv_str(int sock, char *buf, int max_len)
{
    int byte;
    int len;
    int len_recv;
    int len_diff;
    len_diff = 0;
    /* 首先接收一个整数,这个整数表示字符串长度 */
    byte = recv_byte(sock, (char *)&len_recv, sizeof(len_recv));
    if (byte < 0) return -1;
    len = ntohl(len_recv);
    if (len > max_len) {
        len_diff = len-max_len;
        len = max_len;
    }
    /* 然后接收字符串 */
    byte = recv_byte(sock, buf, len);
    if (byte <= 0) return -1;
    buf[byte] = '\0';
    /* 如果实际接收的字符数小于字符串的长度,则消耗掉多余的字符 */
    if (len_diff > 0) eat_byte(sock, len_diff);
    return byte;
}
Пример #15
0
static ssize_t stdin_read(void * opaque, void * buf, size_t count) {
    int i = 0;
    char *ptrbuf = buf;
    int cmd_end_flag=0;

    while( (i < count) && (cmd_end_flag != 1) ){
        ptrbuf[i]=recv_byte();
        
        switch(ptrbuf[i]){
            case '\r':
            case '\n':
                ptrbuf[i] = '\0';
                cmd_end_flag = 1;
                break;
            default :
                cmd_end_flag = 0;
        }
        send_byte(ptrbuf[i]);
        ++i;
    }
    return i;
}
Пример #16
0
static int receive_files(char** fname_list, int fnames)
{
	char	str[MAX_PATH+1];
	char	fname[MAX_PATH+1];
	int		i;
	int		fnum=0;
	uint	errors;
	uint	total_files=0;
	uint	cps;
	uint	wr;
	BOOL	success=FALSE;
	long	fmode;
	long	serial_num=-1;
	ulong	file_bytes=0,file_bytes_left=0;
	ulong	total_bytes=0;
	FILE*	fp;
	time_t	t,startfile,ftime;

	if(fnames>1)
		lprintf(LOG_INFO,"Receiving %u files",fnames);

	outbuf.highwater_mark=0;	/* don't delay ACK/NAK transmits */

	/* Purge input buffer */
	while(is_connected(NULL) && (i=recv_byte(NULL,0))!=NOINP)
		lprintf(LOG_WARNING,"Throwing out received: %s",chr((uchar)i));

	while(is_connected(NULL)) {
		if(mode&XMODEM) {
			SAFECOPY(str,fname_list[0]);	/* we'll have at least one fname */
			file_bytes=file_bytes_left=0x7fffffff;
		}

		else {
			if(mode&YMODEM) {
				lprintf(LOG_INFO,"Fetching Ymodem header block");
				for(errors=0;errors<=xm.max_errors && !xm.cancelled;errors++) {
					if(errors>(xm.max_errors/2) && mode&CRC && !(mode&GMODE))
						mode&=~CRC;
					xmodem_put_nak(&xm, /* expected_block: */ 0);
					if(xmodem_get_block(&xm, block, /* expected_block: */ 0) == 0) {
						send_byte(NULL,ACK,10);
						break; 
					} 
				}
				if(errors>=xm.max_errors || xm.cancelled) {
					lprintf(LOG_ERR,"Error fetching Ymodem header block");
					xmodem_cancel(&xm);
					return(1); 
				}
				if(!block[0]) {
					lprintf(LOG_INFO,"Received Ymodem termination block");
					return(0); 
				}
				file_bytes=ftime=total_files=total_bytes=0;
				i=sscanf(block+strlen(block)+1,"%ld %lo %lo %lo %d %ld"
					,&file_bytes			/* file size (decimal) */
					,&ftime 				/* file time (octal unix format) */
					,&fmode 				/* file mode (not used) */
					,&serial_num			/* program serial number */
					,&total_files			/* remaining files to be sent */
					,&total_bytes			/* remaining bytes to be sent */
					);
				lprintf(LOG_DEBUG,"Ymodem header (%u fields): %s", i, block+strlen(block)+1);
				SAFECOPY(fname,block);

			} else {	/* Zmodem */
				lprintf(LOG_INFO,"Waiting for Zmodem sender...");

				i=zmodem_recv_init(&zm);

				if(zm.cancelled)
					return(1);
				if(i<0)
					return(-1);
				switch(i) {
					case ZFILE:
						SAFECOPY(fname,zm.current_file_name);
						file_bytes = zm.current_file_size;
						ftime = zm.current_file_time;
						total_files = zm.files_remaining;
						total_bytes = zm.bytes_remaining;
						break;
					case ZFIN:
					case ZCOMPL:
						return(!success);
					default:
						return(-1);
				}
			}

			if(!file_bytes)
				file_bytes=0x7fffffff;
			file_bytes_left=file_bytes;
			if(!total_files)
				total_files=fnames-fnum;
			if(!total_files)
				total_files=1;
			if(total_bytes<file_bytes)
				total_bytes=file_bytes;

			lprintf(LOG_DEBUG,"Incoming filename: %.64s ",fname);

			if(mode&RECVDIR)
				sprintf(str,"%s%s",fname_list[0],getfname(fname));
			else {
				SAFECOPY(str,getfname(fname));
				for(i=0;i<fnames;i++) {
					if(!fname_list[i][0])	/* name blank or already used */
						continue;
					if(!stricmp(getfname(fname_list[i]),str)) {
						SAFECOPY(str,fname_list[i]);
						fname_list[i][0]=0;
						break; 
					} 
				}
				if(i==fnames) { 				/* Not found in list */
					if(fnames)
						fprintf(statfp," - Not in receive list!");
					if(!fnames || fnum>=fnames || !fname_list[fnum][0])
						SAFECOPY(str,getfname(fname));	/* worst case */
					else {
						SAFECOPY(str,fname_list[fnum]);
						fname_list[fnum][0]=0; 
					} 
				} 
			}
			fprintf(statfp,"File size: %lu bytes\n", file_bytes);
			if(total_files>1)
				fprintf(statfp,"Remaining: %lu bytes in %u files\n", total_bytes, total_files);
		}

		lprintf(LOG_DEBUG,"Receiving: %.64s ",str);

		fnum++;

		if(!(mode&RECVDIR) && fnames && fnum>fnames) {
			lprintf(LOG_WARNING,"Attempt to send more files than specified");
			xmodem_cancel(&xm);
			break; 
		}

		if(fexistcase(str) && !(mode&OVERWRITE)) {
			lprintf(LOG_WARNING,"%s already exists",str);
			if(mode&ZMODEM) {
				zmodem_send_zskip(&zm);
				continue;
			}
			xmodem_cancel(&xm);
			return(1); 
		}
		if((fp=fnopen(NULL,str,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY))==NULL
			&& (fp=fopen(str,"wb"))==NULL) {
			lprintf(LOG_ERR,"Error %d creating %s",errno,str);
			if(mode&ZMODEM) {
				zmodem_send_zskip(&zm);
				continue;
			}
			xmodem_cancel(&xm);
			return(1); 
		}

		if(mode&XMODEM)
			lprintf(LOG_INFO,"Receiving %s via Xmodem %s"
				,str
				,mode&CRC ? "CRC-16":"Checksum");
		else
			lprintf(LOG_INFO,"Receiving %s (%lu KB) via %s %s"
				,str
				,file_bytes/1024
				,mode&YMODEM ? mode&GMODE ? "Ymodem-G" : "Ymodem" :"Zmodem"
				,mode&ZMODEM ? "" : (mode&CRC ? "CRC-16" : "Checksum"));

		startfile=time(NULL);
		success=FALSE;
		if(mode&ZMODEM) {

			errors=zmodem_recv_file_data(&zm,fp,0);

			/*
 			 * wait for the eof header
			 */

			for(;errors<=zm.max_errors && !success && !zm.cancelled; errors++) {
				if(zmodem_recv_header_and_check(&zm))
					success=TRUE;
			} 

		} else {
			errors=0;
			block_num=1;
			xmodem_put_nak(&xm, block_num);
			while(is_connected(NULL)) {
				xmodem_progress(NULL,block_num,ftell(fp),file_bytes,startfile);
				i=xmodem_get_block(&xm, block, block_num); 	

				if(i!=0) {
					if(i==EOT)	{		/* end of transfer */
						success=TRUE;
						xmodem_put_ack(&xm);
						break;
					}
					if(i==CAN) {		/* Cancel */
						xm.cancelled=TRUE;
						break;
					}

					if(mode&GMODE)
						return(-1);

					if(++errors>=xm.max_errors) {
						lprintf(LOG_ERR,"Too many errors (%u)",errors);
						xmodem_cancel(&xm);
						break;
					}
					if(block_num==1 && errors>(xm.max_errors/2) && mode&CRC && !(mode&GMODE))
						mode&=~CRC;
					xmodem_put_nak(&xm, block_num);
					continue;
				}
				if(!(mode&GMODE))
					send_byte(NULL,ACK,10);
				if(file_bytes_left<=0L)  { /* No more bytes to send */
					lprintf(LOG_WARNING,"Attempt to send more byte specified in header");
					break; 
				}
				wr=xm.block_size;
				if(wr>file_bytes_left)
					wr=file_bytes_left;
				if(fwrite(block,1,wr,fp)!=wr) {
					lprintf(LOG_ERR,"Error writing %u bytes to file at offset %lu"
						,wr,ftell(fp));
					xmodem_cancel(&xm);
					return(1); 
				}
				file_bytes_left-=wr; 
				block_num++;
			}
		}

		/* Use correct file size */
		fflush(fp);
		if(file_bytes < (ulong)filelength(fileno(fp))) {
			lprintf(LOG_INFO,"Truncating file to %lu bytes", file_bytes);
			chsize(fileno(fp),file_bytes);
		} else
			file_bytes = filelength(fileno(fp));
		fclose(fp);
		
		t=time(NULL)-startfile;
		if(!t) t=1;
		if(success)
			lprintf(LOG_INFO,"Successful - Time: %lu:%02lu  CPS: %lu"
				,t/60,t%60,file_bytes/t);	
		else
			lprintf(LOG_ERR,"File Transfer %s", aborted ? "Aborted":"Failure");

		if(!(mode&XMODEM) && ftime)
			setfdate(str,ftime); 

		if(logfp) {
			lprintf(LOG_DEBUG,"Updating DSZLOG: %s", dszlog);
			fprintf(logfp,"%c %6lu %5u bps %4lu cps %3u errors %5u %4u "
				"%s %d\n"
				,success ? (mode&ZMODEM ? 'Z' : 'R') : 'E'
				,file_bytes
				,115200	/* baud */
				,file_bytes/t
				,errors
				,flows
				,mode&ZMODEM ? zm.block_size : xm.block_size
				,dszlog_filename(str)
				,serial_num); 
			fflush(logfp);
		}

		if(aborted) {
			lprintf(LOG_DEBUG,"Locally aborted, sending cancel to remote");
			if(mode&ZMODEM)
				zmodem_abort_receive(&zm);
			xm.cancelled=FALSE;
			xmodem_cancel(&xm);
			break;
		}

		if(mode&XMODEM)	/* maximum of one file */
			break;
		if((cps=file_bytes/t)==0)
			cps=1;
		total_files--;
		total_bytes-=file_bytes;
		if(total_files>1 && total_bytes)
			lprintf(LOG_INFO,"Remaining - Time: %lu:%02lu  Files: %u  KBytes: %lu"
				,(total_bytes/cps)/60
				,(total_bytes/cps)%60
				,total_files
				,total_bytes/1024
				);
	}
	return(!success);	/* 0=success */
}
Пример #17
0
void ncr5390_device::step(bool timeout)
{
	UINT32 ctrl = scsi_bus->ctrl_r();
	UINT32 data = scsi_bus->data_r();
	UINT8 c     = command[0] & 0x7f;

	if(0)
		logerror("%s: state=%d.%d %s\n",
					tag(), state & STATE_MASK, (state & SUB_MASK) >> SUB_SHIFT,
					timeout ? "timeout" : "change");

	if(mode == MODE_I && !(ctrl & S_BSY)) {
		state = IDLE;
		istatus |= I_DISCONNECT;
		reset_disconnect();
		check_irq();
	}
	switch(state & SUB_MASK ? state & SUB_MASK : state & STATE_MASK) {
	case IDLE:
		break;

	case ARB_COMPLETE << SUB_SHIFT: {
		if(!timeout)
			break;

		int win;
		for(win=7; win>=0 && !(data & (1<<win)); win--);
		if(win != scsi_id) {
			scsi_bus->data_w(scsi_refid, 0);
			scsi_bus->ctrl_w(scsi_refid, 0, S_ALL);
			fatalerror("need to wait for bus free\n");
			break;
		}
		state = (state & STATE_MASK) | (ARB_ASSERT_SEL << SUB_SHIFT);
		scsi_bus->ctrl_w(scsi_refid, S_SEL, S_SEL);
		delay(6);
		break;
	}

	case ARB_ASSERT_SEL << SUB_SHIFT:
		if(!timeout)
			break;

		scsi_bus->data_w(scsi_refid, (1<<scsi_id) | (1<<bus_id));
		state = (state & STATE_MASK) | (ARB_SET_DEST << SUB_SHIFT);
		delay_cycles(4);
		break;

	case ARB_SET_DEST << SUB_SHIFT:
		if(!timeout)
			break;

		state = (state & STATE_MASK) | (ARB_RELEASE_BUSY << SUB_SHIFT);
		scsi_bus->ctrl_w(scsi_refid, c == CD_SELECT_ATN || c == CD_SELECT_ATN_STOP ? S_ATN : 0, S_ATN|S_BSY);
		delay(2);
		break;

	case ARB_RELEASE_BUSY << SUB_SHIFT:
		if(!timeout)
			break;

		if(ctrl & S_BSY) {
			state = (state & STATE_MASK) | (ARB_DESKEW_WAIT << SUB_SHIFT);
			if(c == CD_RESELECT)
				scsi_bus->ctrl_w(scsi_refid, S_BSY, S_BSY);
			delay_cycles(2);
		} else {
			state = (state & STATE_MASK) | (ARB_TIMEOUT_BUSY << SUB_SHIFT);
#ifdef DELAY_HACK
			delay(1);
#else
			delay(8192*select_timeout);
#endif
		}
		break;

	case ARB_DESKEW_WAIT << SUB_SHIFT:
		if(!timeout)
			break;

		scsi_bus->data_w(scsi_refid, 0);
		scsi_bus->ctrl_w(scsi_refid, 0, S_SEL);

		if(c == CD_RESELECT) {
			logerror("%s: mode switch to Target\n", tag());
			mode = MODE_T;
		} else {
			logerror("%s: mode switch to Initiator\n", tag());
			mode = MODE_I;
		}
		state &= STATE_MASK;
		step(true);
		break;

	case ARB_TIMEOUT_BUSY << SUB_SHIFT:
		if(timeout) {
			scsi_bus->data_w(scsi_refid, 0);
			logerror("%s: select timeout\n", tag());
			state = (state & STATE_MASK) | (ARB_TIMEOUT_ABORT << SUB_SHIFT);
			delay(1000);
		} else if(ctrl & S_BSY) {
			state = (state & STATE_MASK) | (ARB_DESKEW_WAIT << SUB_SHIFT);
			if(c == CD_RESELECT)
				scsi_bus->ctrl_w(scsi_refid, S_BSY, S_BSY);
			delay_cycles(2);
		}
		break;

	case ARB_TIMEOUT_ABORT << SUB_SHIFT:
		if(!timeout)
			break;

		if(ctrl & S_BSY) {
			state = (state & STATE_MASK) | (ARB_DESKEW_WAIT << SUB_SHIFT);
			if(c == CD_RESELECT)
				scsi_bus->ctrl_w(scsi_refid, S_BSY, S_BSY);
			delay_cycles(2);
		} else {
			scsi_bus->ctrl_w(scsi_refid, 0, S_ALL);
			state = IDLE;
			istatus |= I_DISCONNECT;
			reset_disconnect();
			check_irq();
		}
		break;

	case SEND_WAIT_SETTLE << SUB_SHIFT:
		if(!timeout)
			break;

		state = (state & STATE_MASK) | (SEND_WAIT_REQ_0 << SUB_SHIFT);
		step(false);
		break;

	case SEND_WAIT_REQ_0 << SUB_SHIFT:
		if(ctrl & S_REQ)
			break;
		state = state & STATE_MASK;
		scsi_bus->data_w(scsi_refid, 0);
		scsi_bus->ctrl_w(scsi_refid, 0, S_ACK);
		step(false);
		break;

	case RECV_WAIT_REQ_1 << SUB_SHIFT:
		if(!(ctrl & S_REQ))
			break;

		state = (state & STATE_MASK) | (RECV_WAIT_SETTLE << SUB_SHIFT);
		delay_cycles(sync_period);
		break;

	case RECV_WAIT_SETTLE << SUB_SHIFT:
		if(!timeout)
			break;

		if((state & STATE_MASK) != INIT_XFR_RECV_PAD)
			fifo_push(scsi_bus->data_r());
		scsi_bus->ctrl_w(scsi_refid, S_ACK, S_ACK);
		state = (state & STATE_MASK) | (RECV_WAIT_REQ_0 << SUB_SHIFT);
		step(false);
		break;

	case RECV_WAIT_REQ_0 << SUB_SHIFT:
		if(ctrl & S_REQ)
			break;
		state = state & STATE_MASK;
		step(false);
		break;

	case DISC_SEL_ARBITRATION:
		if(c == CD_SELECT) {
			state = DISC_SEL_WAIT_REQ;
			command_length = derive_msg_size(fifo[0]);
		} else
			state = DISC_SEL_ATN_WAIT_REQ;

		scsi_bus->ctrl_wait(scsi_refid, S_REQ, S_REQ);
		if(ctrl & S_REQ)
			step(false);
		break;

	case DISC_SEL_ATN_WAIT_REQ:
		if(!(ctrl & S_REQ))
			break;
		if((ctrl & S_PHASE_MASK) != S_PHASE_MSG_OUT) {
			function_complete();
			break;
		}
		if(c == CD_SELECT_ATN)
			scsi_bus->ctrl_w(scsi_refid, 0, S_ATN);
		state = DISC_SEL_ATN_SEND_BYTE;
		send_byte();
		break;

	case DISC_SEL_ATN_SEND_BYTE:
		if(c == CD_SELECT_ATN_STOP) {
			seq = 1;
			function_complete();
		} else {
			command_length = derive_msg_size(fifo[0]);
			state = DISC_SEL_WAIT_REQ;
		}
		break;

	case DISC_SEL_WAIT_REQ:
		if(!(ctrl & S_REQ))
			break;
		if((ctrl & S_PHASE_MASK) != S_PHASE_COMMAND) {
			if(!command_length)
				seq = 4;
			scsi_bus->ctrl_wait(scsi_refid, 0, S_REQ);
			function_bus_complete();
			break;
		}
		if(seq < 3)
			seq = 3;
		state = DISC_SEL_SEND_BYTE;
		send_byte();
		break;

	case DISC_SEL_SEND_BYTE:
		if(command_length) {
			command_length--;
			if(!command_length)
				seq = 4;
		}

		state = DISC_SEL_WAIT_REQ;
		break;

	case INIT_CPT_RECV_BYTE_ACK:
		state = INIT_CPT_RECV_WAIT_REQ;
		scsi_bus->ctrl_w(scsi_refid, 0, S_ACK);
		break;

	case INIT_CPT_RECV_WAIT_REQ:
		if(!(ctrl & S_REQ))
			break;

		if((ctrl & S_PHASE_MASK) != S_PHASE_MSG_IN) {
			command_pos = 0;
			bus_complete();
		} else {
			state = INIT_CPT_RECV_BYTE_NACK;
			recv_byte();
		}
		break;

	case INIT_CPT_RECV_BYTE_NACK:
		scsi_bus->ctrl_wait(scsi_refid, 0, S_REQ);
		function_complete();
		break;

	case INIT_MSG_WAIT_REQ:
		if((ctrl & (S_REQ|S_BSY)) == S_BSY)
			break;
		bus_complete();
		break;

	case INIT_XFR:
		switch(xfr_phase) {
		case S_PHASE_DATA_OUT:
			dma_set(DMA_OUT);
			if(tcount == 0 && fifo_pos == 1)
				scsi_bus->ctrl_w(scsi_refid, 0, S_ATN);
			state = INIT_XFR_SEND_BYTE;
			send_byte();
			break;

		case S_PHASE_DATA_IN:
			dma_set(DMA_IN);
			state = tcount == fifo_pos+1 ?
				INIT_XFR_RECV_BYTE_NACK : INIT_XFR_RECV_BYTE_ACK;
			recv_byte();
			break;

		default:
			logerror("%s: xfer on phase %d\n", tag(), scsi_bus->ctrl_r() & S_PHASE_MASK);
			function_complete();
			break;
		}
		break;

	case INIT_XFR_WAIT_REQ:
		if(!(ctrl & S_REQ))
			break;

		if((ctrl & S_PHASE_MASK) != xfr_phase) {
			command_pos = 0;
			bus_complete();
		} else {
			state = INIT_XFR;
			step(false);
		}
		break;

	case INIT_XFR_SEND_BYTE:
		if(tcount == 0 && fifo_pos == 0)
			bus_complete();
		else
			state = INIT_XFR_WAIT_REQ;
		break;

	case INIT_XFR_RECV_BYTE_ACK:
		state = INIT_XFR_WAIT_REQ;
		scsi_bus->ctrl_w(scsi_refid, 0, S_ACK);
		break;

	case INIT_XFR_RECV_BYTE_NACK:
		function_complete();
		break;

	case INIT_XFR_SEND_PAD_WAIT_REQ:
		if(!(ctrl & S_REQ))
			break;

		if((ctrl & S_PHASE_MASK) != xfr_phase) {
			command_pos = 0;
			bus_complete();
		} else {
			state = INIT_XFR_SEND_PAD;
			send_byte();
		}
		break;

	case INIT_XFR_SEND_PAD:
		tcount--;
		if(tcount) {
			state = INIT_XFR_SEND_PAD_WAIT_REQ;
			step(false);
		} else
			function_complete();
		break;

	case INIT_XFR_RECV_PAD_WAIT_REQ:
		if(!(ctrl & S_REQ))
			break;

		if((ctrl & S_PHASE_MASK) != xfr_phase) {
			command_pos = 0;
			bus_complete();
		} else {
			state = INIT_XFR_RECV_PAD;
			recv_byte();
		}
		break;

	case INIT_XFR_RECV_PAD:
		tcount--;
		if(tcount) {
			state = INIT_XFR_RECV_PAD_WAIT_REQ;
			scsi_bus->ctrl_w(scsi_refid, 0, S_ACK);
			step(false);
		} else
			function_complete();
		break;

	default:
		logerror("%s: step() unexpected state %d.%d\n",
					tag(),
					state & STATE_MASK, (state & SUB_MASK) >> SUB_SHIFT);
		exit(0);
	}
}
Пример #18
0
int recv_file (int sock) {
    int          recv_len;      // The number of bytes received from a recv
    char        *filename;
    FILE        *fp;            // The local file to write
    uint32_t     file_length;   // The length of the incoming file in bytes
    unsigned int i;
    byte         current_byte;  // The current byte received

    filename = (char *) malloc (MAX_LINE);

    // receive filename
    if (recv_line(sock, filename, MAX_LINE) <= 0) {
        return -1;
    }

    // Receive the incoming file length
    if (recv_uint32(sock, &file_length) <= 0)
        return -1;

    // Ensure that the file exists
    if (file_length == 0) {
        fprintf(stderr, "[!!] Remote file does not exist or is empty\n");
        return -1;
    }

#if DEBUG
    printf("Receiving %s | %d bytes | ... ", filename, file_length);
    fflush(stdout);
#endif

    // If it does exist, open a local copy as binary
    fp = fopen(filename, "wb+");
    if (!fp) {
        return -1;
    }

    // Loop over each byte and write the received byte to the local file
    for (i = 0; i < file_length; ++i) {
        recv_len = recv_byte(sock, &current_byte);
        if (recv_len <= 0) {
            fclose(fp);
            return -1;
        }

#if DEBUG
        printf("\rReceiving %s | %d bytes | %d%%... ", filename, file_length,
                (int) (100 * floor((i + 1) / file_length)));
        fflush(stdout);
#endif
        fwrite(&current_byte, 1, 1, fp);
    }

    // Close the local file when finished
    fclose(fp);
    free(filename);

#if DEBUG
    printf("Done.\n");
#endif
    return 0;
}