1 /*
2 * \file trc_pkt_lister.cpp
3 * \brief OpenCSD : Trace Packet Lister Test program
4 *
5 * \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved.
6 */
7
8
9 /*
10 * Redistribution and use in source and binary forms, with or without modification,
11 * are permitted provided that the following conditions are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright notice,
17 * this list of conditions and the following disclaimer in the documentation
18 * and/or other materials provided with the distribution.
19 *
20 * 3. Neither the name of the copyright holder nor the names of its contributors
21 * may be used to endorse or promote products derived from this software without
22 * specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 /* Test program / utility - list trace packets in supplied snapshot. */
37
38 #include <cstdio>
39 #include <string>
40 #include <iostream>
41 #include <sstream>
42 #include <cstring>
43
44 #include "opencsd.h" // the library
45 #include "trace_snapshots.h" // the snapshot reading test library
46
47 static bool process_cmd_line_opts( int argc, char* argv[]);
48 static void ListTracePackets(ocsdDefaultErrorLogger &err_logger, SnapShotReader &reader, const std::string &trace_buffer_name);
49 static bool process_cmd_line_logger_opts(int argc, char* argv[]);
50 static void log_cmd_line_opts(int argc, char* argv[]);
51
52 // default path
53 #ifdef WIN32
54 static std::string ss_path = ".\\";
55 #else
56 static std::string ss_path = "./";
57 #endif
58
59 static std::string source_buffer_name = ""; // source name - used if more than one source
60 static bool all_source_ids = true; // output all IDs in source.
61 static std::vector<uint8_t> id_list; // output specific IDs in source
62
63 static ocsdMsgLogger logger;
64 static int logOpts = ocsdMsgLogger::OUT_STDOUT | ocsdMsgLogger::OUT_FILE;
65 static std::string logfileName = "trc_pkt_lister.ppl";
66 static bool outRawPacked = false;
67 static bool outRawUnpacked = false;
68 static bool ss_verbose = false;
69 static bool decode = false;
70 static bool no_undecoded_packets = false;
71 static bool pkt_mon = false;
72 static int test_waits = 0;
73 static bool dstream_format = false;
74 static bool tpiu_format = false;
75 static bool has_hsync = false;
76 static bool src_addr_n = false;
77 static bool stats = false;
78
main(int argc,char * argv[])79 int main(int argc, char* argv[])
80 {
81 std::ostringstream moss;
82
83 if(process_cmd_line_logger_opts(argc,argv))
84 {
85 printf("Bad logger command line options\nProgram Exiting\n");
86 return -2;
87 }
88
89 logger.setLogOpts(logOpts);
90 logger.setLogFileName(logfileName.c_str());
91
92 moss << "Trace Packet Lister: CS Decode library testing\n";
93 moss << "-----------------------------------------------\n\n";
94 moss << "** Library Version : " << ocsdVersion::vers_str() << "\n\n";
95 logger.LogMsg(moss.str());
96
97 log_cmd_line_opts(argc,argv);
98
99 ocsdDefaultErrorLogger err_log;
100 err_log.initErrorLogger(OCSD_ERR_SEV_INFO);
101 err_log.setOutputLogger(&logger);
102
103 if(!process_cmd_line_opts(argc, argv))
104 return -1;
105
106 moss.str("");
107 moss << "Trace Packet Lister : reading snapshot from path " << ss_path << "\n";
108 logger.LogMsg(moss.str());
109
110 SnapShotReader ss_reader;
111 ss_reader.setSnapshotDir(ss_path);
112 ss_reader.setErrorLogger(&err_log);
113 ss_reader.setVerboseOutput(ss_verbose);
114
115 if(ss_reader.snapshotFound())
116 {
117 if(ss_reader.readSnapShot())
118 {
119 std::vector<std::string> sourceBuffList;
120 if(ss_reader.getSourceBufferNameList(sourceBuffList))
121 {
122 bool bValidSourceName = false;
123 // check source name list
124 if(source_buffer_name.size() == 0)
125 {
126 // default to first in the list
127 source_buffer_name = sourceBuffList[0];
128 bValidSourceName = true;
129 }
130 else
131 {
132 for(size_t i = 0; i < sourceBuffList.size(); i++)
133 {
134 if(sourceBuffList[i] == source_buffer_name)
135 {
136 bValidSourceName = true;
137 break;
138 }
139 }
140 }
141
142 if(bValidSourceName)
143 {
144 std::ostringstream oss;
145 oss << "Using " << source_buffer_name << " as trace source\n";
146 logger.LogMsg(oss.str());
147 ListTracePackets(err_log,ss_reader,source_buffer_name);
148 }
149 else
150 {
151 std::ostringstream oss;
152 oss << "Trace Packet Lister : Trace source name " << source_buffer_name << " not found\n";
153 logger.LogMsg(oss.str());
154 oss.str("");
155 oss << "Valid source names are:-\n";
156 for(size_t i = 0; i < sourceBuffList.size(); i++)
157 {
158 oss << sourceBuffList[i] << "\n";
159 }
160 logger.LogMsg(oss.str());
161 }
162
163 }
164 else
165 logger.LogMsg("Trace Packet Lister : No trace source buffer names found\n");
166 }
167 else
168 logger.LogMsg("Trace Packet Lister : Failed to read snapshot\n");
169 }
170 else
171 {
172 std::ostringstream oss;
173 oss << "Trace Packet Lister : Snapshot path" << ss_path << " not found\n";
174 logger.LogMsg(oss.str());
175 }
176
177 return 0;
178 }
179
print_help()180 void print_help()
181 {
182 std::ostringstream oss;
183 oss << "Trace Packet Lister - commands\n\n";
184 oss << "Snapshot:\n\n";
185 oss << "-ss_dir <dir> Set the directory path to a trace snapshot\n";
186 oss << "-ss_verbose Verbose output when reading the snapshot\n";
187 oss << "\nDecode:\n\n";
188 oss << "-id <n> Set an ID to list (may be used multiple times) - default if no id set is for all IDs to be printed\n";
189 oss << "-src_name <name> List packets from a given snapshot source name (defaults to first source found)\n";
190 oss << "-dstream_format Input is DSTREAM framed.\n";
191 oss << "-tpiu Input from TPIU - sync by FSYNC.\n";
192 oss << "-tpiu_hsync Input from TPIU - sync by FSYNC and HSYNC.\n";
193 oss << "-decode Full decode of the packets from the trace snapshot (default is to list undecoded packets only\n";
194 oss << "-decode_only Does not list the undecoded packets, just the trace decode.\n";
195 oss << "-o_raw_packed Output raw packed trace frames\n";
196 oss << "-o_raw_unpacked Output raw unpacked trace data per ID\n";
197 oss << "-test_waits <N> Force wait from packet printer for N packets - test the wait/flush mechanisms for the decoder\n";
198 oss << "-src_addr_n ETE protocol: Split source address ranges on N atoms\n";
199 oss << "-stats Output packet processing statistics (if available).\n";
200 oss << "\nOutput:\n";
201 oss << " Setting any of these options cancels the default output to file & stdout,\n using _only_ the options supplied.\n\n";
202 oss << "-logstdout Output to stdout -> console.\n";
203 oss << "-logstderr Output to stderr.\n";
204 oss << "-logfile Output to default file - " << logfileName << "\n";
205 oss << "-logfilename <name> Output to file <name> \n";
206
207
208 logger.LogMsg(oss.str());
209 }
210
log_cmd_line_opts(int argc,char * argv[])211 void log_cmd_line_opts(int argc, char* argv[])
212 {
213 std::ostringstream oss;
214 oss << "Test Command Line:-\n";
215 oss << argv[0] << " ";
216 for(int i = 1; i < argc; i++)
217 {
218 oss << argv[i] << " ";
219 }
220 oss << "\n\n";
221 logger.LogMsg(oss.str());
222 }
223
224 // true if element ID filtered out
element_filtered(uint8_t elemID)225 bool element_filtered(uint8_t elemID)
226 {
227 bool filtered = false;
228 if(!all_source_ids)
229 {
230 filtered = true;
231 std::vector<uint8_t>::const_iterator it;
232 it = id_list.begin();
233 while((it != id_list.end()) && filtered)
234 {
235 if(*it == elemID)
236 filtered = false;
237 it++;
238 }
239 }
240 return filtered;
241 }
242
process_cmd_line_logger_opts(int argc,char * argv[])243 bool process_cmd_line_logger_opts(int argc, char* argv[])
244 {
245 bool badLoggerOpts = false;
246 bool bChangingOptFlags = false;
247 int newlogOpts = ocsdMsgLogger::OUT_NONE;
248 std::string opt;
249 if(argc > 1)
250 {
251 int options_to_process = argc - 1;
252 int optIdx = 1;
253 while(options_to_process > 0)
254 {
255 opt = argv[optIdx];
256 if(opt == "-logstdout")
257 {
258 newlogOpts |= ocsdMsgLogger::OUT_STDOUT;
259 bChangingOptFlags = true;
260 }
261 else if(opt == "-logstderr")
262 {
263 newlogOpts |= ocsdMsgLogger::OUT_STDERR;
264 bChangingOptFlags = true;
265 }
266 else if(opt == "-logfile")
267 {
268 newlogOpts |= ocsdMsgLogger::OUT_FILE;
269 bChangingOptFlags = true;
270 }
271 else if(opt == "-logfilename")
272 {
273 options_to_process--;
274 optIdx++;
275 if(options_to_process)
276 {
277 logfileName = argv[optIdx];
278 newlogOpts |= ocsdMsgLogger::OUT_FILE;
279 bChangingOptFlags = true;
280 }
281 else
282 {
283 badLoggerOpts = true;
284 }
285 }
286 options_to_process--;
287 optIdx++;
288 }
289 }
290 if(bChangingOptFlags)
291 logOpts = newlogOpts;
292 return badLoggerOpts;
293 }
294
process_cmd_line_opts(int argc,char * argv[])295 bool process_cmd_line_opts(int argc, char* argv[])
296 {
297 bool bOptsOK = true;
298 std::string opt;
299 if(argc > 1)
300 {
301 int options_to_process = argc - 1;
302 int optIdx = 1;
303 while((options_to_process > 0) && bOptsOK)
304 {
305 opt = argv[optIdx];
306 if(opt == "-ss_dir")
307 {
308 options_to_process--;
309 optIdx++;
310 if(options_to_process)
311 ss_path = argv[optIdx];
312 else
313 {
314 logger.LogMsg("Trace Packet Lister : Error: Missing directory string on -ss_dir option\n");
315 bOptsOK = false;
316 }
317 }
318 else if(opt == "-id")
319 {
320 options_to_process--;
321 optIdx++;
322 if(options_to_process)
323 {
324 uint8_t Id = (uint8_t)strtoul(argv[optIdx],0,0);
325 if((Id == 0) || (Id >= 0x70))
326 {
327 std::ostringstream iderrstr;
328 iderrstr << "Trace Packet Lister : Error: invalid ID number 0x" << std::hex << (uint32_t)Id << " on -id option" << std::endl;
329 logger.LogMsg(iderrstr.str());
330 bOptsOK = false;
331 }
332 else
333 {
334 all_source_ids = false;
335 id_list.push_back(Id);
336 }
337 }
338 else
339 {
340 logger.LogMsg("Trace Packet Lister : Error: No ID number on -id option\n");
341 bOptsOK = false;
342 }
343 }
344 else if(strcmp(argv[optIdx], "-src_name") == 0)
345 {
346 options_to_process--;
347 optIdx++;
348 if(options_to_process)
349 source_buffer_name = argv[optIdx];
350 else
351 {
352 logger.LogMsg("Trace Packet Lister : Error: Missing source name string on -src_name option\n");
353 bOptsOK = false;
354 }
355 }
356 else if(strcmp(argv[optIdx], "-test_waits") == 0)
357 {
358 options_to_process--;
359 optIdx++;
360 if(options_to_process)
361 {
362 test_waits = (int)strtol(argv[optIdx],0,0);
363 if(test_waits < 0)
364 test_waits = 0;
365 }
366 else
367 {
368 logger.LogMsg("Trace Packet Lister : Error: wait count value on -test_waits option\n");
369 bOptsOK = false;
370 }
371 }
372 else if(strcmp(argv[optIdx], "-o_raw_packed") == 0)
373 {
374 outRawPacked = true;
375 }
376 else if(strcmp(argv[optIdx], "-o_raw_unpacked") == 0)
377 {
378 outRawUnpacked = true;
379 }
380 else if(strcmp(argv[optIdx], "-ss_verbose") == 0)
381 {
382 ss_verbose = true;
383 }
384 else if(strcmp(argv[optIdx], "-decode") == 0)
385 {
386 decode = true;
387 }
388 else if(strcmp(argv[optIdx], "-pkt_mon") == 0)
389 {
390 pkt_mon = true;
391 }
392 else if(strcmp(argv[optIdx], "-decode_only") == 0)
393 {
394 no_undecoded_packets = true;
395 decode = true;
396 }
397 else if (strcmp(argv[optIdx], "-src_addr_n") == 0)
398 {
399 src_addr_n = true;
400 }
401 else if (strcmp(argv[optIdx], "-stats") == 0)
402 {
403 stats = true;
404 }
405 else if((strcmp(argv[optIdx], "-help") == 0) || (strcmp(argv[optIdx], "--help") == 0) || (strcmp(argv[optIdx], "-h") == 0))
406 {
407 print_help();
408 bOptsOK = false;
409 }
410 else if((opt == "-logstdout") || (opt == "-logstderr") ||
411 (opt == "-logfile") || (opt == "-logfilename"))
412 {
413 // skip all these as processed earlier
414
415 // also additionally skip any filename parameter
416 if(opt == "-logfilename")
417 {
418 options_to_process--;
419 optIdx++;
420 }
421 }
422 else if (strcmp(argv[optIdx], "-dstream_format") == 0)
423 {
424 dstream_format = true;
425 }
426 else if (strcmp(argv[optIdx], "-tpiu") == 0)
427 {
428 tpiu_format = true;
429 }
430 else if (strcmp(argv[optIdx], "-tpiu_hsync") == 0)
431 {
432 has_hsync = true;
433 tpiu_format = true;
434 }
435 else
436 {
437 std::ostringstream errstr;
438 errstr << "Trace Packet Lister : Warning: Ignored unknown option " << argv[optIdx] << "." << std::endl;
439 logger.LogMsg(errstr.str());
440 }
441 options_to_process--;
442 optIdx++;
443 }
444
445 }
446 return bOptsOK;
447 }
448
449 //
450 // if decoding the gen elem printer will be injecting waits, but we may ge a cont from the packet processors if a complete packet is not available.
451 // if packet processing only, then waits will be coming from there until the count is extinguished
452 // wait testing with packet processor only really works correctly if we are doing a single source as there is no way at this
453 // point to know which source has sent the _WAIT. with multi packet processor waiting may get false warnings once the _WAITs run out.
ExpectingPPrintWaitResp(DecodeTree * dcd_tree,TrcGenericElementPrinter & genElemPrinter)454 bool ExpectingPPrintWaitResp(DecodeTree *dcd_tree, TrcGenericElementPrinter &genElemPrinter)
455 {
456 bool ExpectingWaits = false;
457 std::vector<ItemPrinter *> &printers = dcd_tree->getPrinterList();
458 if(test_waits > 0)
459 {
460 // see if last response was from the Gen elem printer expecting a wait
461 ExpectingWaits = genElemPrinter.needAckWait();
462
463 // now see if any of the active packet printers are returing wait responses.
464 if(!ExpectingWaits)
465 {
466 std::vector<ItemPrinter *>::iterator it;
467 it = printers.begin();
468 while((it != printers.end()) && !ExpectingWaits)
469 {
470 ExpectingWaits = (bool)((*it)->getTestWaits() != 0);
471 it++;
472 }
473 }
474
475 // nothing waiting - and no outstanding wait cycles in the Gen elem printer.
476 if(!ExpectingWaits && (genElemPrinter.getTestWaits() == 0))
477 test_waits = 0; // zero out the input value if none of the printers currently have waits scheduled.
478 }
479 return ExpectingWaits;
480 }
481
AttachPacketPrinters(DecodeTree * dcd_tree)482 void AttachPacketPrinters( DecodeTree *dcd_tree)
483 {
484 uint8_t elemID;
485 std::ostringstream oss;
486
487 // attach packet printers to each trace source in the tree
488 DecodeTreeElement *pElement = dcd_tree->getFirstElement(elemID);
489 while(pElement && !no_undecoded_packets)
490 {
491 if(!element_filtered(elemID))
492 {
493 oss.str("");
494
495 ItemPrinter *pPrinter;
496 ocsd_err_t err = dcd_tree->addPacketPrinter(elemID, (bool)(decode || pkt_mon),&pPrinter);
497 if (err == OCSD_OK)
498 {
499 // if not decoding or monitor only
500 if((!(decode || pkt_mon)) && test_waits)
501 pPrinter->setTestWaits(test_waits);
502
503 oss << "Trace Packet Lister : Protocol printer " << pElement->getDecoderTypeName() << " on Trace ID 0x" << std::hex << (uint32_t)elemID << "\n";
504 }
505 else
506 oss << "Trace Packet Lister : Failed to Protocol printer " << pElement->getDecoderTypeName() << " on Trace ID 0x" << std::hex << (uint32_t)elemID << "\n";
507 logger.LogMsg(oss.str());
508
509 }
510 pElement = dcd_tree->getNextElement(elemID);
511 }
512
513 }
514
ConfigureFrameDeMux(DecodeTree * dcd_tree,RawFramePrinter ** framePrinter)515 void ConfigureFrameDeMux(DecodeTree *dcd_tree, RawFramePrinter **framePrinter)
516 {
517 // configure the frame deformatter, and attach a frame printer to the frame deformatter if needed
518 TraceFormatterFrameDecoder *pDeformatter = dcd_tree->getFrameDeformatter();
519 if(pDeformatter != 0)
520 {
521 // configuration - memory alinged buffer
522 uint32_t configFlags = pDeformatter->getConfigFlags();
523
524 // check for TPIU FSYNC & HSYNC
525 if (tpiu_format) configFlags |= OCSD_DFRMTR_HAS_FSYNCS;
526 if (has_hsync) configFlags |= OCSD_DFRMTR_HAS_HSYNCS;
527 // if FSYNC (& HSYNC) - cannot be mem frame aligned.
528 if (tpiu_format) configFlags &= ~OCSD_DFRMTR_FRAME_MEM_ALIGN;
529
530 if (!configFlags)
531 {
532 configFlags = OCSD_DFRMTR_FRAME_MEM_ALIGN;
533 }
534 pDeformatter->Configure(configFlags);
535
536 if (outRawPacked || outRawUnpacked)
537 {
538 if (outRawPacked) configFlags |= OCSD_DFRMTR_PACKED_RAW_OUT;
539 if (outRawUnpacked) configFlags |= OCSD_DFRMTR_UNPACKED_RAW_OUT;
540 dcd_tree->addRawFramePrinter(framePrinter, configFlags);
541 }
542 }
543 }
544
PrintDecodeStats(DecodeTree * dcd_tree)545 void PrintDecodeStats(DecodeTree *dcd_tree)
546 {
547 uint8_t elemID;
548 std::ostringstream oss;
549 ocsd_decode_stats_t *pStats = 0;
550 ocsd_err_t err;
551 bool gotDemuxStats = false;
552 ocsd_demux_stats_t demux_stats;
553
554 oss << "\nReading packet decoder statistics....\n\n";
555 logger.LogMsg(oss.str());
556
557 DecodeTreeElement *pElement = dcd_tree->getFirstElement(elemID);
558 while (pElement)
559 {
560 oss.str("");
561 err = dcd_tree->getDecoderStats(elemID, &pStats);
562 if (!err && pStats)
563 {
564 oss << "Decode stats ID 0x" << std::hex << (uint32_t)elemID << "\n";
565 oss << "Total Bytes: " << std::dec << pStats->channel_total << "; Unsynced Bytes: " << std::dec << pStats->channel_unsynced << "\n";
566 oss << "Bad Header Errors: " << std::dec << pStats->bad_header_errs << "; Bad Sequence Errors: " << std::dec << pStats->bad_sequence_errs << "\n";
567
568 // demux stats same for all IDs - grab them at the first opportunity..
569 if (!gotDemuxStats) {
570 memcpy(&demux_stats, &pStats->demux, sizeof(ocsd_demux_stats_t));
571 gotDemuxStats = true;
572 }
573
574 }
575 else
576 oss << "Decode stats unavailable on Trace ID 0x" << std::hex << (uint32_t)elemID << "\n";
577
578
579 logger.LogMsg(oss.str());
580 pElement = dcd_tree->getNextElement(elemID);
581 }
582
583 // if we have copied over the stats and there is at least 1 frame byte (impossible for there to be 0 if demuxing)
584 if (gotDemuxStats && demux_stats.frame_bytes) {
585 uint64_t total = demux_stats.valid_id_bytes + demux_stats.no_id_bytes + demux_stats.unknown_id_bytes +
586 demux_stats.reserved_id_bytes + demux_stats.frame_bytes;
587 oss.str("");
588 oss << "\nFrame Demux Stats\n";
589 oss << "Trace data bytes sent to registered ID decoders: " << std::dec << demux_stats.valid_id_bytes << "\n";
590 oss << "Trace data bytes without registered ID decoders: " << std::dec << demux_stats.no_id_bytes << "\n";
591 oss << "Trace data bytes with unknown ID: " << std::dec << demux_stats.unknown_id_bytes << "\n";
592 oss << "Trace data bytes with reserved ID: " << std::dec << demux_stats.reserved_id_bytes << "\n";
593 oss << "Frame demux bytes, ID bytes and sync bytes: " << std::dec << demux_stats.frame_bytes << "\n";
594 oss << "Total bytes processed by frame demux: " << std::dec << total << "\n\n";
595 logger.LogMsg(oss.str());
596 }
597 }
598
ListTracePackets(ocsdDefaultErrorLogger & err_logger,SnapShotReader & reader,const std::string & trace_buffer_name)599 void ListTracePackets(ocsdDefaultErrorLogger &err_logger, SnapShotReader &reader, const std::string &trace_buffer_name)
600 {
601 CreateDcdTreeFromSnapShot tree_creator;
602
603 tree_creator.initialise(&reader, &err_logger);
604
605 if(tree_creator.createDecodeTree(trace_buffer_name, (decode == false), src_addr_n ? ETE_OPFLG_PKTDEC_SRCADDR_N_ATOMS : 0))
606 {
607 DecodeTree *dcd_tree = tree_creator.getDecodeTree();
608 dcd_tree->setAlternateErrorLogger(&err_logger);
609
610 RawFramePrinter *framePrinter = 0;
611 TrcGenericElementPrinter *genElemPrinter = 0;
612
613 AttachPacketPrinters(dcd_tree);
614
615 ConfigureFrameDeMux(dcd_tree, &framePrinter);
616
617 // if decoding set the generic element printer to the output interface on the tree.
618 if(decode)
619 {
620 std::ostringstream oss;
621 //dcd_tree->setGenTraceElemOutI(genElemPrinter);
622 dcd_tree->addGenElemPrinter(&genElemPrinter);
623 oss << "Trace Packet Lister : Set trace element decode printer\n";
624 logger.LogMsg(oss.str());
625 genElemPrinter->setTestWaits(test_waits);
626 }
627
628 if(decode)
629 dcd_tree->logMappedRanges(); // print out the mapped ranges
630
631 // check if we have attached at least one printer
632 if(decode || (PktPrinterFact::numPrinters(dcd_tree->getPrinterList()) > 0))
633 {
634 // set up the filtering at the tree level (avoid pushing to processors with no attached printers)
635 if(!all_source_ids)
636 dcd_tree->setIDFilter(id_list);
637 else
638 dcd_tree->clearIDFilter();
639
640 // need to push the data through the decode tree.
641 std::ifstream in;
642 in.open(tree_creator.getBufferFileName(),std::ifstream::in | std::ifstream::binary);
643 if(in.is_open())
644 {
645 ocsd_datapath_resp_t dataPathResp = OCSD_RESP_CONT;
646 static const int bufferSize = 1024;
647 uint8_t trace_buffer[bufferSize]; // temporary buffer to load blocks of data from the file
648 uint32_t trace_index = 0; // index into the overall trace buffer (file).
649
650 // process the file, a buffer load at a time
651 while(!in.eof() && !OCSD_DATA_RESP_IS_FATAL(dataPathResp))
652 {
653 if (dstream_format)
654 {
655 in.read((char *)&trace_buffer[0], 512 - 8);
656 }
657 else
658 in.read((char *)&trace_buffer[0],bufferSize); // load a block of data into the buffer
659
660 std::streamsize nBuffRead = in.gcount(); // get count of data loaded.
661 std::streamsize nBuffProcessed = 0; // amount processed in this buffer.
662 uint32_t nUsedThisTime = 0;
663
664 // process the current buffer load until buffer done, or fatal error occurs
665 while((nBuffProcessed < nBuffRead) && !OCSD_DATA_RESP_IS_FATAL(dataPathResp))
666 {
667 if(OCSD_DATA_RESP_IS_CONT(dataPathResp))
668 {
669 dataPathResp = dcd_tree->TraceDataIn(
670 OCSD_OP_DATA,
671 trace_index,
672 (uint32_t)(nBuffRead - nBuffProcessed),
673 &(trace_buffer[0])+nBuffProcessed,
674 &nUsedThisTime);
675
676 nBuffProcessed += nUsedThisTime;
677 trace_index += nUsedThisTime;
678
679 // test printers can inject _WAIT responses - see if we are expecting one...
680 if(ExpectingPPrintWaitResp(dcd_tree, *genElemPrinter))
681 {
682 if(OCSD_DATA_RESP_IS_CONT(dataPathResp))
683 {
684 // not wait or fatal - log a warning here.
685 std::ostringstream oss;
686 oss << "Trace Packet Lister : WARNING : Data in; data Path expected WAIT response\n";
687 logger.LogMsg(oss.str());
688 }
689 }
690 }
691 else // last response was _WAIT
692 {
693 // may need to acknowledge a wait from the gen elem printer
694 if(genElemPrinter->needAckWait())
695 genElemPrinter->ackWait();
696
697 // dataPathResp not continue or fatal so must be wait...
698 dataPathResp = dcd_tree->TraceDataIn(OCSD_OP_FLUSH,0,0,0,0);
699 }
700 }
701
702 /* dump dstream footers */
703 if (dstream_format) {
704 in.read((char *)&trace_buffer[0], 8);
705 if (outRawPacked)
706 {
707 std::ostringstream oss;
708 oss << "DSTREAM footer [";
709 for (int i = 0; i < 8; i++)
710 {
711 oss << "0x" << std::hex << (int)trace_buffer[i] << " ";
712 }
713 oss << "]\n";
714 logger.LogMsg(oss.str());
715 }
716 }
717 }
718
719 // fatal error - no futher processing
720 if(OCSD_DATA_RESP_IS_FATAL(dataPathResp))
721 {
722 std::ostringstream oss;
723 oss << "Trace Packet Lister : Data Path fatal error\n";
724 logger.LogMsg(oss.str());
725 ocsdError *perr = err_logger.GetLastError();
726 if(perr != 0)
727 logger.LogMsg(ocsdError::getErrorString(perr));
728
729 }
730 else
731 {
732 // mark end of trace into the data path
733 dcd_tree->TraceDataIn(OCSD_OP_EOT,0,0,0,0);
734 }
735
736 // close the input file.
737 in.close();
738
739 std::ostringstream oss;
740 oss << "Trace Packet Lister : Trace buffer done, processed " << trace_index << " bytes.\n";
741 logger.LogMsg(oss.str());
742 if (stats)
743 PrintDecodeStats(dcd_tree);
744 }
745 else
746 {
747 std::ostringstream oss;
748 oss << "Trace Packet Lister : Error : Unable to open trace buffer.\n";
749 logger.LogMsg(oss.str());
750 }
751
752 }
753 else
754 {
755 std::ostringstream oss;
756 oss << "Trace Packet Lister : No supported protocols found.\n";
757 logger.LogMsg(oss.str());
758 }
759
760 // clean up
761
762 // get rid of the decode tree.
763 tree_creator.destroyDecodeTree();
764 }
765 }
766
767 /* End of File trc_pkt_lister.cpp */
768