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