Refactor the Makefile into pieces. This commit inspired by AncientGeek, my hatred...
[freeems-vanilla.git] / bin / freeemsParser.c
blobd2bf21c9c7668764173d18551e9f762cd9256c4e
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!
27 #include <stdio.h>
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[] ){
43 if(argc == 1){
44 puts("No argument supplied!! Please supply a file to parse.");
45 }else if(argc == 2){
46 FILE *inputFile;
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]);
52 return 1;
55 fseek(inputFile, 0L, SEEK_END);
56 int length = ftell(inputFile);
57 rewind(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){
91 processed++;
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 */
97 if(insidePacket){
98 /* Increment the counter */
99 startsInsidePacket++;
100 if(currentPacketLength == 0){
101 doubleStartByteOccurances++;
102 // printf("Double start byte occurred following packet number %u\n", packets);
103 }else{
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 */
110 insidePacket = 1;
111 checksum = 0;
112 currentPacketLength = 0;
114 }else if(insidePacket){
115 if(unescapeNext){
116 /* Clear escaped byte next flag */
117 unescapeNext = 0;
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++;
140 }else{
141 /* Otherwise reset and record as data is bad */
142 insidePacket = 0;
143 checksum = 0;
144 currentPacketLength = 0;
145 escapePairMismatches++;
147 }else if(character == ESCAPE_BYTE){
148 /* Set flag to indicate that the next byte should be un-escaped. */
149 unescapeNext = 1;
150 escapeBytesFound++;
151 }else if(character == STOP_BYTE){
152 packets++;
154 /* Bring the checksum back to where it should be */
155 checksum -= lastChar;
157 /* Check that the checksum matches */
158 if(checksum != lastChar){
159 badChecksums++;
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);
161 }else{
162 goodChecksums++;
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);
167 { // process packet
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 */
174 insidePacket = 0;
175 currentPacketLength= 0;
176 checksum = 0;
177 }else{
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++;
184 }else{
185 charsDropped++;
186 /* Clear the state */
187 insidePacket = 0;
188 currentPacketLength= 0;
189 checksum = 0;
190 // TODO count overlength packets, just print for now:
191 printf("Overlength packet found, resetting state!");
194 }else{
195 /* Do nothing : drop the byte */
196 charsDropped++;
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]);
227 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));
234 }else{
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