|
1 /* |
|
2 * Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 * OST Message Processor |
|
17 * |
|
18 */ |
|
19 package com.nokia.traceviewer.ost; |
|
20 |
|
21 import java.io.IOException; |
|
22 import java.nio.ByteBuffer; |
|
23 |
|
24 import com.nokia.traceviewer.engine.TraceViewerConst; |
|
25 |
|
26 /** |
|
27 * OST Message Processor |
|
28 * |
|
29 */ |
|
30 public class OstMessageProcessor implements OstConsts, TraceViewerConst { |
|
31 |
|
32 /** |
|
33 * Buffer where data is located |
|
34 */ |
|
35 private final ByteBuffer receiveBuffer; |
|
36 |
|
37 /** |
|
38 * Temporary buffer for data |
|
39 */ |
|
40 private final ByteBuffer tempBuffer; |
|
41 |
|
42 /** |
|
43 * Callback class |
|
44 */ |
|
45 private final OstMessageCallback callback; |
|
46 |
|
47 /** |
|
48 * If true, stop processing the messages |
|
49 */ |
|
50 private boolean stopped; |
|
51 |
|
52 /** |
|
53 * @param callback |
|
54 * callback where messages are returned |
|
55 * @param receiveBuffer |
|
56 * buffer where data is located |
|
57 */ |
|
58 public OstMessageProcessor(OstMessageCallback callback, |
|
59 ByteBuffer receiveBuffer) { |
|
60 this.callback = callback; |
|
61 this.receiveBuffer = receiveBuffer; |
|
62 tempBuffer = ByteBuffer.allocateDirect(MAX_MESSAGE_SIZE); |
|
63 } |
|
64 |
|
65 /** |
|
66 * Processes buffer to messages |
|
67 * |
|
68 * @throws IOException |
|
69 */ |
|
70 public void processBuffer() throws IOException { |
|
71 |
|
72 boolean messageFound = false; |
|
73 boolean processorResult = false; |
|
74 int msgLength = 0; |
|
75 int versionNr = 0; |
|
76 int msgStart = 0; |
|
77 // Parses all complete messages |
|
78 int position = receiveBuffer.position(); |
|
79 do { |
|
80 messageFound = false; |
|
81 // Reads next message length if there is enough data |
|
82 if (position - msgStart > OST_V01_HEADER_LENGTH) { |
|
83 versionNr = 0; |
|
84 msgLength = 0; |
|
85 |
|
86 // Get OST version and check the base header length |
|
87 versionNr |= (receiveBuffer.get(msgStart + OST_VERSION_OFFSET) & BYTE_MASK); |
|
88 |
|
89 int headerLength = 0; |
|
90 |
|
91 // OST version 0.1 |
|
92 if (versionNr == OST_V01) { |
|
93 headerLength = OST_V01_HEADER_LENGTH; |
|
94 |
|
95 // Get message length |
|
96 msgLength |= (receiveBuffer.getShort(msgStart |
|
97 + OST_V01_LENGTH_OFFSET_1) & SHORT_MASK) |
|
98 + headerLength; |
|
99 |
|
100 // OST version 0.0 |
|
101 } else if (versionNr == OST_V00) { |
|
102 headerLength = OST_V00_HEADER_LENGTH; |
|
103 |
|
104 // Get message length |
|
105 msgLength |= (receiveBuffer.getShort(msgStart |
|
106 + OST_V01_LENGTH_OFFSET_1) & SHORT_MASK) |
|
107 + headerLength; |
|
108 |
|
109 // OST version 0.5 or 1.0 |
|
110 } else if (versionNr == OST_V05 || versionNr == OST_V10) { |
|
111 headerLength = OST_V05_HEADER_LENGTH; |
|
112 |
|
113 // Get message length |
|
114 msgLength |= (receiveBuffer.get(msgStart |
|
115 + OST_V05_LENGTH_OFFSET) & BYTE_MASK) |
|
116 + headerLength; |
|
117 |
|
118 // If length is only the header length, there are 4 bytes |
|
119 // extended length in Little Endian (LE) |
|
120 if (msgLength == headerLength) { |
|
121 headerLength += OST_V05_EXT_LENGTH_LENGTH; |
|
122 msgLength = receiveBuffer.getInt(msgStart |
|
123 + OST_V05_EXT_LENGTH_OFFSET); |
|
124 |
|
125 // Reverse because of Little Endian |
|
126 msgLength = Integer.reverseBytes(msgLength); |
|
127 msgLength += headerLength; |
|
128 } |
|
129 } else { |
|
130 // Unsupported OST version. |
|
131 System.out |
|
132 .println("Unsupported OST version: 0x" + Integer.toHexString(versionNr)); //$NON-NLS-1$ |
|
133 } |
|
134 |
|
135 // Parses message if it is completely in buffer |
|
136 if (position >= msgStart + msgLength) { |
|
137 processorResult = callback.processMessage(msgStart, |
|
138 msgLength, headerLength, versionNr); |
|
139 msgStart += msgLength; |
|
140 messageFound = true; |
|
141 } |
|
142 } |
|
143 } while (messageFound && processorResult && !stopped); |
|
144 |
|
145 if (!stopped) { |
|
146 // Writes the remaining data into beginning of receive |
|
147 // buffer. The next socket read operation will append data |
|
148 // into buffer |
|
149 int remainderLength = position - msgStart; |
|
150 if (remainderLength > 0 && processorResult) { |
|
151 receiveBuffer.position(msgStart); |
|
152 receiveBuffer.limit(msgStart + remainderLength); |
|
153 tempBuffer.position(0); |
|
154 tempBuffer.limit(MAX_MESSAGE_SIZE); |
|
155 tempBuffer.put(receiveBuffer); |
|
156 |
|
157 receiveBuffer.position(0); |
|
158 receiveBuffer.limit(RECEIVE_BUFFER_SIZE); |
|
159 tempBuffer.position(0); |
|
160 tempBuffer.limit(remainderLength); |
|
161 |
|
162 receiveBuffer.put(tempBuffer); |
|
163 receiveBuffer.position(remainderLength); |
|
164 } else { |
|
165 receiveBuffer.position(0); |
|
166 receiveBuffer.limit(RECEIVE_BUFFER_SIZE); |
|
167 } |
|
168 } |
|
169 } |
|
170 |
|
171 /** |
|
172 * Reads the 8 byte timestamp from the data buffer |
|
173 * |
|
174 * @param msgStart |
|
175 * message start offset |
|
176 * @param timestampOffset |
|
177 * offset to the timestamp in the message |
|
178 * @return the timestamp |
|
179 */ |
|
180 public long parseTimeStampToNanosecs(int msgStart, int timestampOffset) { |
|
181 long timestamp = 0; |
|
182 try { |
|
183 timestamp = receiveBuffer.getLong(msgStart + timestampOffset) |
|
184 & TIMESTAMP_MASK; |
|
185 } catch (Throwable t) { |
|
186 t.printStackTrace(); |
|
187 // Couldn't get timestamp, return MIN_VALUE to set trace as non |
|
188 // valid |
|
189 timestamp = Long.MIN_VALUE; |
|
190 } |
|
191 return timestamp; |
|
192 } |
|
193 |
|
194 /** |
|
195 * Close the processor |
|
196 */ |
|
197 void close() { |
|
198 stopped = true; |
|
199 } |
|
200 } |