1 /* 2 * \file ocsd_c_api.cpp 3 * \brief OpenCSD : "C" API libary implementation. 4 * 5 * \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved. 6 */ 7 8 /* 9 * Redistribution and use in source and binary forms, with or without modification, 10 * are permitted provided that the following conditions are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the copyright holder nor the names of its contributors 20 * may be used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include <cstring> 36 37 /* pull in the C++ decode library */ 38 #include "opencsd.h" 39 40 /* C-API and wrapper objects */ 41 #include "opencsd/c_api/opencsd_c_api.h" 42 #include "ocsd_c_api_obj.h" 43 44 /** MSVC2010 unwanted export workaround */ 45 #ifdef WIN32 46 #if (_MSC_VER == 1600) 47 #include <new> 48 namespace std { const nothrow_t nothrow = nothrow_t(); } 49 #endif 50 #endif 51 52 /*******************************************************************************/ 53 /* C API internal helper function declarations */ 54 /*******************************************************************************/ 55 56 static ocsd_err_t ocsd_create_pkt_sink_cb(ocsd_trace_protocol_t protocol, FnDefPktDataIn pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj ); 57 static ocsd_err_t ocsd_create_pkt_mon_cb(ocsd_trace_protocol_t protocol, FnDefPktDataMon pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj ); 58 static ocsd_err_t ocsd_check_and_add_mem_acc_mapper(const dcd_tree_handle_t handle, DecodeTree **ppDT); 59 60 /*******************************************************************************/ 61 /* C library data - additional data on top of the C++ library objects */ 62 /*******************************************************************************/ 63 64 /* keep a list of interface objects for a decode tree for later disposal */ 65 typedef struct _lib_dt_data_list { 66 std::vector<ITrcTypedBase *> cb_objs; 67 DefLogStrCBObj s_def_log_str_cb; 68 } lib_dt_data_list; 69 70 /* map lists to handles */ 71 static std::map<dcd_tree_handle_t, lib_dt_data_list *> s_data_map; 72 73 /*******************************************************************************/ 74 /* C API functions */ 75 /*******************************************************************************/ 76 77 /** Get Library version. Return a 32 bit version in form MMMMnnpp - MMMM = major version, nn = minor version, pp = patch version */ 78 OCSD_C_API uint32_t ocsd_get_version(void) 79 { 80 return ocsdVersion::vers_num(); 81 } 82 83 /** Get library version string */ 84 OCSD_C_API const char * ocsd_get_version_str(void) 85 { 86 return ocsdVersion::vers_str(); 87 } 88 89 90 /*** Decode tree creation etc. */ 91 92 OCSD_C_API dcd_tree_handle_t ocsd_create_dcd_tree(const ocsd_dcd_tree_src_t src_type, const uint32_t deformatterCfgFlags) 93 { 94 dcd_tree_handle_t handle = C_API_INVALID_TREE_HANDLE; 95 handle = (dcd_tree_handle_t)DecodeTree::CreateDecodeTree(src_type,deformatterCfgFlags); 96 if(handle != C_API_INVALID_TREE_HANDLE) 97 { 98 lib_dt_data_list *pList = new (std::nothrow) lib_dt_data_list; 99 if(pList != 0) 100 { 101 s_data_map.insert(std::pair<dcd_tree_handle_t, lib_dt_data_list *>(handle,pList)); 102 } 103 else 104 { 105 ocsd_destroy_dcd_tree(handle); 106 handle = C_API_INVALID_TREE_HANDLE; 107 } 108 } 109 return handle; 110 } 111 112 OCSD_C_API void ocsd_destroy_dcd_tree(const dcd_tree_handle_t handle) 113 { 114 if(handle != C_API_INVALID_TREE_HANDLE) 115 { 116 GenTraceElemCBObj * pIf = (GenTraceElemCBObj *)(((DecodeTree *)handle)->getGenTraceElemOutI()); 117 if(pIf != 0) 118 delete pIf; 119 120 /* need to clear any associated callback data. */ 121 std::map<dcd_tree_handle_t, lib_dt_data_list *>::iterator it; 122 it = s_data_map.find(handle); 123 if(it != s_data_map.end()) 124 { 125 std::vector<ITrcTypedBase *>::iterator itcb; 126 itcb = it->second->cb_objs.begin(); 127 while(itcb != it->second->cb_objs.end()) 128 { 129 delete *itcb; 130 itcb++; 131 } 132 it->second->cb_objs.clear(); 133 delete it->second; 134 s_data_map.erase(it); 135 } 136 DecodeTree::DestroyDecodeTree((DecodeTree *)handle); 137 } 138 } 139 140 /*** Decode tree process data */ 141 142 OCSD_C_API ocsd_datapath_resp_t ocsd_dt_process_data(const dcd_tree_handle_t handle, 143 const ocsd_datapath_op_t op, 144 const ocsd_trc_index_t index, 145 const uint32_t dataBlockSize, 146 const uint8_t *pDataBlock, 147 uint32_t *numBytesProcessed) 148 { 149 ocsd_datapath_resp_t resp = OCSD_RESP_FATAL_NOT_INIT; 150 if(handle != C_API_INVALID_TREE_HANDLE) 151 resp = ((DecodeTree *)handle)->TraceDataIn(op,index,dataBlockSize,pDataBlock,numBytesProcessed); 152 return resp; 153 } 154 155 /*** Decode tree - decoder management */ 156 157 OCSD_C_API ocsd_err_t ocsd_dt_create_decoder(const dcd_tree_handle_t handle, 158 const char *decoder_name, 159 const int create_flags, 160 const void *decoder_cfg, 161 unsigned char *pCSID 162 ) 163 { 164 ocsd_err_t err = OCSD_OK; 165 DecodeTree *dt = (DecodeTree *)handle; 166 std::string dName = decoder_name; 167 IDecoderMngr *pDcdMngr; 168 err = OcsdLibDcdRegister::getDecoderRegister()->getDecoderMngrByName(dName,&pDcdMngr); 169 if(err != OCSD_OK) 170 return err; 171 172 CSConfig *pConfig = 0; 173 err = pDcdMngr->createConfigFromDataStruct(&pConfig,decoder_cfg); 174 if(err != OCSD_OK) 175 return err; 176 177 err = dt->createDecoder(dName,create_flags,pConfig); 178 if(err == OCSD_OK) 179 *pCSID = pConfig->getTraceID(); 180 delete pConfig; 181 return err; 182 } 183 184 OCSD_C_API ocsd_err_t ocsd_dt_remove_decoder( const dcd_tree_handle_t handle, 185 const unsigned char CSID) 186 { 187 return ((DecodeTree *)handle)->removeDecoder(CSID); 188 } 189 190 OCSD_C_API ocsd_err_t ocsd_dt_attach_packet_callback( const dcd_tree_handle_t handle, 191 const unsigned char CSID, 192 const ocsd_c_api_cb_types callback_type, 193 void *p_fn_callback_data, 194 const void *p_context) 195 { 196 ocsd_err_t err = OCSD_OK; 197 DecodeTree *pDT = static_cast<DecodeTree *>(handle); 198 DecodeTreeElement *pElem = pDT->getDecoderElement(CSID); 199 if(pElem == 0) 200 return OCSD_ERR_INVALID_ID; // cannot find entry for that CSID 201 202 ITrcTypedBase *pDataInSink = 0; // pointer to a sink callback object 203 switch(callback_type) 204 { 205 case OCSD_C_API_CB_PKT_SINK: 206 err = ocsd_create_pkt_sink_cb(pElem->getProtocol(),(FnDefPktDataIn)p_fn_callback_data,p_context,&pDataInSink); 207 if(err == OCSD_OK) 208 err = pElem->getDecoderMngr()->attachPktSink(pElem->getDecoderHandle(), pDataInSink); 209 break; 210 211 case OCSD_C_API_CB_PKT_MON: 212 err = ocsd_create_pkt_mon_cb(pElem->getProtocol(),(FnDefPktDataMon)p_fn_callback_data,p_context,&pDataInSink); 213 if (err == OCSD_OK) 214 err = pElem->getDecoderMngr()->attachPktMonitor(pElem->getDecoderHandle(), pDataInSink); 215 break; 216 217 default: 218 err = OCSD_ERR_INVALID_PARAM_VAL; 219 } 220 221 if(err == OCSD_OK) 222 { 223 if (err == OCSD_OK) 224 { 225 // save object pointer for destruction later. 226 std::map<dcd_tree_handle_t, lib_dt_data_list *>::iterator it; 227 it = s_data_map.find(handle); 228 if (it != s_data_map.end()) 229 it->second->cb_objs.push_back(pDataInSink); 230 } 231 else 232 delete pDataInSink; 233 } 234 return err; 235 } 236 237 OCSD_C_API ocsd_err_t ocsd_dt_get_decode_stats(const dcd_tree_handle_t handle, 238 const unsigned char CSID, 239 ocsd_decode_stats_t **p_stats_block) 240 { 241 DecodeTree *pDT = static_cast<DecodeTree *>(handle); 242 243 return pDT->getDecoderStats(CSID, p_stats_block); 244 } 245 246 OCSD_C_API ocsd_err_t ocsd_dt_reset_decode_stats(const dcd_tree_handle_t handle, 247 const unsigned char CSID) 248 { 249 DecodeTree *pDT = static_cast<DecodeTree *>(handle); 250 251 return pDT->resetDecoderStats(CSID); 252 } 253 254 /*** Decode tree set element output */ 255 OCSD_C_API ocsd_err_t ocsd_dt_set_gen_elem_outfn(const dcd_tree_handle_t handle, FnTraceElemIn pFn, const void *p_context) 256 { 257 258 GenTraceElemCBObj * pCBObj = new (std::nothrow)GenTraceElemCBObj(pFn, p_context); 259 if(pCBObj) 260 { 261 ((DecodeTree *)handle)->setGenTraceElemOutI(pCBObj); 262 return OCSD_OK; 263 } 264 return OCSD_ERR_MEM; 265 } 266 267 268 /*** Default error logging */ 269 270 OCSD_C_API ocsd_err_t ocsd_def_errlog_init(const ocsd_err_severity_t verbosity, const int create_output_logger) 271 { 272 if(DecodeTree::getDefaultErrorLogger()->initErrorLogger(verbosity,(bool)(create_output_logger != 0))) 273 return OCSD_OK; 274 return OCSD_ERR_NOT_INIT; 275 } 276 277 OCSD_C_API ocsd_err_t ocsd_def_errlog_config_output(const int output_flags, const char *log_file_name) 278 { 279 ocsdMsgLogger *pLogger = DecodeTree::getDefaultErrorLogger()->getOutputLogger(); 280 if(pLogger) 281 { 282 pLogger->setLogOpts(output_flags & C_API_MSGLOGOUT_MASK); 283 if(log_file_name != NULL) 284 { 285 pLogger->setLogFileName(log_file_name); 286 } 287 return OCSD_OK; 288 } 289 return OCSD_ERR_NOT_INIT; 290 } 291 292 293 OCSD_C_API ocsd_err_t ocsd_def_errlog_set_strprint_cb(const dcd_tree_handle_t handle, void *p_context, FnDefLoggerPrintStrCB p_str_print_cb) 294 { 295 ocsdMsgLogger *pLogger = DecodeTree::getDefaultErrorLogger()->getOutputLogger(); 296 if (pLogger) 297 { 298 std::map<dcd_tree_handle_t, lib_dt_data_list *>::iterator it; 299 it = s_data_map.find(handle); 300 if (it != s_data_map.end()) 301 { 302 DefLogStrCBObj *pCBObj = &(it->second->s_def_log_str_cb); 303 pCBObj->setCBFn(p_context, p_str_print_cb); 304 pLogger->setStrOutFn(pCBObj); 305 int logOpts = pLogger->getLogOpts(); 306 logOpts |= (int)(ocsdMsgLogger::OUT_STR_CB); 307 pLogger->setLogOpts(logOpts); 308 return OCSD_OK; 309 } 310 } 311 return OCSD_ERR_NOT_INIT; 312 } 313 314 OCSD_C_API void ocsd_def_errlog_msgout(const char *msg) 315 { 316 ocsdMsgLogger *pLogger = DecodeTree::getDefaultErrorLogger()->getOutputLogger(); 317 if(pLogger) 318 pLogger->LogMsg(msg); 319 } 320 321 /*** Convert packet to string */ 322 323 OCSD_C_API ocsd_err_t ocsd_pkt_str(const ocsd_trace_protocol_t pkt_protocol, const void *p_pkt, char *buffer, const int buffer_size) 324 { 325 ocsd_err_t err = OCSD_OK; 326 if((buffer == NULL) || (buffer_size < 2)) 327 return OCSD_ERR_INVALID_PARAM_VAL; 328 329 std::string pktStr = ""; 330 buffer[0] = 0; 331 332 switch(pkt_protocol) 333 { 334 case OCSD_PROTOCOL_ETMV4I: 335 trcPrintElemToString<EtmV4ITrcPacket,ocsd_etmv4_i_pkt>(p_pkt, pktStr); 336 break; 337 338 case OCSD_PROTOCOL_ETMV3: 339 trcPrintElemToString<EtmV3TrcPacket,ocsd_etmv3_pkt>(p_pkt, pktStr); 340 break; 341 342 case OCSD_PROTOCOL_STM: 343 trcPrintElemToString<StmTrcPacket,ocsd_stm_pkt>(p_pkt, pktStr); 344 break; 345 346 case OCSD_PROTOCOL_PTM: 347 trcPrintElemToString<PtmTrcPacket,ocsd_ptm_pkt>(p_pkt, pktStr); 348 break; 349 350 default: 351 if (OCSD_PROTOCOL_IS_CUSTOM(pkt_protocol)) 352 err = ocsd_cust_protocol_to_str(pkt_protocol, p_pkt, buffer, buffer_size); 353 else 354 err = OCSD_ERR_NO_PROTOCOL; 355 break; 356 } 357 358 if(pktStr.size() > 0) 359 { 360 strncpy(buffer,pktStr.c_str(),buffer_size-1); 361 buffer[buffer_size-1] = 0; 362 } 363 return err; 364 } 365 366 OCSD_C_API ocsd_err_t ocsd_gen_elem_str(const ocsd_generic_trace_elem *p_pkt, char *buffer, const int buffer_size) 367 { 368 ocsd_err_t err = OCSD_OK; 369 if((buffer == NULL) || (buffer_size < 2)) 370 return OCSD_ERR_INVALID_PARAM_VAL; 371 std::string str; 372 trcPrintElemToString<OcsdTraceElement,ocsd_generic_trace_elem>(p_pkt,str); 373 if(str.size() > 0) 374 { 375 strncpy(buffer,str.c_str(),buffer_size -1); 376 buffer[buffer_size-1] = 0; 377 } 378 return err; 379 } 380 381 /*** Decode tree -- memory accessor control */ 382 383 OCSD_C_API ocsd_err_t ocsd_dt_add_binfile_mem_acc(const dcd_tree_handle_t handle, const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const char *filepath) 384 { 385 ocsd_err_t err = OCSD_OK; 386 DecodeTree *pDT; 387 err = ocsd_check_and_add_mem_acc_mapper(handle,&pDT); 388 if(err == OCSD_OK) 389 err = pDT->addBinFileMemAcc(address,mem_space,filepath); 390 return err; 391 } 392 393 OCSD_C_API ocsd_err_t ocsd_dt_add_binfile_region_mem_acc(const dcd_tree_handle_t handle, const ocsd_file_mem_region_t *region_array, const int num_regions, const ocsd_mem_space_acc_t mem_space, const char *filepath) 394 { 395 ocsd_err_t err = OCSD_OK; 396 DecodeTree *pDT; 397 err = ocsd_check_and_add_mem_acc_mapper(handle,&pDT); 398 if(err == OCSD_OK) 399 err = pDT->addBinFileRegionMemAcc(region_array,num_regions,mem_space,filepath); 400 return err; 401 } 402 403 OCSD_C_API ocsd_err_t ocsd_dt_add_buffer_mem_acc(const dcd_tree_handle_t handle, const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const uint8_t *p_mem_buffer, const uint32_t mem_length) 404 { 405 ocsd_err_t err = OCSD_OK; 406 DecodeTree *pDT; 407 err = ocsd_check_and_add_mem_acc_mapper(handle,&pDT); 408 if(err == OCSD_OK) 409 err = pDT->addBufferMemAcc(address,mem_space,p_mem_buffer,mem_length); 410 return err; 411 } 412 413 OCSD_C_API ocsd_err_t ocsd_dt_add_callback_mem_acc(const dcd_tree_handle_t handle, 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) 414 { 415 ocsd_err_t err = OCSD_OK; 416 DecodeTree *pDT; 417 err = ocsd_check_and_add_mem_acc_mapper(handle,&pDT); 418 if(err == OCSD_OK) 419 err = pDT->addCallbackMemAcc(st_address,en_address,mem_space,p_cb_func,p_context); 420 return err; 421 } 422 423 OCSD_C_API ocsd_err_t ocsd_dt_add_callback_trcid_mem_acc(const dcd_tree_handle_t handle, 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) 424 { 425 ocsd_err_t err = OCSD_OK; 426 DecodeTree *pDT; 427 err = ocsd_check_and_add_mem_acc_mapper(handle, &pDT); 428 if (err == OCSD_OK) 429 err = pDT->addCallbackIDMemAcc(st_address, en_address, mem_space, p_cb_func, p_context); 430 return err; 431 } 432 433 434 OCSD_C_API ocsd_err_t ocsd_dt_remove_mem_acc(const dcd_tree_handle_t handle, const ocsd_vaddr_t st_address, const ocsd_mem_space_acc_t mem_space) 435 { 436 ocsd_err_t err = OCSD_OK; 437 438 if(handle != C_API_INVALID_TREE_HANDLE) 439 { 440 DecodeTree *pDT = static_cast<DecodeTree *>(handle); 441 err = pDT->removeMemAccByAddress(st_address,mem_space); 442 } 443 else 444 err = OCSD_ERR_INVALID_PARAM_VAL; 445 return err; 446 } 447 448 OCSD_C_API void ocsd_tl_log_mapped_mem_ranges(const dcd_tree_handle_t handle) 449 { 450 if(handle != C_API_INVALID_TREE_HANDLE) 451 { 452 DecodeTree *pDT = static_cast<DecodeTree *>(handle); 453 pDT->logMappedRanges(); 454 } 455 } 456 457 OCSD_C_API void ocsd_gen_elem_init(ocsd_generic_trace_elem *p_pkt, const ocsd_gen_trc_elem_t elem_type) 458 { 459 p_pkt->elem_type = elem_type; 460 p_pkt->flag_bits = 0; 461 p_pkt->ptr_extended_data = 0; 462 } 463 464 OCSD_C_API ocsd_err_t ocsd_dt_set_raw_frame_printer(const dcd_tree_handle_t handle, int flags) 465 { 466 if (handle != C_API_INVALID_TREE_HANDLE) 467 return ((DecodeTree *)handle)->addRawFramePrinter(0, (uint32_t)flags); 468 return OCSD_ERR_NOT_INIT; 469 } 470 471 OCSD_C_API ocsd_err_t ocsd_dt_set_gen_elem_printer(const dcd_tree_handle_t handle) 472 { 473 if (handle != C_API_INVALID_TREE_HANDLE) 474 return ((DecodeTree *)handle)->addGenElemPrinter(0); 475 return OCSD_ERR_NOT_INIT; 476 } 477 478 OCSD_C_API ocsd_err_t ocsd_dt_set_pkt_protocol_printer(const dcd_tree_handle_t handle, uint8_t cs_id, int monitor) 479 { 480 ocsd_err_t err = OCSD_ERR_NOT_INIT; 481 if (handle != C_API_INVALID_TREE_HANDLE) 482 { 483 DecodeTree *p_tree = (DecodeTree *)handle; 484 err = p_tree->addPacketPrinter(cs_id, (bool)(monitor != 0), 0); 485 } 486 return err; 487 } 488 489 OCSD_C_API void ocsd_err_str(const ocsd_err_t err, char *buffer, const int buffer_size) 490 { 491 std::string err_str; 492 err_str = ocsdError::getErrorString(ocsdError(OCSD_ERR_SEV_ERROR, err)); 493 strncpy(buffer, err_str.c_str(), buffer_size - 1); 494 buffer[buffer_size - 1] = 0; 495 } 496 497 OCSD_C_API ocsd_err_t ocsd_get_last_err(ocsd_trc_index_t *index, uint8_t *chan_id, char *message, const int message_len) 498 { 499 ocsdError *p_err; 500 ocsd_err_t err = OCSD_OK; 501 std::string err_str; 502 503 p_err = DecodeTree::getDefaultErrorLogger()->GetLastError(); 504 if (p_err) 505 { 506 *index = p_err->getErrorIndex(); 507 *chan_id = p_err->getErrorChanID(); 508 err_str = p_err->getErrorString(ocsdError(p_err)); 509 strncpy(message, err_str.c_str(), message_len - 1); 510 message[message_len - 1] = 0; 511 err = p_err->getErrorCode(); 512 } 513 else 514 { 515 message[0] = 0; 516 *index = OCSD_BAD_TRC_INDEX; 517 *chan_id = OCSD_BAD_CS_SRC_ID; 518 } 519 return err; 520 } 521 522 /*******************************************************************************/ 523 /* C API local fns */ 524 /*******************************************************************************/ 525 static ocsd_err_t ocsd_create_pkt_sink_cb(ocsd_trace_protocol_t protocol, FnDefPktDataIn pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj ) 526 { 527 ocsd_err_t err = OCSD_OK; 528 *ppCBObj = 0; 529 530 switch(protocol) 531 { 532 case OCSD_PROTOCOL_ETMV4I: 533 *ppCBObj = new (std::nothrow) PktCBObj<EtmV4ITrcPacket>(pPktInFn,p_context); 534 break; 535 536 case OCSD_PROTOCOL_ETMV3: 537 *ppCBObj = new (std::nothrow) PktCBObj<EtmV3TrcPacket>(pPktInFn,p_context); 538 break; 539 540 case OCSD_PROTOCOL_PTM: 541 *ppCBObj = new (std::nothrow) PktCBObj<PtmTrcPacket>(pPktInFn,p_context); 542 break; 543 544 case OCSD_PROTOCOL_STM: 545 *ppCBObj = new (std::nothrow) PktCBObj<StmTrcPacket>(pPktInFn,p_context); 546 break; 547 548 default: 549 if ((protocol >= OCSD_PROTOCOL_CUSTOM_0) && (protocol < OCSD_PROTOCOL_END)) 550 { 551 *ppCBObj = new (std::nothrow) PktCBObj<void>(pPktInFn, p_context); 552 } 553 else 554 err = OCSD_ERR_NO_PROTOCOL; 555 break; 556 } 557 558 if((*ppCBObj == 0) && (err == OCSD_OK)) 559 err = OCSD_ERR_MEM; 560 561 return err; 562 } 563 564 static ocsd_err_t ocsd_create_pkt_mon_cb(ocsd_trace_protocol_t protocol, FnDefPktDataMon pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj ) 565 { 566 ocsd_err_t err = OCSD_OK; 567 *ppCBObj = 0; 568 569 switch(protocol) 570 { 571 case OCSD_PROTOCOL_ETMV4I: 572 *ppCBObj = new (std::nothrow) PktMonCBObj<EtmV4ITrcPacket>(pPktInFn,p_context); 573 break; 574 575 case OCSD_PROTOCOL_ETMV3: 576 *ppCBObj = new (std::nothrow) PktMonCBObj<EtmV3TrcPacket>(pPktInFn,p_context); 577 break; 578 579 case OCSD_PROTOCOL_PTM: 580 *ppCBObj = new (std::nothrow) PktMonCBObj<PtmTrcPacket>(pPktInFn,p_context); 581 break; 582 583 case OCSD_PROTOCOL_STM: 584 *ppCBObj = new (std::nothrow) PktMonCBObj<StmTrcPacket>(pPktInFn,p_context); 585 break; 586 587 default: 588 if ((protocol >= OCSD_PROTOCOL_CUSTOM_0) && (protocol < OCSD_PROTOCOL_END)) 589 { 590 *ppCBObj = new (std::nothrow) PktMonCBObj<void>(pPktInFn, p_context); 591 } 592 else 593 err = OCSD_ERR_NO_PROTOCOL; 594 break; 595 } 596 597 if((*ppCBObj == 0) && (err == OCSD_OK)) 598 err = OCSD_ERR_MEM; 599 600 return err; 601 } 602 603 static ocsd_err_t ocsd_check_and_add_mem_acc_mapper(const dcd_tree_handle_t handle, DecodeTree **ppDT) 604 { 605 *ppDT = 0; 606 if(handle == C_API_INVALID_TREE_HANDLE) 607 return OCSD_ERR_INVALID_PARAM_VAL; 608 *ppDT = static_cast<DecodeTree *>(handle); 609 if(!(*ppDT)->hasMemAccMapper()) 610 return (*ppDT)->createMemAccMapper(); 611 return OCSD_OK; 612 } 613 614 /*******************************************************************************/ 615 /* C API Helper objects */ 616 /*******************************************************************************/ 617 618 /****************** Generic trace element output callback function ************/ 619 GenTraceElemCBObj::GenTraceElemCBObj(FnTraceElemIn pCBFn, const void *p_context) : 620 m_c_api_cb_fn(pCBFn), 621 m_p_cb_context(p_context) 622 { 623 } 624 625 ocsd_datapath_resp_t GenTraceElemCBObj::TraceElemIn(const ocsd_trc_index_t index_sop, 626 const uint8_t trc_chan_id, 627 const OcsdTraceElement &elem) 628 { 629 return m_c_api_cb_fn(m_p_cb_context, index_sop, trc_chan_id, &elem); 630 } 631 632 /* End of File ocsd_c_api.cpp */ 633