• 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 static bool profile = false;
79 static bool multi_session = false;  // decode all buffers in snapshot as same config.
80 
81 static bool macc_cache_disable = false;
82 static uint32_t macc_cache_page_size = 0;
83 static uint32_t macc_cache_page_num = 0;
84 
85 static SnapShotReader ss_reader;
86 
main(int argc,char * argv[])87 int main(int argc, char* argv[])
88 {
89     std::ostringstream moss;
90 
91     if(process_cmd_line_logger_opts(argc,argv))
92     {
93         printf("Bad logger command line options\nProgram Exiting\n");
94         return -2;
95     }
96 
97     logger.setLogOpts(logOpts);
98     logger.setLogFileName(logfileName.c_str());
99 
100     moss << "Trace Packet Lister: CS Decode library testing\n";
101     moss << "-----------------------------------------------\n\n";
102     moss << "** Library Version : " << ocsdVersion::vers_str() << "\n\n";
103     logger.LogMsg(moss.str());
104 
105     log_cmd_line_opts(argc,argv);
106 
107     ocsdDefaultErrorLogger err_log;
108     err_log.initErrorLogger(OCSD_ERR_SEV_INFO);
109     err_log.setOutputLogger(&logger);
110 
111     if(!process_cmd_line_opts(argc, argv))
112         return -1;
113 
114     moss.str("");
115     moss << "Trace Packet Lister : reading snapshot from path " << ss_path << "\n";
116     logger.LogMsg(moss.str());
117 
118     ss_reader.setSnapshotDir(ss_path);
119     ss_reader.setErrorLogger(&err_log);
120     ss_reader.setVerboseOutput(ss_verbose);
121 
122     if(ss_reader.snapshotFound())
123     {
124         if(ss_reader.readSnapShot())
125         {
126             std::vector<std::string> sourceBuffList;
127             if(ss_reader.getSourceBufferNameList(sourceBuffList))
128             {
129                 bool bValidSourceName = false;
130                 // check source name list
131                 if(source_buffer_name.size() == 0)
132                 {
133                     // default to first in the list
134                     source_buffer_name = sourceBuffList[0];
135                     bValidSourceName = true;
136                 }
137                 else
138                 {
139                     for(size_t i = 0; i < sourceBuffList.size(); i++)
140                     {
141                         if(sourceBuffList[i] == source_buffer_name)
142                         {
143                             bValidSourceName = true;
144                             break;
145                         }
146                     }
147                 }
148 
149                 if(bValidSourceName)
150                 {
151                     std::ostringstream oss;
152                     oss << "Using " << source_buffer_name << " as trace source\n";
153                     logger.LogMsg(oss.str());
154                     ListTracePackets(err_log,ss_reader,source_buffer_name);
155                 }
156                 else
157                 {
158                     std::ostringstream oss;
159                     oss << "Trace Packet Lister : Trace source name " << source_buffer_name << " not found\n";
160                     logger.LogMsg(oss.str());
161                     oss.str("");
162                     oss << "Valid source names are:-\n";
163                     for(size_t i = 0; i < sourceBuffList.size(); i++)
164                     {
165                         oss << sourceBuffList[i] << "\n";
166                     }
167                     logger.LogMsg(oss.str());
168                 }
169 
170             }
171             else
172                 logger.LogMsg("Trace Packet Lister : No trace source buffer names found\n");
173         }
174         else
175             logger.LogMsg("Trace Packet Lister : Failed to read snapshot\n");
176     }
177     else
178     {
179         std::ostringstream oss;
180         oss << "Trace Packet Lister : Snapshot path" << ss_path << " not found\n";
181         logger.LogMsg(oss.str());
182     }
183 
184     return 0;
185 }
186 
print_help()187 void print_help()
188 {
189     std::ostringstream oss;
190     oss << "Trace Packet Lister - commands\n\n";
191     oss << "Snapshot:\n\n";
192     oss << "-ss_dir <dir>       Set the directory path to a trace snapshot\n";
193     oss << "-ss_verbose         Verbose output when reading the snapshot\n";
194     oss << "\nDecode:\n\n";
195     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";
196     oss << "-src_name <name>    List packets from a given snapshot source name (defaults to first source found)\n";
197     oss << "-multi_session      List packets from all sources - assumes same config for all (ignored if -src_name used)\n";
198     oss << "-dstream_format     Input is DSTREAM framed.\n";
199     oss << "-tpiu               Input from TPIU - sync by FSYNC.\n";
200     oss << "-tpiu_hsync         Input from TPIU - sync by FSYNC and HSYNC.\n";
201     oss << "-decode             Full decode of the packets from the trace snapshot (default is to list undecoded packets only)\n";
202     oss << "-decode_only        Does not list the undecoded packets, just the trace decode.\n";
203     oss << "-o_raw_packed       Output raw packed trace frames\n";
204     oss << "-o_raw_unpacked     Output raw unpacked trace data per ID\n";
205     oss << "-src_addr_n         ETE protocol: Split source address ranges on N atoms\n";
206     oss << "-stats              Output packet processing statistics (if available).\n";
207     oss << "\nDevelopment:\nOptions used during develop and test of the library\n\n";
208     oss << "-profile            Mute logging output while profiling library performance\n";
209     oss << "-test_waits <N>     Force wait from packet printer for N packets - test the wait/flush mechanisms for the decoder\n";
210     oss << "-macc_cache_disable Switch off caching on memory accessor\n";
211     oss << "-macc_cache_p_size  Set size of caching pages\n";
212     oss << "-macc_cache_p_num   Set number of caching pages\n";
213     oss << "\nOutput:\n";
214     oss << "   Setting any of these options cancels the default output to file & stdout,\n   using _only_ the options supplied.\n\n";
215     oss << "-logstdout          Output to stdout -> console.\n";
216     oss << "-logstderr          Output to stderr.\n";
217     oss << "-logfile            Output to default file - " << logfileName << "\n";
218     oss << "-logfilename <name> Output to file <name> \n";
219 
220 
221     logger.LogMsg(oss.str());
222 }
223 
log_cmd_line_opts(int argc,char * argv[])224 void log_cmd_line_opts(int argc, char* argv[])
225 {
226     std::ostringstream oss;
227     oss << "Test Command Line:-\n";
228     oss << argv[0] << "   ";
229     for(int i = 1; i < argc; i++)
230     {
231         oss << argv[i] << "  ";
232     }
233     oss << "\n\n";
234     logger.LogMsg(oss.str());
235 }
236 
237 // true if element ID filtered out
element_filtered(uint8_t elemID)238 bool element_filtered(uint8_t elemID)
239 {
240     bool filtered = false;
241     if(!all_source_ids)
242     {
243         filtered = true;
244         std::vector<uint8_t>::const_iterator it;
245         it = id_list.begin();
246         while((it != id_list.end()) && filtered)
247         {
248             if(*it == elemID)
249                 filtered = false;
250             it++;
251         }
252     }
253     return filtered;
254 }
255 
process_cmd_line_logger_opts(int argc,char * argv[])256 bool process_cmd_line_logger_opts(int argc, char* argv[])
257 {
258     bool badLoggerOpts = false;
259     bool bChangingOptFlags = false;
260     int newlogOpts = ocsdMsgLogger::OUT_NONE;
261     std::string opt;
262     if(argc > 1)
263     {
264         int options_to_process = argc - 1;
265         int optIdx = 1;
266         while(options_to_process > 0)
267         {
268             opt = argv[optIdx];
269             if(opt == "-logstdout")
270             {
271                 newlogOpts |= ocsdMsgLogger::OUT_STDOUT;
272                 bChangingOptFlags = true;
273             }
274             else if(opt == "-logstderr")
275             {
276                 newlogOpts |= ocsdMsgLogger::OUT_STDERR;
277                 bChangingOptFlags = true;
278             }
279             else if(opt == "-logfile")
280             {
281                 newlogOpts |= ocsdMsgLogger::OUT_FILE;
282                 bChangingOptFlags = true;
283             }
284             else if(opt == "-logfilename")
285             {
286                 options_to_process--;
287                 optIdx++;
288                 if(options_to_process)
289                 {
290                     logfileName = argv[optIdx];
291                     newlogOpts |= ocsdMsgLogger::OUT_FILE;
292                     bChangingOptFlags = true;
293                 }
294                 else
295                 {
296                     badLoggerOpts = true;
297                 }
298             }
299             options_to_process--;
300             optIdx++;
301         }
302     }
303     if(bChangingOptFlags)
304         logOpts = newlogOpts;
305     return badLoggerOpts;
306 }
307 
process_cmd_line_opts(int argc,char * argv[])308 bool process_cmd_line_opts(int argc, char* argv[])
309 {
310     bool bOptsOK = true;
311     std::string opt;
312     if(argc > 1)
313     {
314         int options_to_process = argc - 1;
315         int optIdx = 1;
316         while((options_to_process > 0) && bOptsOK)
317         {
318             opt = argv[optIdx];
319             if(opt == "-ss_dir")
320             {
321                 options_to_process--;
322                 optIdx++;
323                 if(options_to_process)
324                     ss_path = argv[optIdx];
325                 else
326                 {
327                     logger.LogMsg("Trace Packet Lister : Error: Missing directory string on -ss_dir option\n");
328                     bOptsOK = false;
329                 }
330             }
331             else if(opt == "-id")
332             {
333                 options_to_process--;
334                 optIdx++;
335                 if(options_to_process)
336                 {
337                     uint8_t Id = (uint8_t)strtoul(argv[optIdx],0,0);
338                     if((Id == 0) || (Id >= 0x70))
339                     {
340                         std::ostringstream iderrstr;
341                         iderrstr << "Trace Packet Lister : Error: invalid ID number 0x" << std::hex << (uint32_t)Id << " on -id option" << std::endl;
342                         logger.LogMsg(iderrstr.str());
343                         bOptsOK = false;
344                     }
345                     else
346                     {
347                         all_source_ids = false;
348                         id_list.push_back(Id);
349                     }
350                 }
351                 else
352                 {
353                     logger.LogMsg("Trace Packet Lister : Error: No ID number on -id option\n");
354                     bOptsOK = false;
355                 }
356             }
357             else if(strcmp(argv[optIdx], "-src_name") == 0)
358             {
359                 options_to_process--;
360                 optIdx++;
361                 if (options_to_process) {
362                     source_buffer_name = argv[optIdx];
363                     multi_session = false;
364                 }
365                 else
366                 {
367                     logger.LogMsg("Trace Packet Lister : Error: Missing source name string on -src_name option\n");
368                     bOptsOK = false;
369                 }
370             }
371             else if (strcmp(argv[optIdx], "-multi_session") == 0)
372             {
373                 if (source_buffer_name.length() == 0)
374                     multi_session = true;
375             }
376             else if(strcmp(argv[optIdx], "-test_waits") == 0)
377             {
378                 options_to_process--;
379                 optIdx++;
380                 if(options_to_process)
381                 {
382                     test_waits = (int)strtol(argv[optIdx],0,0);
383                     if(test_waits < 0)
384                         test_waits = 0;
385                 }
386                 else
387                 {
388                     logger.LogMsg("Trace Packet Lister : Error: wait count value on -test_waits option\n");
389                     bOptsOK = false;
390                 }
391             }
392             else if(strcmp(argv[optIdx], "-o_raw_packed") == 0)
393             {
394                 outRawPacked = true;
395             }
396             else if(strcmp(argv[optIdx], "-o_raw_unpacked") == 0)
397             {
398                 outRawUnpacked = true;
399             }
400             else if(strcmp(argv[optIdx], "-ss_verbose") == 0)
401             {
402                 ss_verbose = true;
403             }
404             else if(strcmp(argv[optIdx], "-decode") == 0)
405             {
406                 decode = true;
407             }
408             else if(strcmp(argv[optIdx], "-pkt_mon") == 0)
409             {
410                 pkt_mon = true;
411             }
412             else if(strcmp(argv[optIdx], "-decode_only") == 0)
413             {
414                 no_undecoded_packets = true;
415                 decode = true;
416             }
417             else if (strcmp(argv[optIdx], "-src_addr_n") == 0)
418             {
419                 src_addr_n = true;
420             }
421             else if (strcmp(argv[optIdx], "-stats") == 0)
422             {
423                 stats = true;
424             }
425             else if((strcmp(argv[optIdx], "-help") == 0) || (strcmp(argv[optIdx], "--help") == 0) || (strcmp(argv[optIdx], "-h") == 0))
426             {
427                 print_help();
428                 bOptsOK = false;
429             }
430             else if((opt == "-logstdout") || (opt == "-logstderr") ||
431                 (opt == "-logfile") || (opt == "-logfilename"))
432             {
433                 // skip all these as processed earlier
434 
435                 // also additionally skip any filename parameter
436                 if(opt == "-logfilename")
437                 {
438                     options_to_process--;
439                     optIdx++;
440                 }
441             }
442             else if (strcmp(argv[optIdx], "-dstream_format") == 0)
443             {
444                 dstream_format = true;
445             }
446             else if (strcmp(argv[optIdx], "-tpiu") == 0)
447             {
448                 tpiu_format = true;
449             }
450             else if (strcmp(argv[optIdx], "-tpiu_hsync") == 0)
451             {
452                 has_hsync = true;
453                 tpiu_format = true;
454             }
455             else if (strcmp(argv[optIdx], "-profile") == 0)
456             {
457                 profile = true;
458             }
459             else if (strcmp(argv[optIdx], "-macc_cache_disable") == 0)
460             {
461                 macc_cache_disable = true;
462             }
463             else if (strcmp(argv[optIdx], "-macc_cache_p_size") == 0)
464             {
465                 options_to_process--;
466                 optIdx++;
467                 if (options_to_process)
468                     macc_cache_page_size  = (uint32_t)strtoul(argv[optIdx], 0, 0);
469             }
470             else if (strcmp(argv[optIdx], "-macc_cache_p_num") == 0)
471             {
472                 options_to_process--;
473                 optIdx++;
474                 if (options_to_process)
475                     macc_cache_page_num = (uint32_t)strtoul(argv[optIdx], 0, 0);
476             }
477             else
478             {
479                 std::ostringstream errstr;
480                 errstr << "Trace Packet Lister : Warning: Ignored unknown option " << argv[optIdx] << "." << std::endl;
481                 logger.LogMsg(errstr.str());
482             }
483             options_to_process--;
484             optIdx++;
485         }
486 
487     }
488     return bOptsOK;
489 }
490 
491 //
492 // 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.
493 // if packet processing only, then waits will be coming from there until the count is extinguished
494 // wait testing with packet processor only really works correctly if we are doing a single source as there is no way at this
495 // 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)496 bool ExpectingPPrintWaitResp(DecodeTree *dcd_tree, TrcGenericElementPrinter &genElemPrinter)
497 {
498     bool ExpectingWaits = false;
499     std::vector<ItemPrinter *> &printers = dcd_tree->getPrinterList();
500     if(test_waits > 0)
501     {
502         // see if last response was from the Gen elem printer expecting a wait
503         ExpectingWaits = genElemPrinter.needAckWait();
504 
505         // now see if any of the active packet printers are returing wait responses.
506         if(!ExpectingWaits)
507         {
508             std::vector<ItemPrinter *>::iterator it;
509             it = printers.begin();
510             while((it != printers.end()) && !ExpectingWaits)
511             {
512                 ExpectingWaits = (bool)((*it)->getTestWaits() != 0);
513                 it++;
514             }
515         }
516 
517         // nothing waiting - and no outstanding wait cycles in the Gen elem printer.
518         if(!ExpectingWaits && (genElemPrinter.getTestWaits() == 0))
519             test_waits = 0;     // zero out the input value if none of the printers currently have waits scheduled.
520     }
521     return ExpectingWaits;
522 }
523 
AttachPacketPrinters(DecodeTree * dcd_tree)524 void AttachPacketPrinters( DecodeTree *dcd_tree)
525 {
526     uint8_t elemID;
527     std::ostringstream oss;
528 
529     // attach packet printers to each trace source in the tree
530     DecodeTreeElement *pElement = dcd_tree->getFirstElement(elemID);
531     while(pElement && !no_undecoded_packets)
532     {
533         if(!element_filtered(elemID))
534         {
535             oss.str("");
536 
537             ItemPrinter *pPrinter;
538             ocsd_err_t err = dcd_tree->addPacketPrinter(elemID, (bool)(decode || pkt_mon),&pPrinter);
539             if (err == OCSD_OK)
540             {
541                 // if not decoding or monitor only
542                 if((!(decode || pkt_mon)) && test_waits)
543                     pPrinter->setTestWaits(test_waits);
544 
545                 oss << "Trace Packet Lister : Protocol printer " << pElement->getDecoderTypeName() <<  " on Trace ID 0x" << std::hex << (uint32_t)elemID << "\n";
546             }
547             else
548                 oss << "Trace Packet Lister : Failed to Protocol printer " << pElement->getDecoderTypeName() << " on Trace ID 0x" << std::hex << (uint32_t)elemID << "\n";
549             logger.LogMsg(oss.str());
550             if (profile)
551                 pPrinter->setMute(true);
552 
553         }
554         pElement = dcd_tree->getNextElement(elemID);
555     }
556 
557 }
558 
ConfigureFrameDeMux(DecodeTree * dcd_tree,RawFramePrinter ** framePrinter)559 void ConfigureFrameDeMux(DecodeTree *dcd_tree, RawFramePrinter **framePrinter)
560 {
561     // configure the frame deformatter, and attach a frame printer to the frame deformatter if needed
562     TraceFormatterFrameDecoder *pDeformatter = dcd_tree->getFrameDeformatter();
563     if(pDeformatter != 0)
564     {
565         // configuration - memory alinged buffer
566         uint32_t configFlags = pDeformatter->getConfigFlags();
567 
568         // check for TPIU FSYNC & HSYNC
569         if (tpiu_format) configFlags |= OCSD_DFRMTR_HAS_FSYNCS;
570         if (has_hsync) configFlags |= OCSD_DFRMTR_HAS_HSYNCS;
571         // if FSYNC (& HSYNC) - cannot be mem frame aligned.
572         if (tpiu_format) configFlags &= ~OCSD_DFRMTR_FRAME_MEM_ALIGN;
573 
574         if (!configFlags)
575         {
576             configFlags = OCSD_DFRMTR_FRAME_MEM_ALIGN;
577         }
578         pDeformatter->Configure(configFlags);
579 
580         if (outRawPacked || outRawUnpacked)
581         {
582             if (outRawPacked) configFlags |= OCSD_DFRMTR_PACKED_RAW_OUT;
583             if (outRawUnpacked) configFlags |= OCSD_DFRMTR_UNPACKED_RAW_OUT;
584             dcd_tree->addRawFramePrinter(framePrinter, configFlags);
585         }
586     }
587 }
588 
PrintDecodeStats(DecodeTree * dcd_tree)589 void PrintDecodeStats(DecodeTree *dcd_tree)
590 {
591     uint8_t elemID;
592     std::ostringstream oss;
593     ocsd_decode_stats_t *pStats = 0;
594     ocsd_err_t err;
595     bool gotDemuxStats = false;
596     ocsd_demux_stats_t demux_stats;
597 
598     oss << "\nReading packet decoder statistics....\n\n";
599     logger.LogMsg(oss.str());
600 
601     DecodeTreeElement *pElement = dcd_tree->getFirstElement(elemID);
602     while (pElement)
603     {
604         oss.str("");
605         err = dcd_tree->getDecoderStats(elemID, &pStats);
606         if (!err && pStats)
607         {
608             oss << "Decode stats ID 0x" << std::hex << (uint32_t)elemID << "\n";
609             oss << "Total Bytes: " << std::dec << pStats->channel_total << "; Unsynced Bytes: " << std::dec << pStats->channel_unsynced << "\n";
610             oss << "Bad Header Errors: " << std::dec << pStats->bad_header_errs << "; Bad Sequence Errors: " << std::dec << pStats->bad_sequence_errs << "\n";
611 
612             // demux stats same for all IDs - grab them at the first opportunity..
613             if (!gotDemuxStats) {
614                 memcpy(&demux_stats, &pStats->demux, sizeof(ocsd_demux_stats_t));
615                 gotDemuxStats = true;
616             }
617 
618         }
619         else
620             oss << "Decode stats unavailable on Trace ID 0x" << std::hex << (uint32_t)elemID << "\n";
621 
622 
623         logger.LogMsg(oss.str());
624         pElement = dcd_tree->getNextElement(elemID);
625     }
626 
627     // if we have copied over the stats and there is at least 1 frame byte (impossible for there to be 0 if demuxing)
628     if (gotDemuxStats && demux_stats.frame_bytes) {
629         uint64_t total = demux_stats.valid_id_bytes + demux_stats.no_id_bytes + demux_stats.unknown_id_bytes +
630                          demux_stats.reserved_id_bytes + demux_stats.frame_bytes;
631         oss.str("");
632         oss << "\nFrame Demux Stats\n";
633         oss << "Trace data bytes sent to registered ID decoders: " << std::dec << demux_stats.valid_id_bytes << "\n";
634         oss << "Trace data bytes without registered ID decoders: " << std::dec << demux_stats.no_id_bytes << "\n";
635         oss << "Trace data bytes with unknown ID: " << std::dec << demux_stats.unknown_id_bytes << "\n";
636         oss << "Trace data bytes with reserved ID: " << std::dec << demux_stats.reserved_id_bytes << "\n";
637         oss << "Frame demux bytes, ID bytes and sync bytes: " << std::dec << demux_stats.frame_bytes << "\n";
638         oss << "Total bytes processed by frame demux: " << std::dec << total << "\n\n";
639         logger.LogMsg(oss.str());
640     }
641 }
642 
ProcessInputFile(DecodeTree * dcd_tree,std::string & in_filename,TrcGenericElementPrinter * genElemPrinter,ocsdDefaultErrorLogger & err_logger)643 bool ProcessInputFile(DecodeTree *dcd_tree, std::string &in_filename,
644                       TrcGenericElementPrinter* genElemPrinter, ocsdDefaultErrorLogger& err_logger)
645 {
646     bool bOK = true;
647 
648     // need to push the data through the decode tree.
649     std::ifstream in;
650     in.open(in_filename, std::ifstream::in | std::ifstream::binary);
651     if (in.is_open())
652     {
653         ocsd_datapath_resp_t dataPathResp = OCSD_RESP_CONT;
654         static const int bufferSize = 1024;
655         uint8_t trace_buffer[bufferSize];   // temporary buffer to load blocks of data from the file
656         uint32_t trace_index = 0;           // index into the overall trace buffer (file).
657 
658         // process the file, a buffer load at a time
659         while (!in.eof() && !OCSD_DATA_RESP_IS_FATAL(dataPathResp))
660         {
661             if (dstream_format)
662             {
663                 in.read((char*)&trace_buffer[0], 512 - 8);
664             }
665             else
666                 in.read((char*)&trace_buffer[0], bufferSize);   // load a block of data into the buffer
667 
668             std::streamsize nBuffRead = in.gcount();    // get count of data loaded.
669             std::streamsize nBuffProcessed = 0;         // amount processed in this buffer.
670             uint32_t nUsedThisTime = 0;
671 
672             // process the current buffer load until buffer done, or fatal error occurs
673             while ((nBuffProcessed < nBuffRead) && !OCSD_DATA_RESP_IS_FATAL(dataPathResp))
674             {
675                 if (OCSD_DATA_RESP_IS_CONT(dataPathResp))
676                 {
677                     dataPathResp = dcd_tree->TraceDataIn(
678                         OCSD_OP_DATA,
679                         trace_index,
680                         (uint32_t)(nBuffRead - nBuffProcessed),
681                         &(trace_buffer[0]) + nBuffProcessed,
682                         &nUsedThisTime);
683 
684                     nBuffProcessed += nUsedThisTime;
685                     trace_index += nUsedThisTime;
686 
687                     // test printers can inject _WAIT responses - see if we are expecting one...
688                     if (ExpectingPPrintWaitResp(dcd_tree, *genElemPrinter))
689                     {
690                         if (OCSD_DATA_RESP_IS_CONT(dataPathResp))
691                         {
692                             // not wait or fatal - log a warning here.
693                             std::ostringstream oss;
694                             oss << "Trace Packet Lister : WARNING : Data in; data Path expected WAIT response\n";
695                             logger.LogMsg(oss.str());
696                         }
697                     }
698                 }
699                 else // last response was _WAIT
700                 {
701                     // may need to acknowledge a wait from the gen elem printer
702                     if (genElemPrinter->needAckWait())
703                         genElemPrinter->ackWait();
704 
705                     // dataPathResp not continue or fatal so must be wait...
706                     dataPathResp = dcd_tree->TraceDataIn(OCSD_OP_FLUSH, 0, 0, 0, 0);
707                 }
708             }
709 
710             /* dump dstream footers */
711             if (dstream_format) {
712                 in.read((char*)&trace_buffer[0], 8);
713                 if (outRawPacked)
714                 {
715                     std::ostringstream oss;
716                     oss << "DSTREAM footer [";
717                     for (int i = 0; i < 8; i++)
718                     {
719                         oss << "0x" << std::hex << (int)trace_buffer[i] << " ";
720                     }
721                     oss << "]\n";
722                     logger.LogMsg(oss.str());
723                 }
724             }
725         }
726 
727         // fatal error - no futher processing
728         if (OCSD_DATA_RESP_IS_FATAL(dataPathResp))
729         {
730             std::ostringstream oss;
731             oss << "Trace Packet Lister : Data Path fatal error\n";
732             logger.LogMsg(oss.str());
733             ocsdError* perr = err_logger.GetLastError();
734             if (perr != 0)
735                 logger.LogMsg(ocsdError::getErrorString(perr));
736             bOK = false;
737         }
738         else
739         {
740             // mark end of trace into the data path
741             dcd_tree->TraceDataIn(OCSD_OP_EOT, 0, 0, 0, 0);
742         }
743 
744         // close the input file.
745         in.close();
746 
747         std::ostringstream oss;
748         oss << "Trace Packet Lister : Trace buffer done, processed " << trace_index << " bytes.\n";
749         logger.LogMsg(oss.str());
750         if (stats)
751             PrintDecodeStats(dcd_tree);
752         if (profile)
753             genElemPrinter->printStats();
754 
755         // multi-session - reset the decoder for the next pass.
756         if (multi_session)
757             dcd_tree->TraceDataIn(OCSD_OP_RESET, 0, 0, 0, 0);
758     }
759     else
760     {
761         std::ostringstream oss;
762         oss << "Trace Packet Lister : Error : Unable to open trace buffer.\n";
763         logger.LogMsg(oss.str());
764     }
765     return bOK;
766 }
767 
ListTracePackets(ocsdDefaultErrorLogger & err_logger,SnapShotReader & reader,const std::string & trace_buffer_name)768 void ListTracePackets(ocsdDefaultErrorLogger &err_logger, SnapShotReader &reader, const std::string &trace_buffer_name)
769 {
770     CreateDcdTreeFromSnapShot tree_creator;
771 
772     tree_creator.initialise(&reader, &err_logger);
773 
774     if(tree_creator.createDecodeTree(trace_buffer_name, (decode == false), src_addr_n ? ETE_OPFLG_PKTDEC_SRCADDR_N_ATOMS : 0))
775     {
776         DecodeTree *dcd_tree = tree_creator.getDecodeTree();
777         dcd_tree->setAlternateErrorLogger(&err_logger);
778 
779         RawFramePrinter *framePrinter = 0;
780         TrcGenericElementPrinter *genElemPrinter = 0;
781 
782         AttachPacketPrinters(dcd_tree);
783 
784         ConfigureFrameDeMux(dcd_tree, &framePrinter);
785         if (profile && framePrinter)
786             framePrinter->setMute(true);
787 
788         // if decoding set the generic element printer to the output interface on the tree.
789         if(decode)
790         {
791             std::ostringstream oss;
792             //dcd_tree->setGenTraceElemOutI(genElemPrinter);
793             dcd_tree->addGenElemPrinter(&genElemPrinter);
794             oss << "Trace Packet Lister : Set trace element decode printer\n";
795             logger.LogMsg(oss.str());
796             genElemPrinter->setTestWaits(test_waits);
797             if (profile)
798             {
799                 genElemPrinter->setMute(true);
800                 genElemPrinter->set_collect_stats();
801             }
802             if (macc_cache_disable || macc_cache_page_size || macc_cache_page_num)
803             {
804                 TrcMemAccMapper* pMapper = dcd_tree->getMemAccMapper();
805 
806                 if (macc_cache_disable)
807                     pMapper->enableCaching(false);
808                 else
809                 {
810                     // one value set - set the other to default
811                     if (!macc_cache_page_size)
812                         macc_cache_page_size = MEM_ACC_CACHE_DEFAULT_PAGE_SIZE;
813                     if (!macc_cache_page_num)
814                         macc_cache_page_num = MEM_ACC_CACHE_DEFAULT_MRU_SIZE;
815                     pMapper->setCacheSizes(macc_cache_page_size, macc_cache_page_num);
816                 }
817             }
818         }
819 
820         if(decode)
821             dcd_tree->logMappedRanges();    // print out the mapped ranges
822 
823          // check if we have attached at least one printer
824         if(decode || (PktPrinterFact::numPrinters(dcd_tree->getPrinterList()) > 0))
825         {
826             // set up the filtering at the tree level (avoid pushing to processors with no attached printers)
827             if(!all_source_ids)
828                 dcd_tree->setIDFilter(id_list);
829             else
830                 dcd_tree->clearIDFilter();
831 
832             std::string binFileName;
833             if (!multi_session)
834             {
835                 binFileName = tree_creator.getBufferFileName();
836                 ProcessInputFile(dcd_tree, binFileName, genElemPrinter, err_logger);
837             }
838             else
839             {
840                 std::ostringstream oss;
841                 std::vector<std::string> sourceBuffList;
842                 ss_reader.getSourceBufferNameList(sourceBuffList);
843 
844                 for (size_t i = 0; i < sourceBuffList.size(); i++)
845                 {
846                     oss.str("");
847                     oss << "####### Multi Session decode: Buffer " << (i+1) << " of " << sourceBuffList.size();
848                     oss << "; Source name = " << sourceBuffList[i] << ".\n\n";
849                     logger.LogMsg(oss.str());
850 
851                     binFileName = tree_creator.getBufferFileNameFromBuffName(sourceBuffList[i]);
852                     if (binFileName.length() <= 0)
853                     {
854                         oss.str("");
855                         oss << "Trace Packet Lister : ERROR : Multi-session decode for buffer " << sourceBuffList[i] << " - buffer not found. Aborting.\n\n";
856                         logger.LogMsg(oss.str());
857                         break;
858                     }
859 
860                     if (!ProcessInputFile(dcd_tree, binFileName, genElemPrinter, err_logger)) {
861                         oss.str("");
862                         oss << "Trace Packet Lister : ERROR : Multi-session decode for buffer " << sourceBuffList[i] << " failed. Aborting.\n\n";
863                         logger.LogMsg(oss.str());
864                         break;
865                     }
866                     oss.str("");
867                     oss << "####### Buffer " << (i + 1) << " : " << sourceBuffList[i] << " Complete\n\n";
868                     logger.LogMsg(oss.str());
869                 }
870             }
871         }
872         else
873         {
874                 std::ostringstream oss;
875                 oss << "Trace Packet Lister : No supported protocols found.\n";
876                 logger.LogMsg(oss.str());
877         }
878 
879         // clean up
880 
881         // get rid of the decode tree.
882         tree_creator.destroyDecodeTree();
883     }
884 }
885 
886 /* End of File trc_pkt_lister.cpp */
887