From: <ak...@us...> - 2008-04-13 15:49:10
|
Revision: 873 http://can.svn.sourceforge.net/can/?rev=873&view=rev Author: akhe Date: 2008-04-13 08:49:02 -0700 (Sun, 13 Apr 2008) Log Message: ----------- Fixed bug in sliding window protocol that made an erronious checksum when two DEL's where received inside a frame Modified Paths: -------------- trunk/firmware/common/vscp_serial.c trunk/firmware/common/vscp_serial.h Modified: trunk/firmware/common/vscp_serial.c =================================================================== --- trunk/firmware/common/vscp_serial.c 2008-04-09 12:58:39 UTC (rev 872) +++ trunk/firmware/common/vscp_serial.c 2008-04-13 15:49:02 UTC (rev 873) @@ -125,6 +125,7 @@ if ( VSCP_SERIAL_PROTOCOL_SUBSTATE_ESCAPE == vs_sub_state ) { // Second DLE => it's a DLE character + vs_checksum ^= DLE; vs_msgbuffer[ vs_buffer_cnt++ ] = DLE; vs_sub_state = VSCP_SERIAL_PROTOCOL_SUBSTATE_NONE; } @@ -173,15 +174,15 @@ rv = TRUE; // Ack the frame if ( ( VSCP_SERIAL_OPCODE_ACK != vs_msgbuffer[ 0 ] ) && - ( VSCP_SERIAL_OPCODE_SENT_ACK != vs_msgbuffer[ 0 ] ) ) { - vs_sendAck( vs_msgbuffer[ 2 ], vs_msgbuffer[ 3 ] ); + ( VSCP_SERIAL_OPCODE_SENT_ACK != vs_msgbuffer[ 0 ] ) ) { + //vs_sendAck( vs_msgbuffer[ 2 ], vs_msgbuffer[ 3 ] ); } } else { // Nack the frame if ( ( VSCP_SERIAL_OPCODE_NACK != vs_msgbuffer[ 0 ] ) && ( VSCP_SERIAL_OPCODE_SENT_NACK != vs_msgbuffer[ 0 ] ) ) { - vs_sendNack( vs_msgbuffer[ 2 ], vs_msgbuffer[ 3 ] ); + //vs_sendNack( vs_msgbuffer[ 2 ], vs_msgbuffer[ 3 ] ); } } @@ -197,20 +198,20 @@ } break; - default: + default: // Receiving packet if ( VSCP_SERIAL_PROTOCOL_STATE_PACKET == vs_main_state ) { vs_checksum ^= b; - vs_msgbuffer[ vs_buffer_cnt++ ] = b; + vs_msgbuffer[ vs_buffer_cnt++ ] = b; } - break; + break; } // Check for buffer overflow if ( vs_buffer_cnt > VSCP_SERIAL_FRAME_SIZE ) { // Start all over vs_main_state = VSCP_SERIAL_PROTOCOL_STATE_NONE; - vs_sub_state = VSCP_SERIAL_PROTOCOL_SUBSTATE_NONE; + vs_sub_state = VSCP_SERIAL_PROTOCOL_SUBSTATE_NONE; } return rv; @@ -237,48 +238,91 @@ return TRUE; } + /////////////////////////////////////////////////////////////////////////////// -// vs_sendAck -// +// vs_sendResponse +// +// Sent inline so it can be used inside frame feed routine +// -BOOL vs_sendAck( uint8_t channel, uint8_t seqnumber ) +BOOL vs_sendResponse( uint8_t opcode, uint8_t channel, uint8_t seqnumber ) { uint8_t checksum = 0; - vs_buffer_cnt = 0; - // Start of frame - vs_bufferSerialByte( DLE ); - vs_bufferSerialByte( STX ); + if ( !vs_sendSerialByte( DLE ) ) { + return FALSE; + } + if ( !vs_sendSerialByte( STX ) ) { + return FALSE; + } - // ACK Code - vs_bufferSerialByteSubst( &checksum, VSCP_SERIAL_OPCODE_ACK ); + // opcode Code + if ( !vs_sendSerialByte( opcode ) ) { + return FALSE; + } + checksum ^= opcode; // Flags - vs_bufferSerialByteSubst( &checksum, 0 ); + if ( !vs_sendSerialByte( 0 ) ) { + return FALSE; + } + checksum ^= 0; // Channel - vs_bufferSerialByteSubst( &checksum, channel ); + if ( DLE == channel ) { + vs_sendSerialByte( DLE ); + vs_sendSerialByte( DLE ); + checksum ^= DLE; // Only one is used for checksum calculations + } + else { + vs_sendSerialByte( channel ); + checksum ^= channel; + } // Counter - vs_bufferSerialByteSubst( &checksum, seqnumber ); + if ( DLE == seqnumber ) { + vs_sendSerialByte( DLE ); + vs_sendSerialByte( DLE ); + checksum ^= DLE; // Only one is used for checksum calculations + } + else { + vs_sendSerialByte( seqnumber ); + checksum ^= seqnumber; + } // Checksum - vs_bufferSerialByteSubst( &checksum, checksum ); + if ( DLE == checksum ) { + vs_sendSerialByte( DLE ); + vs_sendSerialByte( DLE ); + } + else { + vs_sendSerialByte( checksum ); + } // End of frame - vs_bufferSerialByte( DLE ); - vs_bufferSerialByte( ETX ); + if ( !vs_sendSerialByte( DLE ) ) { + return FALSE; + } + if ( !vs_sendSerialByte( ETX ) ) { + return FALSE; + } - // Send the buffer content - if ( !vs_sendBuffer( vs_msgbuffer, vs_buffer_cnt ) ) { - vs_buffer_cnt = 0; - return FALSE; - } - vs_buffer_cnt = 0; - - return TRUE; + return TRUE; } + +/////////////////////////////////////////////////////////////////////////////// +// vs_sendAck +// +// Sent inline so it can be used inside frame feed routine +// + +BOOL vs_sendAck( uint8_t channel, uint8_t seqnumber ) +{ + return vs_sendResponse( VSCP_SERIAL_OPCODE_ACK, + channel, + seqnumber ); +} /////////////////////////////////////////////////////////////////////////////// // vs_sendNack @@ -286,42 +330,9 @@ BOOL vs_sendNack( uint8_t channel, uint8_t seqnumber ) { - uint8_t checksum = 0; - - vs_buffer_cnt = 0; - - // Start of frame - vs_bufferSerialByte( DLE ); - vs_bufferSerialByte( STX ); - - // ACK Code - vs_bufferSerialByteSubst( &checksum, VSCP_SERIAL_OPCODE_NACK ); - - // Flags - vs_bufferSerialByteSubst( &checksum, 0 ); - - // Channel - vs_bufferSerialByteSubst( &checksum, channel ); - - // Counter - vs_bufferSerialByteSubst( &checksum, seqnumber ); - - // Checksum - vs_bufferSerialByteSubst( &checksum, checksum ); - - // End of frame - vs_bufferSerialByte( DLE ); - vs_bufferSerialByte( ETX ); - - // Send the buffer content - if ( !vs_sendBuffer( vs_msgbuffer, vs_buffer_cnt ) ) { - vs_buffer_cnt = 0; - return FALSE; - } - - vs_buffer_cnt = 0; - - return TRUE; + return vs_sendResponse( VSCP_SERIAL_OPCODE_NACK, + channel, + seqnumber ); } /////////////////////////////////////////////////////////////////////////////// @@ -365,7 +376,7 @@ vs_bufferSerialByteSubst( &checksum, pFrame->data[ i ] ); } - // Checksum + // Checksum - Note: checksum byte(s) sent before checksum calcuulated so OK vs_bufferSerialByteSubst( &checksum, checksum ); // End of frame @@ -401,7 +412,7 @@ // Check pointer - Must be at least command byte if ( NULL == pData ) return FALSE; - count &= 0x0f; // Max 16 bytes + count &= 0x1f; // Max 16 bytes // Start of frame vs_bufferSerialByte( DLE ); @@ -459,7 +470,7 @@ // Check pointer - must at least be error byte if ( NULL == pData ) return FALSE; - count &= 0x0f; // Max 16 bytes + count &= 0x1f; // Max 16 bytes // Start of frame vs_bufferSerialByte( DLE ); @@ -500,6 +511,7 @@ } + /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// @@ -562,7 +574,7 @@ int i; if ( pSlide->cntOutstanding >= VSCP_SERIAL_MAX_SLIDING_WINDOW_FRAMES ) { - return NULL; + return NULL; } for ( i=0; i<VSCP_SERIAL_MAX_SLIDING_WINDOW_FRAMES; i++ ) { @@ -619,8 +631,9 @@ int i; for ( i=0; i<VSCP_SERIAL_MAX_SLIDING_WINDOW_FRAMES; i++ ) { - if ( ( channel == pSlide->Frames[ i ].frame.channel ) && - ( seqnumber == pSlide->Frames[ i ].frame.seqnumber ) ) { + if ( ( 0 != pSlide->Frames[ i ].timestamp ) && + ( channel == pSlide->Frames[ i ].frame.channel ) && + ( seqnumber == pSlide->Frames[ i ].frame.seqnumber ) ) { pSlide->Frames[ i ].timestamp = 0; pSlide->Frames[ i ].send_count = 0; pSlide->cntOutstanding--; // Another frame removed Modified: trunk/firmware/common/vscp_serial.h =================================================================== --- trunk/firmware/common/vscp_serial.h 2008-04-09 12:58:39 UTC (rev 872) +++ trunk/firmware/common/vscp_serial.h 2008-04-13 15:49:02 UTC (rev 873) @@ -60,7 +60,7 @@ #define STX 0x01 // Start of 'text' #define ETX 0x02 // End of 'text' -#define VSCP_SERIAL_FRAME_SIZE 27 // Max frame size +#define VSCP_SERIAL_FRAME_SIZE 23 // Max frame size #define VSCP_SERIAL_BUFFER_SIZE VSCP_SERIAL_FRAME_SIZE * 2 // Protocol state machine @@ -146,7 +146,7 @@ Send a character on the serial line. If its better to send a chunk of data just collect data in this routine and - do the actial send with vs_sendFrame. + do the actual send with vs_sendFrame. @param b Byte to send. @return TRUE on success, FALSE on failure. */ @@ -207,6 +207,17 @@ BOOL vs_getFrame( vs_frame *pFrame ); /*! + Send ACK/NACK response + @param opcode Either ACK or NACK opcode. + @param channel Channel number ACK is sent for. + @param seqnumber Id for packet which is ACK'ed + @return TRUE och success. FALSE on failure. +*/ +BOOL vs_sendResponse( uint8_t opcode, + uint8_t channel, + uint8_t seqnumber ); + +/*! Send ACK @param channel Channel number ACK is sent for. @param seqnumber Id for packet whcih is ACK'ed This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |