• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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