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