Add Freescale Nexus decoder implementation
[babeltrace.git] / converter / nexus / Application.cpp
1 /*
2 * Copyright (C) 2013 Freescale Semiconductor, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 * IN THE SOFTWARE.
21 */
22
23 #include "Application.h"
24 #include "NxMessageDecoder.h"
25 #include "NxMessage.h"
26 #include "FManDebugLogVisitor.h"
27 #include "FullAddressVisitor.h"
28 #include "SizedAddress.h"
29 #include <iostream>
30 #include <iomanip>
31 #include <fstream>
32
33 using std::cout;
34 using std::endl;
35 using std::hex;
36 using std::dec;
37 using std::setfill;
38 using std::setw;
39 using std::ifstream;
40
41 Application::Application() :
42 verbose_(false), summary_(false), data_counter_(0), msg_counter_(0)
43 {
44 }
45
46 Application::~Application()
47 {
48 vector<NxMessageVisitor*>::iterator it;
49 for (it = visitors_.begin(); it != visitors_.end(); it++) {
50 delete *it;
51 }
52 visitors_.clear();
53 }
54
55 // Enable the Full Address Log for the Application
56 void Application::enableFullAddrLog()
57 {
58 NxMessageVisitor* v = new FullAddressVisitor();
59 visitors_.push_back(v);
60 }
61
62 // Enable the FMan Detail Log for the Application
63 void Application::enableFmanLog()
64 {
65 NxMessageVisitor* v = new FManDebugLogVisitor();
66 visitors_.push_back(v);
67 }
68
69 // Main application entry
70 bool Application::process(const string & fn)
71 {
72 bool ret;
73
74 // test if file is available
75 ifstream infile(fn.c_str());
76 if (!infile) {
77 cout << "Input Filename: \"" << fn << "\" cannot be opened! ";
78 return false;
79 } else {
80 infile.close();
81 }
82
83 if (verbose_) {
84 cout << "Input Filename: \"" << fn << "\" - ";
85 }
86
87 // determine format for file
88 if (isBinFile_(fn)) {
89 if (verbose_) {
90 cout << "Binary" << endl;
91 }
92 ret = processBinFile_(fn);
93 } else {
94 if (verbose_) {
95 cout << "Text" << endl;
96 }
97 ret = processTextFile_(fn);
98 }
99
100 if (ret && summary_) {
101 summarize();
102 }
103
104 return ret;
105 }
106
107 // Determine if the name file contains Binary formatted data
108 bool Application::isBinFile_(const string &fn) const
109 {
110 char data[12]; // if text then expecting 0x12345678\n
111
112 // open the file as binary and read the first 12 bytes
113 ifstream infile(fn.c_str(), std::ios::in | std::ios::binary);
114 infile.read(data, 12);
115 infile.close();
116 bool text_file = ((data[0] == '0') && (data[1] == 'x')
117 && ((data[10] == '\n') || (data[10] == ' ')));
118 return !text_file;
119 }
120
121 // Open the named text file and process the Nexus data
122 bool Application::processTextFile_(const string &fn)
123 {
124 bool ret;
125 uint32_t data;
126
127 // open the file and feed the data to the decoder
128 ifstream infile(fn.c_str());
129 while (!infile.eof()) {
130 infile >> hex >> data;
131 ret = process_(data);
132 if (!ret) { // error, so quit
133 break;
134 }
135 }
136 infile.close();
137
138 return ret;
139 }
140
141 // Open the named text file and process the Nexus data
142 bool Application::processBinFile_(const string &fn)
143 {
144 bool ret;
145 uint8_t byte[sizeof(uint32_t)];
146 uint32_t data;
147
148 // open the file and feed the data to the decoder
149 ifstream infile(fn.c_str(), std::ios::in | std::ios::binary);
150 while (!infile.eof()) {
151 infile.read((char*) &byte, sizeof(uint32_t));
152 // Nexus binary files are Big Endian data
153 data = byte[0] << 24;
154 data |= byte[1] << 16;
155 data |= byte[2] << 8;
156 data |= byte[3];
157 ret = process_(data);
158 if (!ret) { // error, so quit
159 break;
160 }
161 }
162 infile.close();
163
164 return ret;
165 }
166
167 // Process the Nexus data
168 bool Application::process_(const uint32_t data)
169 {
170 bool ret = true;
171
172 NxMessage *msg = (NxMessage*) 0;
173 data_counter_++;
174
175 if (verbose_) {
176 cout << dec << data_counter_ << ": MDO/MSEO: 0x" << hex
177 << setfill('0') << setw(8) << data << endl;
178 }
179
180 ret = decoder_.accept(data, msg);
181 if (ret) {
182 if (msg != 0) {
183 ++msg_counter_;
184 // we have a message to output
185 cout << "Message # " << dec << msg_counter_ << endl;
186 cout << msg->asString() << endl;
187
188 // count the messages
189 if (summary_) {
190 msg_count_[msg->tcodeString()]++;
191 }
192
193 // Send all the visitors
194 vector<NxMessageVisitor*>::iterator it;
195 for (it = visitors_.begin(); it != visitors_.end();
196 it++) {
197 msg->accept(**it);
198 // report on visit
199 cout << (*it)->asString() << endl;
200 }
201
202 // nothing else to do for now so delete the message
203 delete msg;
204 msg = (NxMessage*) 0;
205 }
206 } else {
207 // error somewhere - quit
208 if (verbose_) {
209 cout << "NxMessageDecoder Failed. Quitting." << endl;
210 }
211 }
212
213 return ret;
214 }
215
216 // output a summary report on number of messages by type
217 void Application::summarize()
218 {
219 cout << endl << "***********************" << endl;
220 cout << "Message Counts by TCODE" << endl;
221
222 map<string, uint32_t>::const_iterator iter;
223 for (iter = msg_count_.begin(); iter != msg_count_.end(); ++iter) {
224 cout << iter->first << "\t" << dec << setw(10) << setfill(' ')
225 << iter->second << endl;
226 }
227
228 }
This page took 0.033407 seconds and 4 git commands to generate.