static int SetBaudSender( void ) { int data; /* storing sync string data to other machine */ int i; /* loop index */ int wait_time; if( !SenderHandshake() ) return( FAIL ); /* sync byte received ... send string */ StartBlockTrans(); for( i = data = 0; i < SYNC_LEN; i++, data = (data + SYNC_INC) & 0xff ) { SendByte( data ); /* send sync string bytes */ } StopBlockTrans(); wait_time = WaitCount() + SYNC_TIME_OUT; /* limit for time out */ /* If MaxBaud == MIN_BAUD, we're talking over a modem and it might have buffered characters that haven't been transmitted yet. */ if( MaxBaud == MIN_BAUD ) wait_time += SEC(2); for( ;; ) { if( WaitByte( 1 ) == SDATA_TAK ) { SendByte( SDATA_ACK ); if( WaitByte( SEC(1)/2 ) == SDATA_TAK ) { return( SUCCESS ); } else { return( FAIL ); } } else if( WaitCount() >= wait_time ) { /* break not found; other end have not acknowledged string */ return( FAIL ); } } }
static void SlowSend( int ch ) { SendByte( ch ); if( WaitByte( 1 ) != SDATA_NO_DATA ) { Wait( 1 ); /* pickup echoed character */ } }
static int SetBaud( int baud_index, int *sync_point_p ) { int reply; /* storing data received from other machine */ int sync_point; sync_point = *sync_point_p; *sync_point_p += MAX_BAUD_SET_TICKS + 3*SYNC_SLOP; if( !Baud( baud_index ) ) return( FAIL ); /* sets up baud rate */ SyncPoint( sync_point ); ClearCom(); Wait( SYNC_SLOP ); SendByte( SDATA_HI ); reply = WaitByte( SYNC_SLOP * 2 ); if( reply != SDATA_HI ) { return( FAIL ); } /* now go the other way */ *sync_point_p += BaudTable[ baud_index ].full_test_ticks; #ifdef SERVER if( !SetBaudReceiver() ) return( FAIL ); if( !SetBaudSender() ) return( FAIL ); #else if( !SetBaudSender() ) return( FAIL ); if( !SetBaudReceiver() ) return( FAIL ); #endif return( SUCCESS ); }
bool MarchToTheSameDrummer( void ) { int got; #ifdef SERVER SendByte( SDATA_LOK ); #else if( ( got = WaitByte( SEC( 2 ) ) ) != SDATA_LOK ) { return( FAIL ); } #endif #ifndef SERVER SendByte( SDATA_ACK ); #else if( ( got = WaitByte( SEC(1)/2 ) ) != SDATA_ACK ) { return( FAIL ); } #endif Wait( 1 ); /* don't go till the timer hits exactly on the tick */ ZeroWaitCount(); return( SUCCESS ); }
bool SetSyncTime( void ) { if( MaxBaud != MIN_BAUD ) { if( !Baud( LOW_BAUD ) ) return( FAIL ); } #ifdef SERVER if( WaitByte( SEC(1)/10 ) != SDATA_HI ) { return( FAIL ); } #else SendByte( SDATA_HI ); #endif return( MarchToTheSameDrummer() ); }
static int CheckSyncString( void ) { int syn_c; /* correct sync string bytes value */ int i; /* loop index */ unsigned wait; if( CheckPendingError() ) return( FAIL ); wait = (MaxBaud == MIN_BAUD) ? SEC(2) : (SEC(1)/4); for( syn_c = i = 0; i < SYNC_LEN; ++i, syn_c = (syn_c + SYNC_INC) & 0xff ) { if( WaitByte( wait ) != syn_c ) { /* error -- timeout or incorrect data */ return( FAIL ); } wait = SEC(1)/4; } return( SUCCESS ); }
static int SenderHandshake( void ) { unsigned wait_time; /* used to test for time-out */ int reply; /* storing data received from other machine */ wait_time = WaitCount() + SYNC_TIME_OUT; /* limit for time out */ if( MaxBaud == MIN_BAUD ) wait_time += SEC(1); SendByte( SYNC_BYTE ); /* send SYNC_BYTE */ for( ;; ) { /* loop until ACK received or time out */ reply = WaitByte( 1 ); /* get reply */ if( reply == SDATA_ACK ) break; /* ACK received; go to next operation */ if( reply == SDATA_HI ) { /* return HI received */ SendByte( SDATA_HI ); } else if( WaitCount() > wait_time ) { /* time out */ return( FAIL ); } /* not yet time out; loop */ } SendByte( SYNC_END ); return( SUCCESS ); }
static int WaitReceive( byte *err, trap_elen max_len, byte *p, unsigned timeout ) { unsigned wait_time; /* timer */ int data; /* data from other machine */ int result; /* result of BlockReceive() */ ZeroWaitCount(); wait_time = WaitCount() + timeout; for( ;; ) { data = WaitByte( 1 ); if( data == SDATA_STX ) { /* STX received, get block */ result = BlockReceive( err, max_len, p ); if( result ) return( result ); } else if( data == SDATA_RLR ) { /* RLR received */ SendByte( SDATA_NAK ); /* tell the other end to resend block */ } else if( (timeout != FOREVER) && (WaitCount() >= wait_time) ) { return( FAIL ); /* time-out */ } } }
static int SetBaudReceiver( void ) { unsigned wait; if( !ReceiverHandshake() ) return( FAIL ); /* sync string should have been received; and in receive buffer now CheckSyncString() checks if sync string is received successfully */ if( CheckSyncString() ) { SendByte( SDATA_TAK ); wait = (MaxBaud == MIN_BAUD) ? SEC(2) : SEC(1)/2; if( WaitByte( wait ) == SDATA_ACK ) { SendByte( SDATA_TAK ); return( SUCCESS ); } else { return( FAIL ); } } else { return( FAIL ); } }
static int ReceiverHandshake( void ) { int reply; /* storing data received from other machine */ int wait_time; wait_time = WaitCount() + SYNC_TIME_OUT; if( MaxBaud == MIN_BAUD ) wait_time += SEC(1); for( ;; ) { /* loop until SYNC_END received or time out */ reply = WaitByte( 1 ); /* get character */ if( reply == SYNC_END ) break; /* SYNC_END received; continue */ if( reply == SYNC_BYTE ) { /* SYNC_BYTE received; send ACK */ SendByte( SDATA_ACK ); } else if( reply == SDATA_HI ) { /* return HI received */ SendByte( SDATA_HI ); } else if( WaitCount() >= wait_time ) { /* 2 sec time out */ return( FAIL ); } /* not yet time out; loop */ } return( SUCCESS ); }
int GetByte() { return( WaitByte( 0 ) ); }
int GetByte( void ) { return( WaitByte( 0 ) ); }
static char *SetupModem( char *parm ) { char *start; unsigned wait; unsigned ch; int data; Baud( MaxBaud ); wait = SEC(3); while( *parm == ' ' && *parm == '\t' ) ++parm; if( *parm == '\0' ) return( NULL ); for( ;; ) { if( *parm == '(' ) { start = ++parm; for( ;; ) { ch = *parm; if( ch == '\0' ) goto done; ++parm; if( ch == ')' ) break; if( ch == '\\' ) { ch = *parm++; switch( ch ) { case '\0': return( TRP_ERR_invalid_modem_string ); case 'r': ch = '\r'; break; case 'n': ch = '\n'; break; } } data = WaitByte( wait ); if( data == SDATA_NO_DATA ) { if( wait != SEC(60) ) { wait = SEC(60); } else { return( TRP_ERR_timeout_on_modem_string ); } --parm; } else { wait = SEC(3); if( data != ch ) parm = start; } } } else { Wait( SEC(1)/5 ); for( ;; ) { ch = *parm; if( ch == '\0' ) goto done; if( ch == '(' ) break; ++parm; if( ch == '\\' ) { ch = *parm++; switch( ch ) { case '\0': return( TRP_ERR_invalid_modem_string ); case '`': Wait( 1 ); break; case '~': Wait( SEC(1) ); break; case 'r': SlowSend( '\r' ); Wait( SEC(1)/2 ); break; case 'n': SlowSend( '\n' ); break; default: SlowSend( ch ); break; } } else { SlowSend( ch ); } } } } done: #ifdef SERVER #define SEND_CHAR '=' #define EXPECT_CHAR '-' #else #define SEND_CHAR '-' #define EXPECT_CHAR '=' #endif wait = 1; for( ;; ) { data = WaitByte( wait ); if( data == EXPECT_CHAR ) break; if( data == SDATA_NO_DATA ) { if( wait != SEC(10) ) { wait = SEC(10); SendByte( SEND_CHAR ); } else { return( TRP_ERR_modem_failed_connection ); } } } if( wait != SEC(10) ) SendByte( SEND_CHAR ); return( NULL ); }
static int BlockReceive( byte *err, trap_elen max_len, byte *p ) { byte buffer[8]; /* storing bytes other than actual data from blocks */ trap_elen i; /* loop index */ trap_elen len; word crc_val; unsigned blkno; int c; int wait; ZeroWaitCount(); BytesReceived = 0; wait = (MaxBaud == MIN_BAUD) ? SEC(1)/2 : SEC(1)/4; /* Receiving bytes before actual data (up to err byte) */ for( i = 1; i <= 7; ++i ) { c = WaitByte( wait ); if( c == SDATA_NO_DATA ) { /* time-out error */ LastResponse = SDATA_NAK; SendByte( SDATA_NAK ); /* send NAK to request resending of block */ return( FAIL ); } buffer[i] = c; } len = (buffer[MLEN+1] << 8) | buffer[MLEN]; /* number of data bytes */ if( len > max_len ) { /* not enough buffer space to store data */ ClearCom(); return( FAIL ); } /* Receiving actual data bytes */ for( i = 0; i < len; ++i ) { c = WaitByte( wait ); if( c == SDATA_NO_DATA ) { /* time-out error */ LastResponse = SDATA_NAK; SendByte( SDATA_NAK ); /* send NAK to request resending of block */ return( FAIL ); } p[i] = c; } /* Receiving the last byte: ETX */ buffer[0] = WaitByte( wait ); if( buffer[0] != SDATA_ETX ) { /* time-out error */ LastResponse = SDATA_NAK; SendByte( SDATA_NAK ); /* send NAK to request resending of block */ return( FAIL ); } *err = buffer[MERR]; /* storing command byte */ blkno = (buffer[MBLKNO+1] << 8) | buffer[MBLKNO]; /* blk# received */ crc_val = (buffer[MCRC+1] << 8) | buffer[MCRC]; /* crc received */ if( CRC( &buffer[MBLKNO], len, p ) != crc_val ) { /* CRC error */ LastResponse = SDATA_NAK; SendByte( SDATA_NAK ); /* send NAK to request resending of block */ return( FAIL ); } if( ReceiveBlkNo != blkno ) { /* incorrect block */ ClearCom(); LastResponse = SDATA_ACK; SendByte( SDATA_ACK ); return( FAIL ); } /* Block received successfully */ LastResponse = SDATA_ACK; SendByte( SDATA_ACK ); ++ReceiveBlkNo; BytesReceived = len; return( SUCCESS ); }
static int BlockSend( trap_elen num, byte *p, unsigned timeout ) { word crc_value; /* crc value of block */ unsigned wait_time; /* timer for testing time-out */ trap_elen i; /* loop index */ int reply; /* reply message from other machine */ unsigned char crc_low, crc_hi; unsigned char len_low, len_hi; byte extra[3]; /* ..[0]=blkno_low, ..[1]=blkno_hi, ..[2]=err */ unsigned wait; ZeroWaitCount(); extra[2] = PrevErrors = Errors; if( Errors > 255 ) { extra[2] = 255; /* because it is a char, not an int */ } Errors = 0; ClearCom(); /* compose send buffer contents */ len_low = num & 0xff; /* low 8 bits of data block length */ len_hi = num >> 8; /* high 8 bits of data block length */ extra[0] = SendBlkNo & 0xff; /* low 8 bits of send block no */ extra[1] = SendBlkNo >> 8; /* high 8 bits of send block no */ crc_value = CRC( extra, num, p ); /* calculate crc for (blk#+err+data) */ crc_low = crc_value & 0xff; /* low 8 bits of crc_value */ crc_hi = crc_value >> 8; /* high 8 bits of crc_value */ wait = (MaxBaud == MIN_BAUD) ? SEC(2) : SEC(1); for( ;; ) { /* send block loop */ /* send the block */ StartBlockTrans(); SendByte( SDATA_STX ); SendByte( crc_low ); SendByte( crc_hi ); SendByte( len_low ); SendByte( len_hi ); SendByte( extra[0] ); /* blkno_low */ SendByte( extra[1] ); /* blkno_hi */ SendByte( extra[2] ); /* err */ for( i = 0; i < num; ++i ) { SendByte( p[i] ); } SendByte( SDATA_ETX ); StopBlockTrans(); wait_time = WaitCount() + timeout; for( ;; ) { /* wait proper acknowledgement loop */ reply = WaitByte( wait ); /* receive reply */ if( reply == SDATA_NO_DATA ) { if( (timeout != FOREVER) && (WaitCount() >= wait_time) ) { return( FAIL ); /* time-out */ } else { SendByte( SDATA_RLR ); /* request last response */ ++Errors; /* increment error counter */ } } else { if( reply == SDATA_ACK ) { ++SendBlkNo; return( SUCCESS ); /* done, exit from BlockSend() */ } else if( reply == SDATA_NAK ) { /* unsuccessful, re-send block */ ++Errors; break; /* break out of acknowledgement loop; i.e. back to send block loop */ } else if( reply == SDATA_RLR ) { /* request last response */ SendByte( LastResponse ); break; /* break out ackno loop; re-send block */ } else { /* things are totally messed up */ while( WaitByte( SEC(3)/4 ) != SDATA_NO_DATA ) ; /* discard all characters sent */ SendByte( SDATA_RLR ); /* request last response */ ++Errors; } } } } }