]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/opencsd/decoder/source/ocsd_dcd_tree.cpp
Re-add opencsd as a vendor import from the dist directory
[FreeBSD/FreeBSD.git] / contrib / opencsd / decoder / source / ocsd_dcd_tree.cpp
1 /*
2  * \file       ocsd_dcd_tree.cpp
3  * \brief      OpenCSD : 
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 #include "common/ocsd_dcd_tree.h"
37 #include "common/ocsd_lib_dcd_register.h"
38 #include "mem_acc/trc_mem_acc_mapper.h"
39
40 /***************************************************************/
41 ITraceErrorLog *DecodeTree::s_i_error_logger = &DecodeTree::s_error_logger; 
42 std::list<DecodeTree *> DecodeTree::s_trace_dcd_trees;  /**< list of pointers to decode tree objects */
43 ocsdDefaultErrorLogger DecodeTree::s_error_logger;     /**< The library default error logger */
44 TrcIDecode DecodeTree::s_instruction_decoder;           /**< default instruction decode library */
45
46 DecodeTree *DecodeTree::CreateDecodeTree(const ocsd_dcd_tree_src_t src_type, uint32_t formatterCfgFlags)
47 {
48     DecodeTree *dcd_tree = new (std::nothrow) DecodeTree();
49     if(dcd_tree != 0)
50     {
51         if(dcd_tree->initialise(src_type, formatterCfgFlags))
52         {
53             s_trace_dcd_trees.push_back(dcd_tree);
54         }
55         else 
56         {
57             delete dcd_tree;
58             dcd_tree = 0;
59         }
60     }
61     return dcd_tree;
62 }
63
64 void DecodeTree::DestroyDecodeTree(DecodeTree *p_dcd_tree)
65 {
66     std::list<DecodeTree *>::iterator it;
67     bool bDestroyed = false;
68     it = s_trace_dcd_trees.begin();
69     while(!bDestroyed && (it != s_trace_dcd_trees.end()))
70     {
71         if(*it == p_dcd_tree)
72         {
73             s_trace_dcd_trees.erase(it);
74             delete p_dcd_tree;
75             bDestroyed = true;
76         }
77         else
78             it++;
79     }
80 }
81
82 void DecodeTree::setAlternateErrorLogger(ITraceErrorLog *p_error_logger)
83 {
84     if(p_error_logger)
85         s_i_error_logger = p_error_logger;
86     else
87         s_i_error_logger = &s_error_logger;
88 }
89
90 /***************************************************************/
91
92 DecodeTree::DecodeTree() :
93     m_i_instr_decode(&s_instruction_decoder),
94     m_i_mem_access(0),
95     m_i_gen_elem_out(0),
96     m_i_decoder_root(0),
97     m_frame_deformatter_root(0),
98     m_decode_elem_iter(0),
99     m_default_mapper(0),
100     m_created_mapper(false)
101 {
102     for(int i = 0; i < 0x80; i++)
103         m_decode_elements[i] = 0;
104 }
105
106 DecodeTree::~DecodeTree()
107 {
108     destroyMemAccMapper();
109     for(uint8_t i = 0; i < 0x80; i++)
110     {
111         destroyDecodeElement(i);
112     }
113     PktPrinterFact::destroyAllPrinters(m_printer_list);
114 }
115
116
117
118 ocsd_datapath_resp_t DecodeTree::TraceDataIn( const ocsd_datapath_op_t op,
119                                                const ocsd_trc_index_t index,
120                                                const uint32_t dataBlockSize,
121                                                const uint8_t *pDataBlock,
122                                                uint32_t *numBytesProcessed)
123 {
124     if(m_i_decoder_root)
125         return m_i_decoder_root->TraceDataIn(op,index,dataBlockSize,pDataBlock,numBytesProcessed);
126     *numBytesProcessed = 0;
127     return OCSD_RESP_FATAL_NOT_INIT;
128 }
129
130 /* set key interfaces - attach / replace on any existing tree components */
131 void DecodeTree::setInstrDecoder(IInstrDecode *i_instr_decode)
132 {
133     uint8_t elemID;
134     DecodeTreeElement *pElem = 0;
135
136     pElem = getFirstElement(elemID);
137     while(pElem != 0)
138     {
139         pElem->getDecoderMngr()->attachInstrDecoder(pElem->getDecoderHandle(),i_instr_decode);
140         pElem = getNextElement(elemID);
141     }
142 }
143
144 void DecodeTree::setMemAccessI(ITargetMemAccess *i_mem_access)
145 {
146     uint8_t elemID;
147     DecodeTreeElement *pElem = 0;
148    
149     pElem = getFirstElement(elemID);
150     while(pElem != 0)
151     {
152         pElem->getDecoderMngr()->attachMemAccessor(pElem->getDecoderHandle(),i_mem_access);
153         pElem = getNextElement(elemID);
154     }
155     m_i_mem_access = i_mem_access;
156 }
157
158 void DecodeTree::setGenTraceElemOutI(ITrcGenElemIn *i_gen_trace_elem)
159 {
160     uint8_t elemID;
161     DecodeTreeElement *pElem = 0;
162
163     pElem = getFirstElement(elemID);
164     while(pElem != 0)
165     {
166         pElem->getDecoderMngr()->attachOutputSink(pElem->getDecoderHandle(),i_gen_trace_elem);
167         pElem = getNextElement(elemID);
168     }
169 }
170
171 ocsd_err_t DecodeTree::createMemAccMapper(memacc_mapper_t type /* = MEMACC_MAP_GLOBAL*/ )
172 {
173     // clean up any old one
174     destroyMemAccMapper();
175
176     // make a new one
177     switch(type)
178     {
179     default:
180     case MEMACC_MAP_GLOBAL:
181         m_default_mapper = new (std::nothrow) TrcMemAccMapGlobalSpace();
182         break;
183     }
184
185     // set the access interface
186     if(m_default_mapper)
187     {
188         m_created_mapper = true;
189         setMemAccessI(m_default_mapper);
190         m_default_mapper->setErrorLog(s_i_error_logger);
191     }
192
193     return (m_default_mapper != 0) ? OCSD_OK : OCSD_ERR_MEM;
194 }
195
196 void DecodeTree::setExternMemAccMapper(TrcMemAccMapper* pMapper)
197 {
198     destroyMemAccMapper();  // destroy any existing mapper - if decode tree created it.
199     m_default_mapper = pMapper;
200 }
201
202 void DecodeTree::destroyMemAccMapper()
203 {
204     if(m_default_mapper && m_created_mapper)
205     {
206         m_default_mapper->RemoveAllAccessors();
207         delete m_default_mapper;
208         m_default_mapper = 0;
209         m_created_mapper = false;
210     }
211 }
212
213 void DecodeTree::logMappedRanges()
214 {
215     if(m_default_mapper)
216         m_default_mapper->logMappedRanges();
217 }
218
219 /* Memory accessor creation - all on default mem accessor using the 0 CSID for global core space. */
220 ocsd_err_t DecodeTree::addBufferMemAcc(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const uint8_t *p_mem_buffer, const uint32_t mem_length)
221 {
222     if(!hasMemAccMapper())
223         return OCSD_ERR_NOT_INIT;
224
225     // need a valid memory buffer, and a least enough bytes for one opcode.
226     if((p_mem_buffer == 0) || (mem_length < 4))
227         return OCSD_ERR_INVALID_PARAM_VAL;
228
229     TrcMemAccessorBase *p_accessor;
230     ocsd_err_t err = TrcMemAccFactory::CreateBufferAccessor(&p_accessor, address, p_mem_buffer, mem_length);
231     if(err == OCSD_OK)
232     {
233         TrcMemAccBufPtr *pMBuffAcc = dynamic_cast<TrcMemAccBufPtr *>(p_accessor);
234         if(pMBuffAcc)
235         {
236             pMBuffAcc->setMemSpace(mem_space);
237             err = m_default_mapper->AddAccessor(p_accessor,0);
238         }
239         else
240             err = OCSD_ERR_MEM;    // wrong type of object - treat as mem error
241
242         if(err != OCSD_OK)
243             TrcMemAccFactory::DestroyAccessor(p_accessor);
244     }
245     return err;
246 }
247
248 ocsd_err_t DecodeTree::addBinFileMemAcc(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const std::string &filepath)
249 {
250     if(!hasMemAccMapper())
251         return OCSD_ERR_NOT_INIT;
252     
253     if(filepath.length() == 0)
254         return OCSD_ERR_INVALID_PARAM_VAL;
255
256     TrcMemAccessorBase *p_accessor;
257     ocsd_err_t err = TrcMemAccFactory::CreateFileAccessor(&p_accessor,filepath,address);
258
259     if(err == OCSD_OK)
260     {
261         TrcMemAccessorFile *pAcc = dynamic_cast<TrcMemAccessorFile *>(p_accessor);
262         if(pAcc)
263         {
264             pAcc->setMemSpace(mem_space);
265             err = m_default_mapper->AddAccessor(pAcc,0);
266         }
267         else
268             err = OCSD_ERR_MEM;    // wrong type of object - treat as mem error
269
270         if(err != OCSD_OK)
271             TrcMemAccFactory::DestroyAccessor(p_accessor);
272     }
273     return err;
274
275 }
276
277 ocsd_err_t DecodeTree::addBinFileRegionMemAcc(const ocsd_file_mem_region_t *region_array, const int num_regions, const ocsd_mem_space_acc_t mem_space, const std::string &filepath)
278 {
279     if(!hasMemAccMapper())
280         return OCSD_ERR_NOT_INIT;
281
282     if((region_array == 0) || (num_regions == 0) || (filepath.length() == 0))
283         return OCSD_ERR_INVALID_PARAM_VAL;
284
285     TrcMemAccessorBase *p_accessor;
286     int curr_region_idx = 0;
287
288     // add first region during the creation of the file accessor.
289     ocsd_err_t err = TrcMemAccFactory::CreateFileAccessor(&p_accessor,filepath,region_array[curr_region_idx].start_address,region_array[curr_region_idx].file_offset, region_array[curr_region_idx].region_size);            
290     if(err == OCSD_OK)
291     {
292         TrcMemAccessorFile *pAcc = dynamic_cast<TrcMemAccessorFile *>(p_accessor);
293         if(pAcc)
294         {
295             // add additional regions to the file accessor.
296             curr_region_idx++;
297             while(curr_region_idx < num_regions)
298             {
299                 pAcc->AddOffsetRange(region_array[curr_region_idx].start_address, 
300                                         region_array[curr_region_idx].region_size,
301                                         region_array[curr_region_idx].file_offset);
302                 curr_region_idx++;
303             }
304             pAcc->setMemSpace(mem_space);
305
306             // add the accessor to the map.
307             err = m_default_mapper->AddAccessor(pAcc,0);
308         }
309         else
310             err = OCSD_ERR_MEM;    // wrong type of object - treat as mem error
311
312         if(err != OCSD_OK)
313             TrcMemAccFactory::DestroyAccessor(p_accessor);
314     }
315     return err;
316 }
317
318 ocsd_err_t DecodeTree::updateBinFileRegionMemAcc(const ocsd_file_mem_region_t *region_array, const int num_regions, const ocsd_mem_space_acc_t mem_space, const std::string &filepath)
319 {
320     if (!hasMemAccMapper())
321         return OCSD_ERR_NOT_INIT;
322
323     if ((region_array == 0) || (num_regions == 0) || (filepath.length() == 0))
324         return OCSD_ERR_INVALID_PARAM_VAL;
325
326     TrcMemAccessorFile *pAcc = TrcMemAccessorFile::getExistingFileAccessor(filepath);
327     if (!pAcc) 
328         return OCSD_ERR_INVALID_PARAM_VAL;
329
330     int curr_region_idx = 0;
331     while (curr_region_idx < num_regions)
332     {
333         // check "new" range
334         if (!pAcc->addrStartOfRange(region_array[curr_region_idx].start_address))
335         {
336             // ensure adds cleanly
337             if (!pAcc->AddOffsetRange(region_array[curr_region_idx].start_address,
338                 region_array[curr_region_idx].region_size,
339                 region_array[curr_region_idx].file_offset))
340                 return OCSD_ERR_INVALID_PARAM_VAL;  // otherwise bail out
341         }
342         curr_region_idx++;
343     }
344     return OCSD_OK;
345 }
346 ocsd_err_t DecodeTree::initCallbackMemAcc(const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address, 
347     const ocsd_mem_space_acc_t mem_space, void *p_cb_func, bool IDfn, const void *p_context)
348 {
349     if(!hasMemAccMapper())
350         return OCSD_ERR_NOT_INIT;
351
352     if(p_cb_func == 0)
353         return OCSD_ERR_INVALID_PARAM_VAL;
354
355     TrcMemAccessorBase *p_accessor;
356     ocsd_err_t err = TrcMemAccFactory::CreateCBAccessor(&p_accessor, st_address, en_address, mem_space);
357     if(err == OCSD_OK)
358     {
359         TrcMemAccCB *pCBAcc = dynamic_cast<TrcMemAccCB *>(p_accessor);
360         if(pCBAcc)
361         {
362             if (IDfn)
363                 pCBAcc->setCBIDIfFn((Fn_MemAccID_CB)p_cb_func, p_context);
364             else
365                 pCBAcc->setCBIfFn((Fn_MemAcc_CB)p_cb_func, p_context);
366
367             err = m_default_mapper->AddAccessor(p_accessor,0);
368         }
369         else
370             err = OCSD_ERR_MEM;    // wrong type of object - treat as mem error
371
372         if(err != OCSD_OK)
373             TrcMemAccFactory::DestroyAccessor(p_accessor);
374     }
375     return err;
376 }
377
378 ocsd_err_t DecodeTree::addCallbackMemAcc(const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address, const ocsd_mem_space_acc_t mem_space, Fn_MemAcc_CB p_cb_func, const void *p_context)
379 {
380     return initCallbackMemAcc(st_address, en_address, mem_space, (void *)p_cb_func, false, p_context);
381 }
382
383 ocsd_err_t DecodeTree::addCallbackIDMemAcc(const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address, const ocsd_mem_space_acc_t mem_space, Fn_MemAccID_CB p_cb_func, const void *p_context)
384 {
385     return initCallbackMemAcc(st_address, en_address, mem_space, (void *)p_cb_func, true, p_context);
386 }
387
388 ocsd_err_t DecodeTree::removeMemAccByAddress(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space)
389 {
390     if(!hasMemAccMapper())
391         return OCSD_ERR_NOT_INIT;
392     return m_default_mapper->RemoveAccessorByAddress(address,mem_space,0);
393 }
394
395 ocsd_err_t DecodeTree::createDecoder(const std::string &decoderName, const int createFlags, const CSConfig *pConfig)
396 {
397     ocsd_err_t err = OCSD_OK;
398     IDecoderMngr *pDecoderMngr = 0;
399     TraceComponent *pTraceComp = 0;
400     int crtFlags = createFlags;
401
402     uint8_t CSID = 0;   // default for single stream decoder (no deformatter) - we ignore the ID
403     if(usingFormatter())
404     {
405         CSID = pConfig->getTraceID();
406         crtFlags |= OCSD_CREATE_FLG_INST_ID;
407     }
408
409     // create the decode element to attach to the channel.
410     if((err = createDecodeElement(CSID)) != OCSD_OK)
411         return err;
412
413     // get the libary decoder register.
414     OcsdLibDcdRegister * lib_reg = OcsdLibDcdRegister::getDecoderRegister();
415     if(lib_reg == 0)
416         return OCSD_ERR_NOT_INIT;
417
418     // find the named decoder
419     if((err = lib_reg->getDecoderMngrByName(decoderName,&pDecoderMngr)) != OCSD_OK)
420         return err;
421
422     // got the decoder...
423     if((err = pDecoderMngr->createDecoder(crtFlags,(int)CSID,pConfig,&pTraceComp)) != OCSD_OK)
424         return err;
425
426     m_decode_elements[CSID]->SetDecoderElement(decoderName, pDecoderMngr, pTraceComp, true);
427
428     // always attach an error logger
429     if(err == OCSD_OK)
430         err = pDecoderMngr->attachErrorLogger(pTraceComp,DecodeTree::s_i_error_logger);
431
432     // if we created a packet decoder it may need additional components.
433     if(crtFlags &  OCSD_CREATE_FLG_FULL_DECODER)
434     {
435         if(m_i_instr_decode && (err == OCSD_OK))
436             err = pDecoderMngr->attachInstrDecoder(pTraceComp,m_i_instr_decode);
437         
438         if(err == OCSD_ERR_DCD_INTERFACE_UNUSED)    // ignore if instruction decoder refused
439             err = OCSD_OK;
440
441         if(m_i_mem_access && (err == OCSD_OK))
442             err = pDecoderMngr->attachMemAccessor(pTraceComp,m_i_mem_access);
443
444         if(err == OCSD_ERR_DCD_INTERFACE_UNUSED)    // ignore if mem accessor refused
445             err = OCSD_OK;
446
447         if( m_i_gen_elem_out && (err == OCSD_OK))
448             err = pDecoderMngr->attachOutputSink(pTraceComp,m_i_gen_elem_out);
449     }
450
451     // finally attach the packet processor input to the demux output channel
452     if(err == OCSD_OK)
453     {
454         ITrcDataIn *pDataIn = 0;
455         if((err = pDecoderMngr->getDataInputI(pTraceComp,&pDataIn)) == OCSD_OK)
456         {
457             // got the interface -> attach to demux, or direct to input of decode tree
458             if(usingFormatter())
459                 err = m_frame_deformatter_root->getIDStreamAttachPt(CSID)->attach(pDataIn);
460             else
461                 m_i_decoder_root = pDataIn;
462         }
463     }
464
465     if(err != OCSD_OK)
466     {
467         destroyDecodeElement(CSID); // will destroy decoder as well.       
468     }
469     return err;
470 }
471
472 ocsd_err_t DecodeTree::removeDecoder(const uint8_t CSID)
473 {
474     ocsd_err_t err = OCSD_OK;
475     uint8_t localID = CSID;
476     if(!usingFormatter())
477         localID = 0;
478
479     if(usingFormatter() && !OCSD_IS_VALID_CS_SRC_ID(CSID))
480         err = OCSD_ERR_INVALID_ID;
481     else
482     {
483         destroyDecodeElement(localID);
484     }
485     return err;
486 }
487
488 DecodeTreeElement * DecodeTree::getDecoderElement(const uint8_t CSID) const
489 {
490     DecodeTreeElement *ret_elem = 0;
491     if(usingFormatter() && OCSD_IS_VALID_CS_SRC_ID(CSID))
492     {
493         ret_elem = m_decode_elements[CSID]; 
494     }
495     else
496         ret_elem = m_decode_elements[0];    // ID 0 is used if single leaf tree.
497     return ret_elem;
498 }
499
500 DecodeTreeElement *DecodeTree::getFirstElement(uint8_t &elemID)
501 {
502     m_decode_elem_iter = 0;
503     return getNextElement(elemID);
504 }
505
506 DecodeTreeElement *DecodeTree::getNextElement(uint8_t &elemID)
507 {
508     DecodeTreeElement *ret_elem = 0;
509
510     if(m_decode_elem_iter < 0x80)
511     {
512         // find a none zero entry or end of range
513         while((m_decode_elements[m_decode_elem_iter] == 0) && (m_decode_elem_iter < 0x80))
514             m_decode_elem_iter++;
515
516         // return entry unless end of range
517         if(m_decode_elem_iter < 0x80)
518         {
519             ret_elem = m_decode_elements[m_decode_elem_iter];
520             elemID = m_decode_elem_iter;
521             m_decode_elem_iter++;
522         }
523     }
524     return ret_elem;
525 }
526
527 bool DecodeTree::initialise(const ocsd_dcd_tree_src_t type, uint32_t formatterCfgFlags)
528 {
529     bool initOK = true;
530     m_dcd_tree_type = type;
531     if(type ==  OCSD_TRC_SRC_FRAME_FORMATTED)
532     {
533         // frame formatted - we want to create the deformatter and hook it up
534         m_frame_deformatter_root = new (std::nothrow) TraceFormatterFrameDecoder();
535         if(m_frame_deformatter_root)
536         {
537             m_frame_deformatter_root->Configure(formatterCfgFlags);
538             m_frame_deformatter_root->getErrLogAttachPt()->attach(DecodeTree::s_i_error_logger);
539             m_i_decoder_root = dynamic_cast<ITrcDataIn*>(m_frame_deformatter_root);
540         }
541         else 
542             initOK = false;
543     }
544     return initOK;
545 }
546
547 void DecodeTree::setSingleRoot(TrcPktProcI *pComp)
548 {
549     m_i_decoder_root = static_cast<ITrcDataIn*>(pComp);
550 }
551
552 ocsd_err_t DecodeTree::createDecodeElement(const uint8_t CSID)
553 {
554     ocsd_err_t err = OCSD_ERR_INVALID_ID;
555     if(CSID < 0x80)
556     {
557         if(m_decode_elements[CSID] == 0)
558         {
559             m_decode_elements[CSID] = new (std::nothrow) DecodeTreeElement();
560             if(m_decode_elements[CSID] == 0)
561                 err = OCSD_ERR_MEM;
562             else 
563                 err = OCSD_OK;
564         }
565         else
566             err = OCSD_ERR_ATTACH_TOO_MANY;
567     }
568     return err;
569 }
570
571 void DecodeTree::destroyDecodeElement(const uint8_t CSID)
572 {
573     if(CSID < 0x80)
574     {
575         if(m_decode_elements[CSID] != 0)
576         {
577             m_decode_elements[CSID]->DestroyElem();
578             delete m_decode_elements[CSID];
579             m_decode_elements[CSID] = 0;
580         }
581     }
582 }
583
584 ocsd_err_t DecodeTree::setIDFilter(std::vector<uint8_t> &ids)
585 {
586     ocsd_err_t err = OCSD_ERR_DCDT_NO_FORMATTER;
587     if(usingFormatter())
588     {
589         err = m_frame_deformatter_root->OutputFilterAllIDs(false);
590         if(err == OCSD_OK)
591             err = m_frame_deformatter_root->OutputFilterIDs(ids,true);
592     }
593     return err;
594 }
595
596 ocsd_err_t DecodeTree::clearIDFilter()
597 {
598     ocsd_err_t err = OCSD_ERR_DCDT_NO_FORMATTER;
599     if(usingFormatter())
600     {
601         err = m_frame_deformatter_root->OutputFilterAllIDs(true);
602     }
603     return err;
604 }
605
606 /** add a protocol packet printer */
607 ocsd_err_t DecodeTree::addPacketPrinter(uint8_t CSID, bool bMonitor, ItemPrinter **ppPrinter)
608 {
609     ocsd_err_t err = OCSD_ERR_INVALID_PARAM_VAL;
610     DecodeTreeElement *pElement = getDecoderElement(CSID);
611     if (pElement)
612     {
613         ocsd_trace_protocol_t protocol = pElement->getProtocol();
614         ItemPrinter *pPrinter;
615
616         pPrinter = PktPrinterFact::createProtocolPrinter(getPrinterList(), protocol, CSID);        
617         if (pPrinter)
618         {
619             pPrinter->setMessageLogger(getCurrentErrorLogI()->getOutputLogger());
620             switch (protocol)
621             {
622             case  OCSD_PROTOCOL_ETMV4I:
623             {
624                 PacketPrinter<EtmV4ITrcPacket> *pTPrinter = dynamic_cast<PacketPrinter<EtmV4ITrcPacket> *>(pPrinter);
625                 if (bMonitor)
626                     err = pElement->getDecoderMngr()->attachPktMonitor(pElement->getDecoderHandle(), (IPktRawDataMon<EtmV4ITrcPacket> *)pTPrinter);
627                 else
628                     err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), (IPktDataIn<EtmV4ITrcPacket> *)pTPrinter);
629             }
630             break;
631
632             case  OCSD_PROTOCOL_ETMV3:
633             {
634                 PacketPrinter<EtmV3TrcPacket> *pTPrinter = dynamic_cast<PacketPrinter<EtmV3TrcPacket> *>(pPrinter);
635                 if (bMonitor)
636                     err = pElement->getDecoderMngr()->attachPktMonitor(pElement->getDecoderHandle(), (IPktRawDataMon<EtmV3TrcPacket> *)pTPrinter);
637                 else
638                     err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), (IPktDataIn<EtmV3TrcPacket> *)pTPrinter);
639             }
640             break;
641
642             case  OCSD_PROTOCOL_PTM:
643             {
644                 PacketPrinter<PtmTrcPacket> *pTPrinter = dynamic_cast<PacketPrinter<PtmTrcPacket> *>(pPrinter);
645                 if (bMonitor)
646                     err = pElement->getDecoderMngr()->attachPktMonitor(pElement->getDecoderHandle(), (IPktRawDataMon<PtmTrcPacket> *)pTPrinter);
647                 else
648                     err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), (IPktDataIn<PtmTrcPacket> *)pTPrinter);
649             }
650             break;
651
652             case OCSD_PROTOCOL_STM:
653             {
654                 PacketPrinter<StmTrcPacket> *pTPrinter = dynamic_cast<PacketPrinter<StmTrcPacket> *>(pPrinter);
655                 if (bMonitor)
656                     err = pElement->getDecoderMngr()->attachPktMonitor(pElement->getDecoderHandle(), (IPktRawDataMon<StmTrcPacket> *)pTPrinter);
657                 else
658                     err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), (IPktDataIn<StmTrcPacket> *)pTPrinter);
659             }
660             break;
661
662             default:
663                 err = OCSD_ERR_NO_PROTOCOL;
664                 break;
665             }
666
667             if (err == OCSD_OK)
668             {
669                 if (ppPrinter)
670                     *ppPrinter = pPrinter;
671             }
672             else
673                 PktPrinterFact::destroyPrinter(getPrinterList(), pPrinter);
674         }
675     }
676     return err;
677 }
678
679 /** add a raw frame printer */
680 ocsd_err_t DecodeTree::addRawFramePrinter(RawFramePrinter **ppPrinter, uint32_t flags)
681 {
682     ocsd_err_t err = OCSD_ERR_MEM;
683     RawFramePrinter *pPrinter = PktPrinterFact::createRawFramePrinter(getPrinterList());
684     if (pPrinter)
685     {
686         pPrinter->setMessageLogger((DecodeTree::getCurrentErrorLogI()->getOutputLogger()));
687         TraceFormatterFrameDecoder *pFrameDecoder = getFrameDeformatter();
688         uint32_t cfgFlags = pFrameDecoder->getConfigFlags();
689         cfgFlags |= ((uint32_t)flags & (OCSD_DFRMTR_PACKED_RAW_OUT | OCSD_DFRMTR_UNPACKED_RAW_OUT));
690         pFrameDecoder->Configure(cfgFlags);
691         err = pFrameDecoder->getTrcRawFrameAttachPt()->attach(pPrinter);        
692         if (ppPrinter && (err==OCSD_OK))
693             *ppPrinter = pPrinter;
694     }
695     return err;
696 }
697
698 /** add a generic element output printer */
699 ocsd_err_t DecodeTree::addGenElemPrinter(TrcGenericElementPrinter **ppPrinter)
700 {
701     ocsd_err_t err = OCSD_ERR_MEM;
702     TrcGenericElementPrinter *pPrinter = PktPrinterFact::createGenElemPrinter(getPrinterList());
703     if (pPrinter)
704     {
705         pPrinter->setMessageLogger((DecodeTree::getCurrentErrorLogI()->getOutputLogger()));
706         setGenTraceElemOutI(pPrinter);
707         err = OCSD_OK;
708         if (ppPrinter)
709             *ppPrinter = pPrinter;
710     }
711     return err;
712
713 }
714
715 /* End of File ocsd_dcd_tree.cpp */