1 /* FreeEMS - the open source engine management system
3 * Copyright 2009, 2010 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 /* TODO split into functions? */
40 int main( int argc
, char *argv
[] ){
42 puts("No argument supplied!! Please supply a file to parse.");
45 inputFile
= fopen(argv
[1], "rb");
47 /* Could not open file */
48 if(inputFile
== NULL
){
49 printf("Error opening file %s, please check the name and try again!\n", argv
[1]);
53 fseek(inputFile
, 0L, SEEK_END
);
54 int length
= ftell(inputFile
);
56 printf("The length of file %s is %u\n\n", argv
[1], length
);
57 printf("Attempting to parse file...\n\n");
59 /* Statistic collection variables */
60 unsigned int packets
= 0;
61 unsigned int charsDropped
= 0;
62 unsigned int badChecksums
= 0;
63 unsigned int goodChecksums
= 0;
64 unsigned int startsInsidePacket
= 0;
65 unsigned int totalFalseStartLost
= 0;
66 unsigned int doubleStartByteOccurances
= 0;
67 unsigned int strayDataBytesOccurances
= 0;
68 unsigned int escapeBytesFound
= 0;
69 unsigned int escapedStopBytesFound
= 0;
70 unsigned int escapedStartBytesFound
= 0;
71 unsigned int escapedEscapeBytesFound
= 0;
72 unsigned int escapePairMismatches
= 0;
74 /* Loop and state variables */
75 unsigned char insidePacket
= 0;
76 unsigned char unescapeNext
= 0;
77 unsigned int processed
= 0;
78 unsigned char checksum
= 0;
79 unsigned char lastChar
= 0;
80 unsigned int currentPacketLength
= 0;
82 // To store a packet in for purposes of further diagnostics
83 unsigned char packetBuffer
[3000]; // more than sufficient for current FreeEMS increase for other variants.
84 unsigned short packetTypeCounts
[65536]; // upto 65535 of each type, then it'll overflow...
86 /* Iterate through the file char at a time */
87 while(processed
< length
){
89 unsigned char character
= fgetc(inputFile
);
91 /* Look for a start byte to indicate a new packet */
92 if(character
== START_BYTE
){
93 /* If we are had already found a start byte */
95 /* Increment the counter */
97 if(currentPacketLength
== 0){
98 doubleStartByteOccurances
++;
99 // printf("Double start byte occurred following packet number %u\n", packets);
101 totalFalseStartLost
+= currentPacketLength
; // remember how much we lost
102 strayDataBytesOccurances
++;
103 // printf("Stray data or unfinished packet found following packet number %u\n", packets);
106 /* Reset to us using it unless someone else was */
109 currentPacketLength
= 0;
111 }else if(insidePacket
){
113 /* Clear escaped byte next flag */
116 if(character
== ESCAPED_ESCAPE_BYTE
){
117 /* Store and checksum escape byte */
118 checksum
+= ESCAPE_BYTE
;
119 lastChar
= ESCAPE_BYTE
;
120 escapedEscapeBytesFound
++;
121 packetBuffer
[currentPacketLength
] = ESCAPE_BYTE
;
122 currentPacketLength
++;
123 }else if(character
== ESCAPED_START_BYTE
){
124 /* Store and checksum start byte */
125 checksum
+= START_BYTE
;
126 lastChar
= START_BYTE
;
127 escapedStartBytesFound
++;
128 packetBuffer
[currentPacketLength
] = START_BYTE
;
129 currentPacketLength
++;
130 }else if(character
== ESCAPED_STOP_BYTE
){
131 /* Store and checksum stop byte */
132 checksum
+= STOP_BYTE
;
133 lastChar
= STOP_BYTE
;
134 escapedStopBytesFound
++;
135 packetBuffer
[currentPacketLength
] = STOP_BYTE
;
136 currentPacketLength
++;
138 /* Otherwise reset and record as data is bad */
141 currentPacketLength
= 0;
142 escapePairMismatches
++;
144 }else if(character
== ESCAPE_BYTE
){
145 /* Set flag to indicate that the next byte should be un-escaped. */
148 }else if(character
== STOP_BYTE
){
151 /* Bring the checksum back to where it should be */
152 checksum
-= lastChar
;
154 /* Check that the checksum matches */
155 if(checksum
!= lastChar
){
157 printf("Packet number %u ending of length %u at char number %u failed checksum! Received %u Calculated %u\n", packets
, currentPacketLength
, processed
, lastChar
, checksum
);
160 // 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);
162 // Increment count for packet type that it is
163 unsigned short packetType
= packetBuffer
[1] * 256 + packetBuffer
[2];
164 packetTypeCounts
[packetType
]++;
167 /* Clear the state */
169 currentPacketLength
= 0;
172 /* If it isn't special checksum it! */
173 checksum
+= character
;
174 lastChar
= character
;
175 packetBuffer
[currentPacketLength
] = character
;
176 currentPacketLength
++;
179 /* Do nothing : drop the byte */
184 printf("Data stream statistics :\n");
186 printf("\nPackets and checksums :\n");
187 printf("%u packets were found\n", packets
);
188 printf("%u had good checksums\n", goodChecksums
);
189 printf("%u had incorrect checksums\n", badChecksums
);
191 printf("\nGeneral issues :\n");
192 printf("%u leading characters were dropped\n", charsDropped
);
193 printf("%u false starts occurred\n", startsInsidePacket
);
194 printf("%u double start bytes occurred\n", doubleStartByteOccurances
);
195 printf("%u stray part packets occurred\n", strayDataBytesOccurances
);
196 printf("%u chars lost from false starts \n", totalFalseStartLost
);
198 printf("\nEscaped byte profile :\n");
199 printf("%u escape bytes were found\n", escapeBytesFound
);
200 printf("%u escaped stop bytes were found\n", escapedStopBytesFound
);
201 printf("%u escaped start bytes were found\n", escapedStartBytesFound
);
202 printf("%u escaped escape bytes were found\n", escapedEscapeBytesFound
);
203 printf("%u escape pairs were mismatched\n", escapePairMismatches
);
205 printf("\nReport counts for all non-zero packet types\n");
206 unsigned long oCount
= 0;
207 while(oCount
< 65536){
208 if(packetTypeCounts
[oCount
] != 0){
209 printf(" Packet of type %#.4x / %u was found %u times!\n", oCount
, oCount
, packetTypeCounts
[oCount
]);
215 /* Subtract one to eliminate command name. */
216 printf("Wrong number of arguments!! Was %u should be 1...\n", argc
- 1);
218 return 0; // non-zero = error