|
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.
|