Hopefully the last update to the makefile for now. Changes to release mechanism stuff.
[freeems-vanilla.git] / bin / freeemsParser.c
blob1dd09780f2a65579f3649922b35ad722a3960c3d
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!
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 /* TODO split into functions? */
40 int main( int argc, char *argv[] ){
41 if(argc == 1){
42 puts("No argument supplied!! Please supply a file to parse.");
43 }else if(argc == 2){
44 FILE *inputFile;
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]);
50 return 1;
53 fseek(inputFile, 0L, SEEK_END);
54 int length = ftell(inputFile);
55 rewind(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){
88 processed++;
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 */
94 if(insidePacket){
95 /* Increment the counter */
96 startsInsidePacket++;
97 if(currentPacketLength == 0){
98 doubleStartByteOccurances++;
99 // printf("Double start byte occurred following packet number %u\n", packets);
100 }else{
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 */
107 insidePacket = 1;
108 checksum = 0;
109 currentPacketLength = 0;
111 }else if(insidePacket){
112 if(unescapeNext){
113 /* Clear escaped byte next flag */
114 unescapeNext = 0;
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++;
137 }else{
138 /* Otherwise reset and record as data is bad */
139 insidePacket = 0;
140 checksum = 0;
141 currentPacketLength = 0;
142 escapePairMismatches++;
144 }else if(character == ESCAPE_BYTE){
145 /* Set flag to indicate that the next byte should be un-escaped. */
146 unescapeNext = 1;
147 escapeBytesFound++;
148 }else if(character == STOP_BYTE){
149 packets++;
151 /* Bring the checksum back to where it should be */
152 checksum -= lastChar;
154 /* Check that the checksum matches */
155 if(checksum != lastChar){
156 badChecksums++;
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);
158 }else{
159 goodChecksums++;
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);
161 { // process packet
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 */
168 insidePacket = 0;
169 currentPacketLength= 0;
170 checksum = 0;
171 }else{
172 /* If it isn't special checksum it! */
173 checksum += character;
174 lastChar = character;
175 packetBuffer[currentPacketLength] = character;
176 currentPacketLength++;
178 }else{
179 /* Do nothing : drop the byte */
180 charsDropped++;
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]);
211 oCount++;
214 }else{
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