633 lines
22 KiB
C++
633 lines
22 KiB
C++
/*
|
|
* \file ocsd_c_api.cpp
|
|
* \brief OpenCSD : "C" API libary implementation.
|
|
*
|
|
* \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved.
|
|
*/
|
|
|
|
/*
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
* are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
*
|
|
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software without
|
|
* specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include <cstring>
|
|
|
|
/* pull in the C++ decode library */
|
|
#include "opencsd.h"
|
|
|
|
/* C-API and wrapper objects */
|
|
#include "opencsd/c_api/opencsd_c_api.h"
|
|
#include "ocsd_c_api_obj.h"
|
|
|
|
/** MSVC2010 unwanted export workaround */
|
|
#ifdef WIN32
|
|
#if (_MSC_VER == 1600)
|
|
#include <new>
|
|
namespace std { const nothrow_t nothrow = nothrow_t(); }
|
|
#endif
|
|
#endif
|
|
|
|
/*******************************************************************************/
|
|
/* C API internal helper function declarations */
|
|
/*******************************************************************************/
|
|
|
|
static ocsd_err_t ocsd_create_pkt_sink_cb(ocsd_trace_protocol_t protocol, FnDefPktDataIn pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj );
|
|
static ocsd_err_t ocsd_create_pkt_mon_cb(ocsd_trace_protocol_t protocol, FnDefPktDataMon pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj );
|
|
static ocsd_err_t ocsd_check_and_add_mem_acc_mapper(const dcd_tree_handle_t handle, DecodeTree **ppDT);
|
|
|
|
/*******************************************************************************/
|
|
/* C library data - additional data on top of the C++ library objects */
|
|
/*******************************************************************************/
|
|
|
|
/* keep a list of interface objects for a decode tree for later disposal */
|
|
typedef struct _lib_dt_data_list {
|
|
std::vector<ITrcTypedBase *> cb_objs;
|
|
DefLogStrCBObj s_def_log_str_cb;
|
|
} lib_dt_data_list;
|
|
|
|
/* map lists to handles */
|
|
static std::map<dcd_tree_handle_t, lib_dt_data_list *> s_data_map;
|
|
|
|
/*******************************************************************************/
|
|
/* C API functions */
|
|
/*******************************************************************************/
|
|
|
|
/** Get Library version. Return a 32 bit version in form MMMMnnpp - MMMM = major version, nn = minor version, pp = patch version */
|
|
OCSD_C_API uint32_t ocsd_get_version(void)
|
|
{
|
|
return ocsdVersion::vers_num();
|
|
}
|
|
|
|
/** Get library version string */
|
|
OCSD_C_API const char * ocsd_get_version_str(void)
|
|
{
|
|
return ocsdVersion::vers_str();
|
|
}
|
|
|
|
|
|
/*** Decode tree creation etc. */
|
|
|
|
OCSD_C_API dcd_tree_handle_t ocsd_create_dcd_tree(const ocsd_dcd_tree_src_t src_type, const uint32_t deformatterCfgFlags)
|
|
{
|
|
dcd_tree_handle_t handle = C_API_INVALID_TREE_HANDLE;
|
|
handle = (dcd_tree_handle_t)DecodeTree::CreateDecodeTree(src_type,deformatterCfgFlags);
|
|
if(handle != C_API_INVALID_TREE_HANDLE)
|
|
{
|
|
lib_dt_data_list *pList = new (std::nothrow) lib_dt_data_list;
|
|
if(pList != 0)
|
|
{
|
|
s_data_map.insert(std::pair<dcd_tree_handle_t, lib_dt_data_list *>(handle,pList));
|
|
}
|
|
else
|
|
{
|
|
ocsd_destroy_dcd_tree(handle);
|
|
handle = C_API_INVALID_TREE_HANDLE;
|
|
}
|
|
}
|
|
return handle;
|
|
}
|
|
|
|
OCSD_C_API void ocsd_destroy_dcd_tree(const dcd_tree_handle_t handle)
|
|
{
|
|
if(handle != C_API_INVALID_TREE_HANDLE)
|
|
{
|
|
GenTraceElemCBObj * pIf = (GenTraceElemCBObj *)(((DecodeTree *)handle)->getGenTraceElemOutI());
|
|
if(pIf != 0)
|
|
delete pIf;
|
|
|
|
/* need to clear any associated callback data. */
|
|
std::map<dcd_tree_handle_t, lib_dt_data_list *>::iterator it;
|
|
it = s_data_map.find(handle);
|
|
if(it != s_data_map.end())
|
|
{
|
|
std::vector<ITrcTypedBase *>::iterator itcb;
|
|
itcb = it->second->cb_objs.begin();
|
|
while(itcb != it->second->cb_objs.end())
|
|
{
|
|
delete *itcb;
|
|
itcb++;
|
|
}
|
|
it->second->cb_objs.clear();
|
|
delete it->second;
|
|
s_data_map.erase(it);
|
|
}
|
|
DecodeTree::DestroyDecodeTree((DecodeTree *)handle);
|
|
}
|
|
}
|
|
|
|
/*** Decode tree process data */
|
|
|
|
OCSD_C_API ocsd_datapath_resp_t ocsd_dt_process_data(const dcd_tree_handle_t handle,
|
|
const ocsd_datapath_op_t op,
|
|
const ocsd_trc_index_t index,
|
|
const uint32_t dataBlockSize,
|
|
const uint8_t *pDataBlock,
|
|
uint32_t *numBytesProcessed)
|
|
{
|
|
ocsd_datapath_resp_t resp = OCSD_RESP_FATAL_NOT_INIT;
|
|
if(handle != C_API_INVALID_TREE_HANDLE)
|
|
resp = ((DecodeTree *)handle)->TraceDataIn(op,index,dataBlockSize,pDataBlock,numBytesProcessed);
|
|
return resp;
|
|
}
|
|
|
|
/*** Decode tree - decoder management */
|
|
|
|
OCSD_C_API ocsd_err_t ocsd_dt_create_decoder(const dcd_tree_handle_t handle,
|
|
const char *decoder_name,
|
|
const int create_flags,
|
|
const void *decoder_cfg,
|
|
unsigned char *pCSID
|
|
)
|
|
{
|
|
ocsd_err_t err = OCSD_OK;
|
|
DecodeTree *dt = (DecodeTree *)handle;
|
|
std::string dName = decoder_name;
|
|
IDecoderMngr *pDcdMngr;
|
|
err = OcsdLibDcdRegister::getDecoderRegister()->getDecoderMngrByName(dName,&pDcdMngr);
|
|
if(err != OCSD_OK)
|
|
return err;
|
|
|
|
CSConfig *pConfig = 0;
|
|
err = pDcdMngr->createConfigFromDataStruct(&pConfig,decoder_cfg);
|
|
if(err != OCSD_OK)
|
|
return err;
|
|
|
|
err = dt->createDecoder(dName,create_flags,pConfig);
|
|
if(err == OCSD_OK)
|
|
*pCSID = pConfig->getTraceID();
|
|
delete pConfig;
|
|
return err;
|
|
}
|
|
|
|
OCSD_C_API ocsd_err_t ocsd_dt_remove_decoder( const dcd_tree_handle_t handle,
|
|
const unsigned char CSID)
|
|
{
|
|
return ((DecodeTree *)handle)->removeDecoder(CSID);
|
|
}
|
|
|
|
OCSD_C_API ocsd_err_t ocsd_dt_attach_packet_callback( const dcd_tree_handle_t handle,
|
|
const unsigned char CSID,
|
|
const ocsd_c_api_cb_types callback_type,
|
|
void *p_fn_callback_data,
|
|
const void *p_context)
|
|
{
|
|
ocsd_err_t err = OCSD_OK;
|
|
DecodeTree *pDT = static_cast<DecodeTree *>(handle);
|
|
DecodeTreeElement *pElem = pDT->getDecoderElement(CSID);
|
|
if(pElem == 0)
|
|
return OCSD_ERR_INVALID_ID; // cannot find entry for that CSID
|
|
|
|
ITrcTypedBase *pDataInSink = 0; // pointer to a sink callback object
|
|
switch(callback_type)
|
|
{
|
|
case OCSD_C_API_CB_PKT_SINK:
|
|
err = ocsd_create_pkt_sink_cb(pElem->getProtocol(),(FnDefPktDataIn)p_fn_callback_data,p_context,&pDataInSink);
|
|
if(err == OCSD_OK)
|
|
err = pElem->getDecoderMngr()->attachPktSink(pElem->getDecoderHandle(), pDataInSink);
|
|
break;
|
|
|
|
case OCSD_C_API_CB_PKT_MON:
|
|
err = ocsd_create_pkt_mon_cb(pElem->getProtocol(),(FnDefPktDataMon)p_fn_callback_data,p_context,&pDataInSink);
|
|
if (err == OCSD_OK)
|
|
err = pElem->getDecoderMngr()->attachPktMonitor(pElem->getDecoderHandle(), pDataInSink);
|
|
break;
|
|
|
|
default:
|
|
err = OCSD_ERR_INVALID_PARAM_VAL;
|
|
}
|
|
|
|
if(err == OCSD_OK)
|
|
{
|
|
if (err == OCSD_OK)
|
|
{
|
|
// save object pointer for destruction later.
|
|
std::map<dcd_tree_handle_t, lib_dt_data_list *>::iterator it;
|
|
it = s_data_map.find(handle);
|
|
if (it != s_data_map.end())
|
|
it->second->cb_objs.push_back(pDataInSink);
|
|
}
|
|
else
|
|
delete pDataInSink;
|
|
}
|
|
return err;
|
|
}
|
|
|
|
OCSD_C_API ocsd_err_t ocsd_dt_get_decode_stats(const dcd_tree_handle_t handle,
|
|
const unsigned char CSID,
|
|
ocsd_decode_stats_t **p_stats_block)
|
|
{
|
|
DecodeTree *pDT = static_cast<DecodeTree *>(handle);
|
|
|
|
return pDT->getDecoderStats(CSID, p_stats_block);
|
|
}
|
|
|
|
OCSD_C_API ocsd_err_t ocsd_dt_reset_decode_stats(const dcd_tree_handle_t handle,
|
|
const unsigned char CSID)
|
|
{
|
|
DecodeTree *pDT = static_cast<DecodeTree *>(handle);
|
|
|
|
return pDT->resetDecoderStats(CSID);
|
|
}
|
|
|
|
/*** Decode tree set element output */
|
|
OCSD_C_API ocsd_err_t ocsd_dt_set_gen_elem_outfn(const dcd_tree_handle_t handle, FnTraceElemIn pFn, const void *p_context)
|
|
{
|
|
|
|
GenTraceElemCBObj * pCBObj = new (std::nothrow)GenTraceElemCBObj(pFn, p_context);
|
|
if(pCBObj)
|
|
{
|
|
((DecodeTree *)handle)->setGenTraceElemOutI(pCBObj);
|
|
return OCSD_OK;
|
|
}
|
|
return OCSD_ERR_MEM;
|
|
}
|
|
|
|
|
|
/*** Default error logging */
|
|
|
|
OCSD_C_API ocsd_err_t ocsd_def_errlog_init(const ocsd_err_severity_t verbosity, const int create_output_logger)
|
|
{
|
|
if(DecodeTree::getDefaultErrorLogger()->initErrorLogger(verbosity,(bool)(create_output_logger != 0)))
|
|
return OCSD_OK;
|
|
return OCSD_ERR_NOT_INIT;
|
|
}
|
|
|
|
OCSD_C_API ocsd_err_t ocsd_def_errlog_config_output(const int output_flags, const char *log_file_name)
|
|
{
|
|
ocsdMsgLogger *pLogger = DecodeTree::getDefaultErrorLogger()->getOutputLogger();
|
|
if(pLogger)
|
|
{
|
|
pLogger->setLogOpts(output_flags & C_API_MSGLOGOUT_MASK);
|
|
if(log_file_name != NULL)
|
|
{
|
|
pLogger->setLogFileName(log_file_name);
|
|
}
|
|
return OCSD_OK;
|
|
}
|
|
return OCSD_ERR_NOT_INIT;
|
|
}
|
|
|
|
|
|
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)
|
|
{
|
|
ocsdMsgLogger *pLogger = DecodeTree::getDefaultErrorLogger()->getOutputLogger();
|
|
if (pLogger)
|
|
{
|
|
std::map<dcd_tree_handle_t, lib_dt_data_list *>::iterator it;
|
|
it = s_data_map.find(handle);
|
|
if (it != s_data_map.end())
|
|
{
|
|
DefLogStrCBObj *pCBObj = &(it->second->s_def_log_str_cb);
|
|
pCBObj->setCBFn(p_context, p_str_print_cb);
|
|
pLogger->setStrOutFn(pCBObj);
|
|
int logOpts = pLogger->getLogOpts();
|
|
logOpts |= (int)(ocsdMsgLogger::OUT_STR_CB);
|
|
pLogger->setLogOpts(logOpts);
|
|
return OCSD_OK;
|
|
}
|
|
}
|
|
return OCSD_ERR_NOT_INIT;
|
|
}
|
|
|
|
OCSD_C_API void ocsd_def_errlog_msgout(const char *msg)
|
|
{
|
|
ocsdMsgLogger *pLogger = DecodeTree::getDefaultErrorLogger()->getOutputLogger();
|
|
if(pLogger)
|
|
pLogger->LogMsg(msg);
|
|
}
|
|
|
|
/*** Convert packet to string */
|
|
|
|
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)
|
|
{
|
|
ocsd_err_t err = OCSD_OK;
|
|
if((buffer == NULL) || (buffer_size < 2))
|
|
return OCSD_ERR_INVALID_PARAM_VAL;
|
|
|
|
std::string pktStr = "";
|
|
buffer[0] = 0;
|
|
|
|
switch(pkt_protocol)
|
|
{
|
|
case OCSD_PROTOCOL_ETMV4I:
|
|
trcPrintElemToString<EtmV4ITrcPacket,ocsd_etmv4_i_pkt>(p_pkt, pktStr);
|
|
break;
|
|
|
|
case OCSD_PROTOCOL_ETMV3:
|
|
trcPrintElemToString<EtmV3TrcPacket,ocsd_etmv3_pkt>(p_pkt, pktStr);
|
|
break;
|
|
|
|
case OCSD_PROTOCOL_STM:
|
|
trcPrintElemToString<StmTrcPacket,ocsd_stm_pkt>(p_pkt, pktStr);
|
|
break;
|
|
|
|
case OCSD_PROTOCOL_PTM:
|
|
trcPrintElemToString<PtmTrcPacket,ocsd_ptm_pkt>(p_pkt, pktStr);
|
|
break;
|
|
|
|
default:
|
|
if (OCSD_PROTOCOL_IS_CUSTOM(pkt_protocol))
|
|
err = ocsd_cust_protocol_to_str(pkt_protocol, p_pkt, buffer, buffer_size);
|
|
else
|
|
err = OCSD_ERR_NO_PROTOCOL;
|
|
break;
|
|
}
|
|
|
|
if(pktStr.size() > 0)
|
|
{
|
|
strncpy(buffer,pktStr.c_str(),buffer_size-1);
|
|
buffer[buffer_size-1] = 0;
|
|
}
|
|
return err;
|
|
}
|
|
|
|
OCSD_C_API ocsd_err_t ocsd_gen_elem_str(const ocsd_generic_trace_elem *p_pkt, char *buffer, const int buffer_size)
|
|
{
|
|
ocsd_err_t err = OCSD_OK;
|
|
if((buffer == NULL) || (buffer_size < 2))
|
|
return OCSD_ERR_INVALID_PARAM_VAL;
|
|
std::string str;
|
|
trcPrintElemToString<OcsdTraceElement,ocsd_generic_trace_elem>(p_pkt,str);
|
|
if(str.size() > 0)
|
|
{
|
|
strncpy(buffer,str.c_str(),buffer_size -1);
|
|
buffer[buffer_size-1] = 0;
|
|
}
|
|
return err;
|
|
}
|
|
|
|
/*** Decode tree -- memory accessor control */
|
|
|
|
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)
|
|
{
|
|
ocsd_err_t err = OCSD_OK;
|
|
DecodeTree *pDT;
|
|
err = ocsd_check_and_add_mem_acc_mapper(handle,&pDT);
|
|
if(err == OCSD_OK)
|
|
err = pDT->addBinFileMemAcc(address,mem_space,filepath);
|
|
return err;
|
|
}
|
|
|
|
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)
|
|
{
|
|
ocsd_err_t err = OCSD_OK;
|
|
DecodeTree *pDT;
|
|
err = ocsd_check_and_add_mem_acc_mapper(handle,&pDT);
|
|
if(err == OCSD_OK)
|
|
err = pDT->addBinFileRegionMemAcc(region_array,num_regions,mem_space,filepath);
|
|
return err;
|
|
}
|
|
|
|
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)
|
|
{
|
|
ocsd_err_t err = OCSD_OK;
|
|
DecodeTree *pDT;
|
|
err = ocsd_check_and_add_mem_acc_mapper(handle,&pDT);
|
|
if(err == OCSD_OK)
|
|
err = pDT->addBufferMemAcc(address,mem_space,p_mem_buffer,mem_length);
|
|
return err;
|
|
}
|
|
|
|
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)
|
|
{
|
|
ocsd_err_t err = OCSD_OK;
|
|
DecodeTree *pDT;
|
|
err = ocsd_check_and_add_mem_acc_mapper(handle,&pDT);
|
|
if(err == OCSD_OK)
|
|
err = pDT->addCallbackMemAcc(st_address,en_address,mem_space,p_cb_func,p_context);
|
|
return err;
|
|
}
|
|
|
|
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)
|
|
{
|
|
ocsd_err_t err = OCSD_OK;
|
|
DecodeTree *pDT;
|
|
err = ocsd_check_and_add_mem_acc_mapper(handle, &pDT);
|
|
if (err == OCSD_OK)
|
|
err = pDT->addCallbackIDMemAcc(st_address, en_address, mem_space, p_cb_func, p_context);
|
|
return err;
|
|
}
|
|
|
|
|
|
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)
|
|
{
|
|
ocsd_err_t err = OCSD_OK;
|
|
|
|
if(handle != C_API_INVALID_TREE_HANDLE)
|
|
{
|
|
DecodeTree *pDT = static_cast<DecodeTree *>(handle);
|
|
err = pDT->removeMemAccByAddress(st_address,mem_space);
|
|
}
|
|
else
|
|
err = OCSD_ERR_INVALID_PARAM_VAL;
|
|
return err;
|
|
}
|
|
|
|
OCSD_C_API void ocsd_tl_log_mapped_mem_ranges(const dcd_tree_handle_t handle)
|
|
{
|
|
if(handle != C_API_INVALID_TREE_HANDLE)
|
|
{
|
|
DecodeTree *pDT = static_cast<DecodeTree *>(handle);
|
|
pDT->logMappedRanges();
|
|
}
|
|
}
|
|
|
|
OCSD_C_API void ocsd_gen_elem_init(ocsd_generic_trace_elem *p_pkt, const ocsd_gen_trc_elem_t elem_type)
|
|
{
|
|
p_pkt->elem_type = elem_type;
|
|
p_pkt->flag_bits = 0;
|
|
p_pkt->ptr_extended_data = 0;
|
|
}
|
|
|
|
OCSD_C_API ocsd_err_t ocsd_dt_set_raw_frame_printer(const dcd_tree_handle_t handle, int flags)
|
|
{
|
|
if (handle != C_API_INVALID_TREE_HANDLE)
|
|
return ((DecodeTree *)handle)->addRawFramePrinter(0, (uint32_t)flags);
|
|
return OCSD_ERR_NOT_INIT;
|
|
}
|
|
|
|
OCSD_C_API ocsd_err_t ocsd_dt_set_gen_elem_printer(const dcd_tree_handle_t handle)
|
|
{
|
|
if (handle != C_API_INVALID_TREE_HANDLE)
|
|
return ((DecodeTree *)handle)->addGenElemPrinter(0);
|
|
return OCSD_ERR_NOT_INIT;
|
|
}
|
|
|
|
OCSD_C_API ocsd_err_t ocsd_dt_set_pkt_protocol_printer(const dcd_tree_handle_t handle, uint8_t cs_id, int monitor)
|
|
{
|
|
ocsd_err_t err = OCSD_ERR_NOT_INIT;
|
|
if (handle != C_API_INVALID_TREE_HANDLE)
|
|
{
|
|
DecodeTree *p_tree = (DecodeTree *)handle;
|
|
err = p_tree->addPacketPrinter(cs_id, (bool)(monitor != 0), 0);
|
|
}
|
|
return err;
|
|
}
|
|
|
|
OCSD_C_API void ocsd_err_str(const ocsd_err_t err, char *buffer, const int buffer_size)
|
|
{
|
|
std::string err_str;
|
|
err_str = ocsdError::getErrorString(ocsdError(OCSD_ERR_SEV_ERROR, err));
|
|
strncpy(buffer, err_str.c_str(), buffer_size - 1);
|
|
buffer[buffer_size - 1] = 0;
|
|
}
|
|
|
|
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)
|
|
{
|
|
ocsdError *p_err;
|
|
ocsd_err_t err = OCSD_OK;
|
|
std::string err_str;
|
|
|
|
p_err = DecodeTree::getDefaultErrorLogger()->GetLastError();
|
|
if (p_err)
|
|
{
|
|
*index = p_err->getErrorIndex();
|
|
*chan_id = p_err->getErrorChanID();
|
|
err_str = p_err->getErrorString(ocsdError(p_err));
|
|
strncpy(message, err_str.c_str(), message_len - 1);
|
|
message[message_len - 1] = 0;
|
|
err = p_err->getErrorCode();
|
|
}
|
|
else
|
|
{
|
|
message[0] = 0;
|
|
*index = OCSD_BAD_TRC_INDEX;
|
|
*chan_id = OCSD_BAD_CS_SRC_ID;
|
|
}
|
|
return err;
|
|
}
|
|
|
|
/*******************************************************************************/
|
|
/* C API local fns */
|
|
/*******************************************************************************/
|
|
static ocsd_err_t ocsd_create_pkt_sink_cb(ocsd_trace_protocol_t protocol, FnDefPktDataIn pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj )
|
|
{
|
|
ocsd_err_t err = OCSD_OK;
|
|
*ppCBObj = 0;
|
|
|
|
switch(protocol)
|
|
{
|
|
case OCSD_PROTOCOL_ETMV4I:
|
|
*ppCBObj = new (std::nothrow) PktCBObj<EtmV4ITrcPacket>(pPktInFn,p_context);
|
|
break;
|
|
|
|
case OCSD_PROTOCOL_ETMV3:
|
|
*ppCBObj = new (std::nothrow) PktCBObj<EtmV3TrcPacket>(pPktInFn,p_context);
|
|
break;
|
|
|
|
case OCSD_PROTOCOL_PTM:
|
|
*ppCBObj = new (std::nothrow) PktCBObj<PtmTrcPacket>(pPktInFn,p_context);
|
|
break;
|
|
|
|
case OCSD_PROTOCOL_STM:
|
|
*ppCBObj = new (std::nothrow) PktCBObj<StmTrcPacket>(pPktInFn,p_context);
|
|
break;
|
|
|
|
default:
|
|
if ((protocol >= OCSD_PROTOCOL_CUSTOM_0) && (protocol < OCSD_PROTOCOL_END))
|
|
{
|
|
*ppCBObj = new (std::nothrow) PktCBObj<void>(pPktInFn, p_context);
|
|
}
|
|
else
|
|
err = OCSD_ERR_NO_PROTOCOL;
|
|
break;
|
|
}
|
|
|
|
if((*ppCBObj == 0) && (err == OCSD_OK))
|
|
err = OCSD_ERR_MEM;
|
|
|
|
return err;
|
|
}
|
|
|
|
static ocsd_err_t ocsd_create_pkt_mon_cb(ocsd_trace_protocol_t protocol, FnDefPktDataMon pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj )
|
|
{
|
|
ocsd_err_t err = OCSD_OK;
|
|
*ppCBObj = 0;
|
|
|
|
switch(protocol)
|
|
{
|
|
case OCSD_PROTOCOL_ETMV4I:
|
|
*ppCBObj = new (std::nothrow) PktMonCBObj<EtmV4ITrcPacket>(pPktInFn,p_context);
|
|
break;
|
|
|
|
case OCSD_PROTOCOL_ETMV3:
|
|
*ppCBObj = new (std::nothrow) PktMonCBObj<EtmV3TrcPacket>(pPktInFn,p_context);
|
|
break;
|
|
|
|
case OCSD_PROTOCOL_PTM:
|
|
*ppCBObj = new (std::nothrow) PktMonCBObj<PtmTrcPacket>(pPktInFn,p_context);
|
|
break;
|
|
|
|
case OCSD_PROTOCOL_STM:
|
|
*ppCBObj = new (std::nothrow) PktMonCBObj<StmTrcPacket>(pPktInFn,p_context);
|
|
break;
|
|
|
|
default:
|
|
if ((protocol >= OCSD_PROTOCOL_CUSTOM_0) && (protocol < OCSD_PROTOCOL_END))
|
|
{
|
|
*ppCBObj = new (std::nothrow) PktMonCBObj<void>(pPktInFn, p_context);
|
|
}
|
|
else
|
|
err = OCSD_ERR_NO_PROTOCOL;
|
|
break;
|
|
}
|
|
|
|
if((*ppCBObj == 0) && (err == OCSD_OK))
|
|
err = OCSD_ERR_MEM;
|
|
|
|
return err;
|
|
}
|
|
|
|
static ocsd_err_t ocsd_check_and_add_mem_acc_mapper(const dcd_tree_handle_t handle, DecodeTree **ppDT)
|
|
{
|
|
*ppDT = 0;
|
|
if(handle == C_API_INVALID_TREE_HANDLE)
|
|
return OCSD_ERR_INVALID_PARAM_VAL;
|
|
*ppDT = static_cast<DecodeTree *>(handle);
|
|
if(!(*ppDT)->hasMemAccMapper())
|
|
return (*ppDT)->createMemAccMapper();
|
|
return OCSD_OK;
|
|
}
|
|
|
|
/*******************************************************************************/
|
|
/* C API Helper objects */
|
|
/*******************************************************************************/
|
|
|
|
/****************** Generic trace element output callback function ************/
|
|
GenTraceElemCBObj::GenTraceElemCBObj(FnTraceElemIn pCBFn, const void *p_context) :
|
|
m_c_api_cb_fn(pCBFn),
|
|
m_p_cb_context(p_context)
|
|
{
|
|
}
|
|
|
|
ocsd_datapath_resp_t GenTraceElemCBObj::TraceElemIn(const ocsd_trc_index_t index_sop,
|
|
const uint8_t trc_chan_id,
|
|
const OcsdTraceElement &elem)
|
|
{
|
|
return m_c_api_cb_fn(m_p_cb_context, index_sop, trc_chan_id, &elem);
|
|
}
|
|
|
|
/* End of File ocsd_c_api.cpp */
|