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