1 /* Open Log Viewer
2 *
3 * Copyright 2011
4 *
5 * This file is part of the OpenLogViewer project.
6 *
7 * OpenLogViewer 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.
11 *
12 * OpenLogViewer 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.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with any OpenLogViewer software. If not, see http://www.gnu.org/licenses/
19 *
20 * I ask that if you make any changes to this file you fork the code on github.com!
21 *
22 */
23 package org.diyefi.openlogviewer.decoder;
24
25 import java.io.File;
26 import java.io.FileInputStream;
27 import java.io.IOException;
28 import org.diyefi.openlogviewer.genericlog.GenericLog;
29
30 /**
31 *
32 * @author Bryan
33 */
34 public class FreeEMSByteLA implements Runnable { // implements runnable to make this class theadable
35
36 private final short ESCAPE_BYTE = 0xBB;// for unsigned byte
37 private final short START_BYTE = 0xAA;// for unsigned byte
38 private final short STOP_BYTE = 0xCC;// for unsigned byte
39 private final short ESCAPED_ESCAPE_BYTE = 0x44;// for unsigned byte
40 private final short ESCAPED_START_BYTE = 0x55;// for unsigned byte
41 private final short ESCAPED_STOP_BYTE = 0x33;// for unsigned byte
42
43 private short[] wholePacket;// for unsigned byte
44 private File logFile;
45 private FileInputStream logStream;
46 private boolean startFound;
47 private GenericLog decodedLog;
48 private Thread t;
49
50 String[] headers = {
51 "PTIT", "T0", "T1", "T2", "T3", "T4", "T5", "T6", "T7"
52 }; //This needs to be converted to resourses or gathered externally at some point
53
54 // NO default constructor, a file or path to a file MUST be given
55 // Reason: File()'s constructors are ambiguous cannot give a null value
56 /**
57 * FreeEmsBin Constructor: <code>String</code> path to your binary log
58 * @param String path
59 *
60 */
61 public FreeEMSByteLA(String path) {
62
63 this(new File(path));
64
65
66 }
67
68 /**
69 * FreeEmsBin Constructor: <code>File</code> object of your Binary log
70 * @param File f
71 */
72 public FreeEMSByteLA(File f) {
73 logFile = f;
74 startFound = false;
75 wholePacket = new short[3000];
76 decodedLog = new GenericLog(headers);
77
78 t = new Thread(this, "FreeEMSByteLA Loading");
79 t.setPriority(Thread.MAX_PRIORITY);
80 t.start();
81
82 }
83
84
85
86 /**
87 * DecodeLog will use the current <code>logFile</code> parse through it and when required pass the job <br>
88 * to the required method of this class such as decodePacket or checksum.
89 */
90 //public void decodeLog() {
91 public void run() {
92 try {
93 // file setup
94 byte[] readByte = new byte[1];
95 short uByte = 0;// uByte stands for UNSIGNED BYTE
96
97 startFound = false;
98 logStream = new FileInputStream(logFile);
99 decodedLog.setLogStatus(GenericLog.LOG_LOADING);
100 int packetLength = 0;
101 while (logStream.read(readByte) != -1) {
102 uByte = (short) (readByte[0] & 0xff); // mask the byte in case something screwey happens
103 if (uByte == START_BYTE) {
104 if (!startFound) {
105 startFound = true;
106 } else {
107 //TO-DO: find something to put here
108 }
109 } else if (startFound) { // do NOTHING until a start is found
110
111 if (uByte == STOP_BYTE) {
112 if (checksum(wholePacket, packetLength)) {
113 decodePacket(wholePacket, packetLength);
114 startFound = false;
115 }
116 packetLength = 0;
117 } else if (uByte == ESCAPE_BYTE) {
118 if (logStream.read(readByte) != -1) { // read in the next byte, as it is to be escaped
119 uByte = unEscapeByte((short) (readByte[0] & 0xff)); // unescape this byte
120 if (uByte != (short) -1) {
121 wholePacket[packetLength] = uByte; // add the escaped byte to a temp storage area for processing later
122 packetLength++;
123
124 } else {
125 startFound = false; // Data was bad, the rest of the data should be ignored
126 }
127 }
128 } else {
129 wholePacket[packetLength] = uByte; // add the info to a temp storage area for processing later
130 packetLength++;
131 }
132 }
133 //else-> No else because if the start byte or start found conditions
134 // were not met then ignore data untill start is found due to a packet being bad
135 }
136 decodedLog.setLogStatus(1);
137
138
139 } catch (IOException IOE) {
140 System.out.println(IOE.getMessage());
141 //TO-DO: Add code to handle or warn of the error
142
143 }
144
145 }
146
147 /**
148 * This method decodes a packet by splitting up the data into larger datatypes to keep the unsigned info <br>
149 * This method could probably use a litle work
150 * @param packet is a <code>short</code> array containing 1 full packet
151 *
152 */
153 private void decodePacket(short[] packet, int length) {
154 int PTIT = (int)packet[3];
155 int T0 = 0;
156 int T1 = 0;
157 int T2 = 0;
158 int T3 = 0;
159 int T4 = 0;
160 int T5 = 0;
161 int T6 = 0;
162 int T7 = 0;
163 decodedLog.addValue("PTIT", PTIT);
164
165 if((PTIT % 2) == 1){
166 T0 = 1;
167 PTIT -= 1;
168 }
169 if((PTIT % 4) == 2){
170 T1 = 1;
171 PTIT -= 2;
172 }
173 if((PTIT % 8) == 4){
174 T2 = 1;
175 PTIT -= 4;
176 }
177 if((PTIT % 16) == 8){
178 T3 = 1;
179 PTIT -= 8;
180 }
181 if((PTIT % 32) == 16){
182 T4 = 1;
183 PTIT -= 16;
184 }
185 if((PTIT % 64) == 32){
186 T5 = 1;
187 PTIT -= 32;
188 }
189 if((PTIT % 128) == 64){
190 T6 = 1;
191 PTIT -= 64;
192 }
193 if(PTIT == 128){
194 T7 = 1;
195 }
196
197 decodedLog.addValue("T0", T0);
198 decodedLog.addValue("T1", T1);
199 decodedLog.addValue("T2", T2);
200 decodedLog.addValue("T3", T3);
201 decodedLog.addValue("T4", T4);
202 decodedLog.addValue("T5", T5);
203 decodedLog.addValue("T6", T6);
204 decodedLog.addValue("T7", T7);
205 }
206
207 /**
208 * performs a check sum based on the packet data <br>
209 * the checksum needs to be improved however
210 * @param packet
211 * @return true or false based on if the checksum passes
212 */
213 private boolean checksum(short[] packet, int length) {
214 if(length > 0){
215 short includedSum = packet[length -1]; // sum is last byte
216 long veryBIGsum = 0;
217 for(int x=0;x<length-1;x++){
218 veryBIGsum += packet[x];
219 }
220 short calculatedSum = (short)(veryBIGsum % 256);
221 return (calculatedSum == includedSum) ? true : false;
222 }else{
223 return false;
224 }
225 }
226
227 /**
228 * takes the byte to be escaped and returns the proper value
229 * @param uByte - byte to be Un-escaped
230 * @return -1 if bad data or the proper value of the escaped byte
231 */
232 private short unEscapeByte(short uByte) {
233 if (uByte == ESCAPED_START_BYTE) {
234 return START_BYTE;
235 } else if (uByte == ESCAPED_STOP_BYTE) {
236 return STOP_BYTE;
237 } else if (uByte == ESCAPED_ESCAPE_BYTE) {
238 return ESCAPE_BYTE;
239 } else {
240 return (short) -1;
241 }
242 }
243
244 /**
245 *
246 * @return getGenericLog() returns the reference to the generic log the binary data has been converted to
247 */
248 /*public GenericLog getGenericLog() {
249 if (logLoaded) {
250 return decodedLog;
251 } else {
252 return null;
253 }
254 }*/
255
256
257
258 /**
259 *
260 * @return Misc data about this log
261 * <br> to be implemented in full later
262 */
263 @Override
264 public String toString() {
265 return super.toString();
266 }
267 }