• 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 
main(int argc,char * argv[])78 int main(int argc, char* argv[])
79 {
80     std::ostringstream moss;
81 
82     if(process_cmd_line_logger_opts(argc,argv))
83     {
84         printf("Bad logger command line options\nProgram Exiting\n");
85         return -2;
86     }
87 
88     logger.setLogOpts(logOpts);
89     logger.setLogFileName(logfileName.c_str());
90 
91     moss << "Trace Packet Lister: CS Decode library testing\n";
92     moss << "-----------------------------------------------\n\n";
93     moss << "** Library Version : " << ocsdVersion::vers_str() << "\n\n";
94     logger.LogMsg(moss.str());
95 
96     log_cmd_line_opts(argc,argv);
97 
98     ocsdDefaultErrorLogger err_log;
99     err_log.initErrorLogger(OCSD_ERR_SEV_INFO);
100     err_log.setOutputLogger(&logger);
101 
102     if(!process_cmd_line_opts(argc, argv))
103         return -1;
104 
105     moss.str("");
106     moss << "Trace Packet Lister : reading snapshot from path " << ss_path << "\n";
107     logger.LogMsg(moss.str());
108 
109     SnapShotReader ss_reader;
110     ss_reader.setSnapshotDir(ss_path);
111     ss_reader.setErrorLogger(&err_log);
112     ss_reader.setVerboseOutput(ss_verbose);
113 
114     if(ss_reader.snapshotFound())
115     {
116         if(ss_reader.readSnapShot())
117         {
118             std::vector<std::string> sourceBuffList;
119             if(ss_reader.getSourceBufferNameList(sourceBuffList))
120             {
121                 bool bValidSourceName = false;
122                 // check source name list
123                 if(source_buffer_name.size() == 0)
124                 {
125                     // default to first in the list
126                     source_buffer_name = sourceBuffList[0];
127                     bValidSourceName = true;
128                 }
129                 else
130                 {
131                     for(size_t i = 0; i < sourceBuffList.size(); i++)
132                     {
133                         if(sourceBuffList[i] == source_buffer_name)
134                         {
135                             bValidSourceName = true;
136                             break;
137                         }
138                     }
139                 }
140 
141                 if(bValidSourceName)
142                 {
143                     std::ostringstream oss;
144                     oss << "Using " << source_buffer_name << " as trace source\n";
145                     logger.LogMsg(oss.str());
146                     ListTracePackets(err_log,ss_reader,source_buffer_name);
147                 }
148                 else
149                 {
150                     std::ostringstream oss;
151                     oss << "Trace Packet Lister : Trace source name " << source_buffer_name << " not found\n";
152                     logger.LogMsg(oss.str());
153                     oss.str("");
154                     oss << "Valid source names are:-\n";
155                     for(size_t i = 0; i < sourceBuffList.size(); i++)
156                     {
157                         oss << sourceBuffList[i] << "\n";
158                     }
159                     logger.LogMsg(oss.str());
160                 }
161 
162             }
163             else
164                 logger.LogMsg("Trace Packet Lister : No trace source buffer names found\n");
165         }
166         else
167             logger.LogMsg("Trace Packet Lister : Failed to read snapshot\n");
168     }
169     else
170     {
171         std::ostringstream oss;
172         oss << "Trace Packet Lister : Snapshot path" << ss_path << " not found\n";
173         logger.LogMsg(oss.str());
174     }
175 
176     return 0;
177 }
178 
print_help()179 void print_help()
180 {
181     std::ostringstream oss;
182     oss << "Trace Packet Lister - commands\n\n";
183     oss << "Snapshot:\n\n";
184     oss << "-ss_dir <dir>       Set the directory path to a trace snapshot\n";
185     oss << "-ss_verbose         Verbose output when reading the snapshot\n";
186     oss << "\nDecode:\n\n";
187     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";
188     oss << "-src_name <name>    List packets from a given snapshot source name (defaults to first source found)\n";
189     oss << "-dstream_format     Input is DSTREAM framed.\n";
190     oss << "-tpiu               Input from TPIU - sync by FSYNC.\n";
191     oss << "-tpiu_hsync         Input from TPIU - sync by FSYNC and HSYNC.\n";
192     oss << "-decode             Full decode of the packets from the trace snapshot (default is to list undecoded packets only\n";
193     oss << "-decode_only        Does not list the undecoded packets, just the trace decode.\n";
194     oss << "-o_raw_packed       Output raw packed trace frames\n";
195     oss << "-o_raw_unpacked     Output raw unpacked trace data per ID\n";
196     oss << "-test_waits <N>     Force wait from packet printer for N packets - test the wait/flush mechanisms for the decoder\n";
197     oss << "-src_addr_n         ETE protocol: Split source address ranges on N atoms\n";
198     oss << "\nOutput:\n";
199     oss << "   Setting any of these options cancels the default output to file & stdout,\n   using _only_ the options supplied.\n\n";
200     oss << "-logstdout          Output to stdout -> console.\n";
201     oss << "-logstderr          Output to stderr.\n";
202     oss << "-logfile            Output to default file - " << logfileName << "\n";
203     oss << "-logfilename <name> Output to file <name> \n";
204 
205 
206     logger.LogMsg(oss.str());
207 }
208 
log_cmd_line_opts(int argc,char * argv[])209 void log_cmd_line_opts(int argc, char* argv[])
210 {
211     std::ostringstream oss;
212     oss << "Test Command Line:-\n";
213     oss << argv[0] << "   ";
214     for(int i = 1; i < argc; i++)
215     {
216         oss << argv[i] << "  ";
217     }
218     oss << "\n\n";
219     logger.LogMsg(oss.str());
220 }
221 
222 // true if element ID filtered out
element_filtered(uint8_t elemID)223 bool element_filtered(uint8_t elemID)
224 {
225     bool filtered = false;
226     if(!all_source_ids)
227     {
228         filtered = true;
229         std::vector<uint8_t>::const_iterator it;
230         it = id_list.begin();
231         while((it != id_list.end()) && filtered)
232         {
233             if(*it == elemID)
234                 filtered = false;
235             it++;
236         }
237     }
238     return filtered;
239 }
240 
process_cmd_line_logger_opts(int argc,char * argv[])241 bool process_cmd_line_logger_opts(int argc, char* argv[])
242 {
243     bool badLoggerOpts = false;
244     bool bChangingOptFlags = false;
245     int newlogOpts = ocsdMsgLogger::OUT_NONE;
246     std::string opt;
247     if(argc > 1)
248     {
249         int options_to_process = argc - 1;
250         int optIdx = 1;
251         while(options_to_process > 0)
252         {
253             opt = argv[optIdx];
254             if(opt == "-logstdout")
255             {
256                 newlogOpts |= ocsdMsgLogger::OUT_STDOUT;
257                 bChangingOptFlags = true;
258             }
259             else if(opt == "-logstderr")
260             {
261                 newlogOpts |= ocsdMsgLogger::OUT_STDERR;
262                 bChangingOptFlags = true;
263             }
264             else if(opt == "-logfile")
265             {
266                 newlogOpts |= ocsdMsgLogger::OUT_FILE;
267                 bChangingOptFlags = true;
268             }
269             else if(opt == "-logfilename")
270             {
271                 options_to_process--;
272                 optIdx++;
273                 if(options_to_process)
274                 {
275                     logfileName = argv[optIdx];
276                     newlogOpts |= ocsdMsgLogger::OUT_FILE;
277                     bChangingOptFlags = true;
278                 }
279                 else
280                 {
281                     badLoggerOpts = true;
282                 }
283             }
284             options_to_process--;
285             optIdx++;
286         }
287     }
288     if(bChangingOptFlags)
289         logOpts = newlogOpts;
290     return badLoggerOpts;
291 }
292 
process_cmd_line_opts(int argc,char * argv[])293 bool process_cmd_line_opts(int argc, char* argv[])
294 {
295     bool bOptsOK = true;
296     std::string opt;
297     if(argc > 1)
298     {
299         int options_to_process = argc - 1;
300         int optIdx = 1;
301         while((options_to_process > 0) && bOptsOK)
302         {
303             opt = argv[optIdx];
304             if(opt == "-ss_dir")
305             {
306                 options_to_process--;
307                 optIdx++;
308                 if(options_to_process)
309                     ss_path = argv[optIdx];
310                 else
311                 {
312                     logger.LogMsg("Trace Packet Lister : Error: Missing directory string on -ss_dir option\n");
313                     bOptsOK = false;
314                 }
315             }
316             else if(opt == "-id")
317             {
318                 options_to_process--;
319                 optIdx++;
320                 if(options_to_process)
321                 {
322                     uint8_t Id = (uint8_t)strtoul(argv[optIdx],0,0);
323                     if((Id == 0) || (Id >= 0x70))
324                     {
325                         std::ostringstream iderrstr;
326                         iderrstr << "Trace Packet Lister : Error: invalid ID number 0x" << std::hex << (uint32_t)Id << " on -id option" << std::endl;
327                         logger.LogMsg(iderrstr.str());
328                         bOptsOK = false;
329                     }
330                     else
331                     {
332                         all_source_ids = false;
333                         id_list.push_back(Id);
334                     }
335                 }
336                 else
337                 {
338                     logger.LogMsg("Trace Packet Lister : Error: No ID number on -id option\n");
339                     bOptsOK = false;
340                 }
341             }
342             else if(strcmp(argv[optIdx], "-src_name") == 0)
343             {
344                 options_to_process--;
345                 optIdx++;
346                 if(options_to_process)
347                     source_buffer_name = argv[optIdx];
348                 else
349                 {
350                     logger.LogMsg("Trace Packet Lister : Error: Missing source name string on -src_name option\n");
351                     bOptsOK = false;
352                 }
353             }
354             else if(strcmp(argv[optIdx], "-test_waits") == 0)
355             {
356                 options_to_process--;
357                 optIdx++;
358                 if(options_to_process)
359                 {
360                     test_waits = (int)strtol(argv[optIdx],0,0);
361                     if(test_waits < 0)
362                         test_waits = 0;
363                 }
364                 else
365                 {
366                     logger.LogMsg("Trace Packet Lister : Error: wait count value on -test_waits option\n");
367                     bOptsOK = false;
368                 }
369             }
370             else if(strcmp(argv[optIdx], "-o_raw_packed") == 0)
371             {
372                 outRawPacked = true;
373             }
374             else if(strcmp(argv[optIdx], "-o_raw_unpacked") == 0)
375             {
376                 outRawUnpacked = true;
377             }
378             else if(strcmp(argv[optIdx], "-ss_verbose") == 0)
379             {
380                 ss_verbose = true;
381             }
382             else if(strcmp(argv[optIdx], "-decode") == 0)
383             {
384                 decode = true;
385             }
386             else if(strcmp(argv[optIdx], "-pkt_mon") == 0)
387             {
388                 pkt_mon = true;
389             }
390             else if(strcmp(argv[optIdx], "-decode_only") == 0)
391             {
392                 no_undecoded_packets = true;
393                 decode = true;
394             }
395             else if (strcmp(argv[optIdx], "-src_addr_n") == 0)
396             {
397                 src_addr_n = true;
398             }
399             else if((strcmp(argv[optIdx], "-help") == 0) || (strcmp(argv[optIdx], "--help") == 0) || (strcmp(argv[optIdx], "-h") == 0))
400             {
401                 print_help();
402                 bOptsOK = false;
403             }
404             else if((opt == "-logstdout") || (opt == "-logstderr") ||
405                 (opt == "-logfile") || (opt == "-logfilename"))
406             {
407                 // skip all these as processed earlier
408 
409                 // also additionally skip any filename parameter
410                 if(opt == "-logfilename")
411                 {
412                     options_to_process--;
413                     optIdx++;
414                 }
415             }
416             else if (strcmp(argv[optIdx], "-dstream_format") == 0)
417             {
418                 dstream_format = true;
419             }
420             else if (strcmp(argv[optIdx], "-tpiu") == 0)
421             {
422                 tpiu_format = true;
423             }
424             else if (strcmp(argv[optIdx], "-tpiu_hsync") == 0)
425             {
426                 has_hsync = true;
427                 tpiu_format = true;
428             }
429             else
430             {
431                 std::ostringstream errstr;
432                 errstr << "Trace Packet Lister : Warning: Ignored unknown option " << argv[optIdx] << "." << std::endl;
433                 logger.LogMsg(errstr.str());
434             }
435             options_to_process--;
436             optIdx++;
437         }
438 
439     }
440     return bOptsOK;
441 }
442 
443 //
444 // 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.
445 // if packet processing only, then waits will be coming from there until the count is extinguished
446 // wait testing with packet processor only really works correctly if we are doing a single source as there is no way at this
447 // 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)448 bool ExpectingPPrintWaitResp(DecodeTree *dcd_tree, TrcGenericElementPrinter &genElemPrinter)
449 {
450     bool ExpectingWaits = false;
451     std::vector<ItemPrinter *> &printers = dcd_tree->getPrinterList();
452     if(test_waits > 0)
453     {
454         // see if last response was from the Gen elem printer expecting a wait
455         ExpectingWaits = genElemPrinter.needAckWait();
456 
457         // now see if any of the active packet printers are returing wait responses.
458         if(!ExpectingWaits)
459         {
460             std::vector<ItemPrinter *>::iterator it;
461             it = printers.begin();
462             while((it != printers.end()) && !ExpectingWaits)
463             {
464                 ExpectingWaits = (bool)((*it)->getTestWaits() != 0);
465                 it++;
466             }
467         }
468 
469         // nothing waiting - and no outstanding wait cycles in the Gen elem printer.
470         if(!ExpectingWaits && (genElemPrinter.getTestWaits() == 0))
471             test_waits = 0;     // zero out the input value if none of the printers currently have waits scheduled.
472     }
473     return ExpectingWaits;
474 }
475 
AttachPacketPrinters(DecodeTree * dcd_tree)476 void AttachPacketPrinters( DecodeTree *dcd_tree)
477 {
478     uint8_t elemID;
479     std::ostringstream oss;
480 
481     // attach packet printers to each trace source in the tree
482     DecodeTreeElement *pElement = dcd_tree->getFirstElement(elemID);
483     while(pElement && !no_undecoded_packets)
484     {
485         if(!element_filtered(elemID))
486         {
487             oss.str("");
488 
489             ItemPrinter *pPrinter;
490             ocsd_err_t err = dcd_tree->addPacketPrinter(elemID, (bool)(decode || pkt_mon),&pPrinter);
491             if (err == OCSD_OK)
492             {
493                 // if not decoding or monitor only
494                 if((!(decode || pkt_mon)) && test_waits)
495                     pPrinter->setTestWaits(test_waits);
496 
497                 oss << "Trace Packet Lister : Protocol printer " << pElement->getDecoderTypeName() <<  " on Trace ID 0x" << std::hex << (uint32_t)elemID << "\n";
498             }
499             else
500                 oss << "Trace Packet Lister : Failed to Protocol printer " << pElement->getDecoderTypeName() << " on Trace ID 0x" << std::hex << (uint32_t)elemID << "\n";
501             logger.LogMsg(oss.str());
502 
503         }
504         pElement = dcd_tree->getNextElement(elemID);
505     }
506 
507 }
508 
ConfigureFrameDeMux(DecodeTree * dcd_tree,RawFramePrinter ** framePrinter)509 void ConfigureFrameDeMux(DecodeTree *dcd_tree, RawFramePrinter **framePrinter)
510 {
511     // configure the frame deformatter, and attach a frame printer to the frame deformatter if needed
512     TraceFormatterFrameDecoder *pDeformatter = dcd_tree->getFrameDeformatter();
513     if(pDeformatter != 0)
514     {
515         // configuration - memory alinged buffer
516         uint32_t configFlags = pDeformatter->getConfigFlags();
517 
518         // check for TPIU FSYNC & HSYNC
519         if (tpiu_format) configFlags |= OCSD_DFRMTR_HAS_FSYNCS;
520         if (has_hsync) configFlags |= OCSD_DFRMTR_HAS_HSYNCS;
521         // if FSYNC (& HSYNC) - cannot be mem frame aligned.
522         if (tpiu_format) configFlags &= ~OCSD_DFRMTR_FRAME_MEM_ALIGN;
523 
524         if (!configFlags)
525         {
526             configFlags = OCSD_DFRMTR_FRAME_MEM_ALIGN;
527         }
528         pDeformatter->Configure(configFlags);
529 
530         if (outRawPacked || outRawUnpacked)
531         {
532             if (outRawPacked) configFlags |= OCSD_DFRMTR_PACKED_RAW_OUT;
533             if (outRawUnpacked) configFlags |= OCSD_DFRMTR_UNPACKED_RAW_OUT;
534             dcd_tree->addRawFramePrinter(framePrinter, configFlags);
535         }
536     }
537 }
538 
ListTracePackets(ocsdDefaultErrorLogger & err_logger,SnapShotReader & reader,const std::string & trace_buffer_name)539 void ListTracePackets(ocsdDefaultErrorLogger &err_logger, SnapShotReader &reader, const std::string &trace_buffer_name)
540 {
541     CreateDcdTreeFromSnapShot tree_creator;
542 
543     tree_creator.initialise(&reader, &err_logger);
544 
545     if(tree_creator.createDecodeTree(trace_buffer_name, (decode == false), src_addr_n ? ETE_OPFLG_PKTDEC_SRCADDR_N_ATOMS : 0))
546     {
547         DecodeTree *dcd_tree = tree_creator.getDecodeTree();
548         dcd_tree->setAlternateErrorLogger(&err_logger);
549 
550         RawFramePrinter *framePrinter = 0;
551         TrcGenericElementPrinter *genElemPrinter = 0;
552 
553         AttachPacketPrinters(dcd_tree);
554 
555         ConfigureFrameDeMux(dcd_tree, &framePrinter);
556 
557         // if decoding set the generic element printer to the output interface on the tree.
558         if(decode)
559         {
560             std::ostringstream oss;
561             //dcd_tree->setGenTraceElemOutI(genElemPrinter);
562             dcd_tree->addGenElemPrinter(&genElemPrinter);
563             oss << "Trace Packet Lister : Set trace element decode printer\n";
564             logger.LogMsg(oss.str());
565             genElemPrinter->setTestWaits(test_waits);
566         }
567 
568         if(decode)
569             dcd_tree->logMappedRanges();    // print out the mapped ranges
570 
571          // check if we have attached at least one printer
572         if(decode || (PktPrinterFact::numPrinters(dcd_tree->getPrinterList()) > 0))
573         {
574             // set up the filtering at the tree level (avoid pushing to processors with no attached printers)
575             if(!all_source_ids)
576                 dcd_tree->setIDFilter(id_list);
577             else
578                 dcd_tree->clearIDFilter();
579 
580             // need to push the data through the decode tree.
581             std::ifstream in;
582             in.open(tree_creator.getBufferFileName(),std::ifstream::in | std::ifstream::binary);
583             if(in.is_open())
584             {
585                 ocsd_datapath_resp_t dataPathResp = OCSD_RESP_CONT;
586                 static const int bufferSize = 1024;
587                 uint8_t trace_buffer[bufferSize];   // temporary buffer to load blocks of data from the file
588                 uint32_t trace_index = 0;           // index into the overall trace buffer (file).
589 
590                 // process the file, a buffer load at a time
591                 while(!in.eof() && !OCSD_DATA_RESP_IS_FATAL(dataPathResp))
592                 {
593                     if (dstream_format)
594                     {
595                         in.read((char *)&trace_buffer[0], 512 - 8);
596                     }
597                     else
598                         in.read((char *)&trace_buffer[0],bufferSize);   // load a block of data into the buffer
599 
600                     std::streamsize nBuffRead = in.gcount();    // get count of data loaded.
601                     std::streamsize nBuffProcessed = 0;         // amount processed in this buffer.
602                     uint32_t nUsedThisTime = 0;
603 
604                     // process the current buffer load until buffer done, or fatal error occurs
605                     while((nBuffProcessed < nBuffRead) && !OCSD_DATA_RESP_IS_FATAL(dataPathResp))
606                     {
607                         if(OCSD_DATA_RESP_IS_CONT(dataPathResp))
608                         {
609                             dataPathResp = dcd_tree->TraceDataIn(
610                                 OCSD_OP_DATA,
611                                 trace_index,
612                                 (uint32_t)(nBuffRead - nBuffProcessed),
613                                 &(trace_buffer[0])+nBuffProcessed,
614                                 &nUsedThisTime);
615 
616                             nBuffProcessed += nUsedThisTime;
617                             trace_index += nUsedThisTime;
618 
619                             // test printers can inject _WAIT responses - see if we are expecting one...
620                             if(ExpectingPPrintWaitResp(dcd_tree, *genElemPrinter))
621                             {
622                                 if(OCSD_DATA_RESP_IS_CONT(dataPathResp))
623                                 {
624                                     // not wait or fatal - log a warning here.
625                                     std::ostringstream oss;
626                                     oss << "Trace Packet Lister : WARNING : Data in; data Path expected WAIT response\n";
627                                     logger.LogMsg(oss.str());
628                                 }
629                             }
630                         }
631                         else // last response was _WAIT
632                         {
633                             // may need to acknowledge a wait from the gen elem printer
634                             if(genElemPrinter->needAckWait())
635                                 genElemPrinter->ackWait();
636 
637                             // dataPathResp not continue or fatal so must be wait...
638                             dataPathResp = dcd_tree->TraceDataIn(OCSD_OP_FLUSH,0,0,0,0);
639                         }
640                     }
641 
642                     /* dump dstream footers */
643                     if (dstream_format) {
644                         in.read((char *)&trace_buffer[0], 8);
645                         if (outRawPacked)
646                         {
647                             std::ostringstream oss;
648                             oss << "DSTREAM footer [";
649                             for (int i = 0; i < 8; i++)
650                             {
651                                 oss << "0x" << std::hex << (int)trace_buffer[i] << " ";
652                             }
653                             oss << "]\n";
654                             logger.LogMsg(oss.str());
655                         }
656                     }
657                 }
658 
659                 // fatal error - no futher processing
660                 if(OCSD_DATA_RESP_IS_FATAL(dataPathResp))
661                 {
662                     std::ostringstream oss;
663                     oss << "Trace Packet Lister : Data Path fatal error\n";
664                     logger.LogMsg(oss.str());
665                     ocsdError *perr = err_logger.GetLastError();
666                     if(perr != 0)
667                         logger.LogMsg(ocsdError::getErrorString(perr));
668 
669                 }
670                 else
671                 {
672                     // mark end of trace into the data path
673                     dcd_tree->TraceDataIn(OCSD_OP_EOT,0,0,0,0);
674                 }
675 
676                 // close the input file.
677                 in.close();
678 
679                 std::ostringstream oss;
680                 oss << "Trace Packet Lister : Trace buffer done, processed " << trace_index << " bytes.\n";
681                 logger.LogMsg(oss.str());
682 
683             }
684             else
685             {
686                 std::ostringstream oss;
687                 oss << "Trace Packet Lister : Error : Unable to open trace buffer.\n";
688                 logger.LogMsg(oss.str());
689             }
690 
691         }
692         else
693         {
694                 std::ostringstream oss;
695                 oss << "Trace Packet Lister : No supported protocols found.\n";
696                 logger.LogMsg(oss.str());
697         }
698 
699         // clean up
700 
701         // get rid of the decode tree.
702         tree_creator.destroyDecodeTree();
703     }
704 }
705 
706 /* End of File trc_pkt_lister.cpp */
707