1 /* FreeEMS - the open source engine management system
3 * Copyright 2009-2012 Fred Cooke
5 * This file is part of the FreeEMS project.
7 * FreeEMS software is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * FreeEMS software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with any FreeEMS software. If not, see http://www.gnu.org/licenses/
20 * We ask that if you make any changes to this file you email them upstream to
21 * us at admin(at)diyefi(dot)org or, even better, fork the code on github.com!
23 * Thank you for choosing FreeEMS to run your engine!
30 /* Special byte definitions */
31 #define ESCAPE_BYTE 0xBB
32 #define START_BYTE 0xAA
33 #define STOP_BYTE 0xCC
34 #define ESCAPED_ESCAPE_BYTE 0x44
35 #define ESCAPED_START_BYTE 0x55
36 #define ESCAPED_STOP_BYTE 0x33
39 #define MAXIMUM_EXPECTED_PACKET_LENGTH 0x0820
41 /* TODO split into functions? */
42 int main( int argc
, char *argv
[] ){
44 puts("No argument supplied!! Please supply a file to parse.");
47 inputFile
= fopen(argv
[1], "rb");
49 /* Could not open file */
50 if(inputFile
== NULL
){
51 printf("Error opening file %s, please check the name and try again!\n", argv
[1]);
55 fseek(inputFile
, 0L, SEEK_END
);
56 int length
= ftell(inputFile
);
58 printf("The length of file %s is %u\n\n", argv
[1], length
);
59 printf("Attempting to parse file...\n\n");
61 /* Statistic collection variables */
62 unsigned int packets
= 0;
63 unsigned int charsDropped
= 0;
64 unsigned int badChecksums
= 0;
65 unsigned int goodChecksums
= 0;
66 unsigned int startsInsidePacket
= 0;
67 unsigned int totalFalseStartLost
= 0;
68 unsigned int doubleStartByteOccurances
= 0;
69 unsigned int strayDataBytesOccurances
= 0;
70 unsigned int escapeBytesFound
= 0;
71 unsigned int escapedStopBytesFound
= 0;
72 unsigned int escapedStartBytesFound
= 0;
73 unsigned int escapedEscapeBytesFound
= 0;
74 unsigned int escapePairMismatches
= 0;
75 unsigned long sumOfGoodPacketLengths
= 0;
77 /* Loop and state variables */
78 unsigned char insidePacket
= 0;
79 unsigned char unescapeNext
= 0;
80 unsigned int processed
= 0;
81 unsigned char checksum
= 0;
82 unsigned char lastChar
= 0;
83 unsigned int currentPacketLength
= 0;
85 // To store a packet in for purposes of further diagnostics
86 unsigned char packetBuffer
[MAXIMUM_EXPECTED_PACKET_LENGTH
]; // more than sufficient for current FreeEMS increase for other variants.
87 unsigned short packetTypeCounts
[65536] = {0}; // upto 65535 of each type, then it'll overflow...
89 /* Iterate through the file char at a time */
90 while(processed
< length
){
92 unsigned char character
= fgetc(inputFile
);
94 /* Look for a start byte to indicate a new packet */
95 if(character
== START_BYTE
){
96 /* If we are had already found a start byte */
98 /* Increment the counter */
100 if(currentPacketLength
== 0){
101 doubleStartByteOccurances
++;
102 // printf("Double start byte occurred following packet number %u\n", packets);
104 totalFalseStartLost
+= currentPacketLength
; // remember how much we lost
105 strayDataBytesOccurances
++;
106 // printf("Stray data or unfinished packet found following packet number %u\n", packets);
109 /* Reset to us using it unless someone else was */
112 currentPacketLength
= 0;
114 }else if(insidePacket
){
116 /* Clear escaped byte next flag */
119 if(character
== ESCAPED_ESCAPE_BYTE
){
120 /* Store and checksum escape byte */
121 checksum
+= ESCAPE_BYTE
;
122 lastChar
= ESCAPE_BYTE
;
123 escapedEscapeBytesFound
++;
124 packetBuffer
[currentPacketLength
] = ESCAPE_BYTE
;
125 currentPacketLength
++;
126 }else if(character
== ESCAPED_START_BYTE
){
127 /* Store and checksum start byte */
128 checksum
+= START_BYTE
;
129 lastChar
= START_BYTE
;
130 escapedStartBytesFound
++;
131 packetBuffer
[currentPacketLength
] = START_BYTE
;
132 currentPacketLength
++;
133 }else if(character
== ESCAPED_STOP_BYTE
){
134 /* Store and checksum stop byte */
135 checksum
+= STOP_BYTE
;
136 lastChar
= STOP_BYTE
;
137 escapedStopBytesFound
++;
138 packetBuffer
[currentPacketLength
] = STOP_BYTE
;
139 currentPacketLength
++;
141 /* Otherwise reset and record as data is bad */
144 currentPacketLength
= 0;
145 escapePairMismatches
++;
147 }else if(character
== ESCAPE_BYTE
){
148 /* Set flag to indicate that the next byte should be un-escaped. */
151 }else if(character
== STOP_BYTE
){
154 /* Bring the checksum back to where it should be */
155 checksum
-= lastChar
;
157 /* Check that the checksum matches */
158 if(checksum
!= lastChar
){
160 printf("Packet number %u ending of length %u at char number %u failed checksum! Received %u Calculated %u\n", packets
, currentPacketLength
, processed
, lastChar
, checksum
);
163 /* Add the length to the SUM */
164 sumOfGoodPacketLengths
+= currentPacketLength
;
166 // printf("Packet number %u ending of length %u at char number %u checked out OK! Received %u Calculated %u\n", packets, currentPacketLength, processed, lastChar, checksum);
168 // Increment count for packet type that it is
169 unsigned short packetType
= packetBuffer
[1] * 256 + packetBuffer
[2];
170 packetTypeCounts
[packetType
]++;
173 /* Clear the state */
175 currentPacketLength
= 0;
178 if (currentPacketLength
< MAXIMUM_EXPECTED_PACKET_LENGTH
) {
179 /* If it isn't special checksum it! */
180 checksum
+= character
;
181 lastChar
= character
;
182 packetBuffer
[currentPacketLength
] = character
;
183 currentPacketLength
++;
186 /* Clear the state */
188 currentPacketLength
= 0;
190 // TODO count overlength packets, just print for now:
191 printf("Overlength packet found, resetting state!");
195 /* Do nothing : drop the byte */
200 printf("Data stream statistics :\n");
202 printf("\nPackets and checksums :\n");
203 printf("%u packets were found\n", packets
);
204 printf("%u had good checksums\n", goodChecksums
);
205 printf("%u had incorrect checksums\n", badChecksums
);
207 printf("\nGeneral issues :\n");
208 printf("%u leading characters were dropped\n", charsDropped
);
209 printf("%u false starts occurred\n", startsInsidePacket
);
210 printf("%u double start bytes occurred\n", doubleStartByteOccurances
);
211 printf("%u stray part packets occurred\n", strayDataBytesOccurances
);
212 printf("%u chars lost from false starts \n", totalFalseStartLost
);
214 printf("\nEscaped byte profile :\n");
215 printf("%u escape bytes were found\n", escapeBytesFound
);
216 printf("%u escaped stop bytes were found\n", escapedStopBytesFound
);
217 printf("%u escaped start bytes were found\n", escapedStartBytesFound
);
218 printf("%u escaped escape bytes were found\n", escapedEscapeBytesFound
);
219 printf("%u escape pairs were mismatched\n", escapePairMismatches
);
221 printf("\nReport counts for all non-zero packet types\n");
222 unsigned long oCount
= 0;
223 while(oCount
< 65536){
224 if(packetTypeCounts
[oCount
] != 0){
225 printf(" Packet of type %#.4x / %u was found %u times!\n", oCount
, oCount
, packetTypeCounts
[oCount
]);
230 printf("\nGood packet length stats :\n");
231 printf("%u total sum of good packet bytes\n", sumOfGoodPacketLengths
);
232 printf("%u average good packet length (with remainder of %u)\n", (sumOfGoodPacketLengths
/ goodChecksums
), (sumOfGoodPacketLengths
% goodChecksums
));
235 /* Subtract one to eliminate command name. */
236 printf("Wrong number of arguments!! Was %u should be 1...\n", argc
- 1);
238 return 0; // non-zero = error