117f65170SRuslan Bukin /*
217f65170SRuslan Bukin  * \file       ocsd_c_api.cpp
317f65170SRuslan Bukin  * \brief      OpenCSD : "C" API libary implementation.
417f65170SRuslan Bukin  *
517f65170SRuslan Bukin  * \copyright  Copyright (c) 2015, ARM Limited. All Rights Reserved.
617f65170SRuslan Bukin  */
717f65170SRuslan Bukin 
817f65170SRuslan Bukin /*
917f65170SRuslan Bukin  * Redistribution and use in source and binary forms, with or without modification,
1017f65170SRuslan Bukin  * are permitted provided that the following conditions are met:
1117f65170SRuslan Bukin  *
1217f65170SRuslan Bukin  * 1. Redistributions of source code must retain the above copyright notice,
1317f65170SRuslan Bukin  * this list of conditions and the following disclaimer.
1417f65170SRuslan Bukin  *
1517f65170SRuslan Bukin  * 2. Redistributions in binary form must reproduce the above copyright notice,
1617f65170SRuslan Bukin  * this list of conditions and the following disclaimer in the documentation
1717f65170SRuslan Bukin  * and/or other materials provided with the distribution.
1817f65170SRuslan Bukin  *
1917f65170SRuslan Bukin  * 3. Neither the name of the copyright holder nor the names of its contributors
2017f65170SRuslan Bukin  * may be used to endorse or promote products derived from this software without
2117f65170SRuslan Bukin  * specific prior written permission.
2217f65170SRuslan Bukin  *
2317f65170SRuslan Bukin  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
2417f65170SRuslan Bukin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2517f65170SRuslan Bukin  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2617f65170SRuslan Bukin  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2717f65170SRuslan Bukin  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2817f65170SRuslan Bukin  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2917f65170SRuslan Bukin  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3017f65170SRuslan Bukin  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3117f65170SRuslan Bukin  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3217f65170SRuslan Bukin  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3317f65170SRuslan Bukin  */
3417f65170SRuslan Bukin 
3517f65170SRuslan Bukin #include <cstring>
3617f65170SRuslan Bukin 
3717f65170SRuslan Bukin /* pull in the C++ decode library */
3817f65170SRuslan Bukin #include "opencsd.h"
3917f65170SRuslan Bukin 
4017f65170SRuslan Bukin /* C-API and wrapper objects */
4117f65170SRuslan Bukin #include "opencsd/c_api/opencsd_c_api.h"
4217f65170SRuslan Bukin #include "ocsd_c_api_obj.h"
4317f65170SRuslan Bukin 
4417f65170SRuslan Bukin /** MSVC2010 unwanted export workaround */
4517f65170SRuslan Bukin #ifdef WIN32
4617f65170SRuslan Bukin #if (_MSC_VER == 1600)
4717f65170SRuslan Bukin #include <new>
4817f65170SRuslan Bukin namespace std { const nothrow_t nothrow = nothrow_t(); }
4917f65170SRuslan Bukin #endif
5017f65170SRuslan Bukin #endif
5117f65170SRuslan Bukin 
5217f65170SRuslan Bukin /*******************************************************************************/
5317f65170SRuslan Bukin /* C API internal helper function declarations                                 */
5417f65170SRuslan Bukin /*******************************************************************************/
5517f65170SRuslan Bukin 
5617f65170SRuslan Bukin static ocsd_err_t ocsd_create_pkt_sink_cb(ocsd_trace_protocol_t protocol, FnDefPktDataIn pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj );
5717f65170SRuslan Bukin static ocsd_err_t ocsd_create_pkt_mon_cb(ocsd_trace_protocol_t protocol, FnDefPktDataMon pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj );
5817f65170SRuslan Bukin static ocsd_err_t ocsd_check_and_add_mem_acc_mapper(const dcd_tree_handle_t handle, DecodeTree **ppDT);
5917f65170SRuslan Bukin 
6017f65170SRuslan Bukin /*******************************************************************************/
6117f65170SRuslan Bukin /* C library data - additional data on top of the C++ library objects          */
6217f65170SRuslan Bukin /*******************************************************************************/
6317f65170SRuslan Bukin 
6417f65170SRuslan Bukin /* keep a list of interface objects for a decode tree for later disposal */
6517f65170SRuslan Bukin typedef struct _lib_dt_data_list {
6617f65170SRuslan Bukin     std::vector<ITrcTypedBase *> cb_objs;
6717f65170SRuslan Bukin     DefLogStrCBObj s_def_log_str_cb;
6817f65170SRuslan Bukin } lib_dt_data_list;
6917f65170SRuslan Bukin 
7017f65170SRuslan Bukin /* map lists to handles */
7117f65170SRuslan Bukin static std::map<dcd_tree_handle_t, lib_dt_data_list *> s_data_map;
7217f65170SRuslan Bukin 
7317f65170SRuslan Bukin /*******************************************************************************/
7417f65170SRuslan Bukin /* C API functions                                                             */
7517f65170SRuslan Bukin /*******************************************************************************/
7617f65170SRuslan Bukin 
77*fc502085SRuslan Bukin /** Get Library version. Return a 32 bit version in form MMMMnnpp - MMMM = major version, nn = minor version, pp = patch version */
ocsd_get_version(void)7817f65170SRuslan Bukin OCSD_C_API uint32_t ocsd_get_version(void)
7917f65170SRuslan Bukin {
8017f65170SRuslan Bukin     return ocsdVersion::vers_num();
8117f65170SRuslan Bukin }
8217f65170SRuslan Bukin 
8317f65170SRuslan Bukin /** Get library version string */
ocsd_get_version_str(void)8417f65170SRuslan Bukin OCSD_C_API const char * ocsd_get_version_str(void)
8517f65170SRuslan Bukin {
8617f65170SRuslan Bukin     return ocsdVersion::vers_str();
8717f65170SRuslan Bukin }
8817f65170SRuslan Bukin 
8917f65170SRuslan Bukin 
9017f65170SRuslan Bukin /*** Decode tree creation etc. */
9117f65170SRuslan Bukin 
ocsd_create_dcd_tree(const ocsd_dcd_tree_src_t src_type,const uint32_t deformatterCfgFlags)9217f65170SRuslan Bukin OCSD_C_API dcd_tree_handle_t ocsd_create_dcd_tree(const ocsd_dcd_tree_src_t src_type, const uint32_t deformatterCfgFlags)
9317f65170SRuslan Bukin {
9417f65170SRuslan Bukin     dcd_tree_handle_t handle = C_API_INVALID_TREE_HANDLE;
9517f65170SRuslan Bukin     handle = (dcd_tree_handle_t)DecodeTree::CreateDecodeTree(src_type,deformatterCfgFlags);
9617f65170SRuslan Bukin     if(handle != C_API_INVALID_TREE_HANDLE)
9717f65170SRuslan Bukin     {
9817f65170SRuslan Bukin         lib_dt_data_list *pList = new (std::nothrow) lib_dt_data_list;
9917f65170SRuslan Bukin         if(pList != 0)
10017f65170SRuslan Bukin         {
10117f65170SRuslan Bukin             s_data_map.insert(std::pair<dcd_tree_handle_t, lib_dt_data_list *>(handle,pList));
10217f65170SRuslan Bukin         }
10317f65170SRuslan Bukin         else
10417f65170SRuslan Bukin         {
10517f65170SRuslan Bukin             ocsd_destroy_dcd_tree(handle);
10617f65170SRuslan Bukin             handle = C_API_INVALID_TREE_HANDLE;
10717f65170SRuslan Bukin         }
10817f65170SRuslan Bukin     }
10917f65170SRuslan Bukin     return handle;
11017f65170SRuslan Bukin }
11117f65170SRuslan Bukin 
ocsd_destroy_dcd_tree(const dcd_tree_handle_t handle)11217f65170SRuslan Bukin OCSD_C_API void ocsd_destroy_dcd_tree(const dcd_tree_handle_t handle)
11317f65170SRuslan Bukin {
11417f65170SRuslan Bukin     if(handle != C_API_INVALID_TREE_HANDLE)
11517f65170SRuslan Bukin     {
11617f65170SRuslan Bukin         GenTraceElemCBObj * pIf = (GenTraceElemCBObj *)(((DecodeTree *)handle)->getGenTraceElemOutI());
11717f65170SRuslan Bukin         if(pIf != 0)
11817f65170SRuslan Bukin             delete pIf;
11917f65170SRuslan Bukin 
12017f65170SRuslan Bukin         /* need to clear any associated callback data. */
12117f65170SRuslan Bukin         std::map<dcd_tree_handle_t, lib_dt_data_list *>::iterator it;
12217f65170SRuslan Bukin         it = s_data_map.find(handle);
12317f65170SRuslan Bukin         if(it != s_data_map.end())
12417f65170SRuslan Bukin         {
12517f65170SRuslan Bukin             std::vector<ITrcTypedBase *>::iterator itcb;
12617f65170SRuslan Bukin             itcb = it->second->cb_objs.begin();
12717f65170SRuslan Bukin             while(itcb != it->second->cb_objs.end())
12817f65170SRuslan Bukin             {
12917f65170SRuslan Bukin                 delete *itcb;
13017f65170SRuslan Bukin                 itcb++;
13117f65170SRuslan Bukin             }
13217f65170SRuslan Bukin             it->second->cb_objs.clear();
13317f65170SRuslan Bukin             delete it->second;
13417f65170SRuslan Bukin             s_data_map.erase(it);
13517f65170SRuslan Bukin         }
13617f65170SRuslan Bukin         DecodeTree::DestroyDecodeTree((DecodeTree *)handle);
13717f65170SRuslan Bukin     }
13817f65170SRuslan Bukin }
13917f65170SRuslan Bukin 
14017f65170SRuslan Bukin /*** Decode tree process data */
14117f65170SRuslan Bukin 
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)14217f65170SRuslan Bukin OCSD_C_API ocsd_datapath_resp_t ocsd_dt_process_data(const dcd_tree_handle_t handle,
14317f65170SRuslan Bukin                                             const ocsd_datapath_op_t op,
14417f65170SRuslan Bukin                                             const ocsd_trc_index_t index,
14517f65170SRuslan Bukin                                             const uint32_t dataBlockSize,
14617f65170SRuslan Bukin                                             const uint8_t *pDataBlock,
14717f65170SRuslan Bukin                                             uint32_t *numBytesProcessed)
14817f65170SRuslan Bukin {
14917f65170SRuslan Bukin     ocsd_datapath_resp_t resp =  OCSD_RESP_FATAL_NOT_INIT;
15017f65170SRuslan Bukin     if(handle != C_API_INVALID_TREE_HANDLE)
15117f65170SRuslan Bukin         resp = ((DecodeTree *)handle)->TraceDataIn(op,index,dataBlockSize,pDataBlock,numBytesProcessed);
15217f65170SRuslan Bukin     return resp;
15317f65170SRuslan Bukin }
15417f65170SRuslan Bukin 
15517f65170SRuslan Bukin /*** Decode tree - decoder management */
15617f65170SRuslan Bukin 
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)15717f65170SRuslan Bukin OCSD_C_API ocsd_err_t ocsd_dt_create_decoder(const dcd_tree_handle_t handle,
15817f65170SRuslan Bukin                                              const char *decoder_name,
15917f65170SRuslan Bukin                                              const int create_flags,
16017f65170SRuslan Bukin                                              const void *decoder_cfg,
16117f65170SRuslan Bukin                                              unsigned char *pCSID
16217f65170SRuslan Bukin                                              )
16317f65170SRuslan Bukin {
16417f65170SRuslan Bukin     ocsd_err_t err = OCSD_OK;
16517f65170SRuslan Bukin     DecodeTree *dt = (DecodeTree *)handle;
16617f65170SRuslan Bukin     std::string dName = decoder_name;
16717f65170SRuslan Bukin     IDecoderMngr *pDcdMngr;
16817f65170SRuslan Bukin     err = OcsdLibDcdRegister::getDecoderRegister()->getDecoderMngrByName(dName,&pDcdMngr);
16917f65170SRuslan Bukin     if(err != OCSD_OK)
17017f65170SRuslan Bukin         return err;
17117f65170SRuslan Bukin 
17217f65170SRuslan Bukin     CSConfig *pConfig = 0;
17317f65170SRuslan Bukin     err = pDcdMngr->createConfigFromDataStruct(&pConfig,decoder_cfg);
17417f65170SRuslan Bukin     if(err != OCSD_OK)
17517f65170SRuslan Bukin         return err;
17617f65170SRuslan Bukin 
17717f65170SRuslan Bukin     err = dt->createDecoder(dName,create_flags,pConfig);
17817f65170SRuslan Bukin     if(err == OCSD_OK)
17917f65170SRuslan Bukin         *pCSID = pConfig->getTraceID();
18017f65170SRuslan Bukin     delete pConfig;
18117f65170SRuslan Bukin     return err;
18217f65170SRuslan Bukin }
18317f65170SRuslan Bukin 
ocsd_dt_remove_decoder(const dcd_tree_handle_t handle,const unsigned char CSID)18417f65170SRuslan Bukin OCSD_C_API ocsd_err_t ocsd_dt_remove_decoder(   const dcd_tree_handle_t handle,
18517f65170SRuslan Bukin                                                 const unsigned char CSID)
18617f65170SRuslan Bukin {
18717f65170SRuslan Bukin     return ((DecodeTree *)handle)->removeDecoder(CSID);
18817f65170SRuslan Bukin }
18917f65170SRuslan Bukin 
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)19017f65170SRuslan Bukin OCSD_C_API ocsd_err_t ocsd_dt_attach_packet_callback(  const dcd_tree_handle_t handle,
19117f65170SRuslan Bukin                                                 const unsigned char CSID,
19217f65170SRuslan Bukin                                                 const ocsd_c_api_cb_types callback_type,
19317f65170SRuslan Bukin                                                 void *p_fn_callback_data,
19417f65170SRuslan Bukin                                                 const void *p_context)
19517f65170SRuslan Bukin {
19617f65170SRuslan Bukin     ocsd_err_t err = OCSD_OK;
19717f65170SRuslan Bukin     DecodeTree *pDT = static_cast<DecodeTree *>(handle);
19817f65170SRuslan Bukin     DecodeTreeElement *pElem = pDT->getDecoderElement(CSID);
19917f65170SRuslan Bukin     if(pElem == 0)
20017f65170SRuslan Bukin         return OCSD_ERR_INVALID_ID;  // cannot find entry for that CSID
20117f65170SRuslan Bukin 
20217f65170SRuslan Bukin     ITrcTypedBase *pDataInSink = 0;  // pointer to a sink callback object
20317f65170SRuslan Bukin     switch(callback_type)
20417f65170SRuslan Bukin     {
20517f65170SRuslan Bukin     case OCSD_C_API_CB_PKT_SINK:
20617f65170SRuslan Bukin         err = ocsd_create_pkt_sink_cb(pElem->getProtocol(),(FnDefPktDataIn)p_fn_callback_data,p_context,&pDataInSink);
20717f65170SRuslan Bukin         if(err == OCSD_OK)
20817f65170SRuslan Bukin             err = pElem->getDecoderMngr()->attachPktSink(pElem->getDecoderHandle(), pDataInSink);
20917f65170SRuslan Bukin         break;
21017f65170SRuslan Bukin 
21117f65170SRuslan Bukin     case OCSD_C_API_CB_PKT_MON:
21217f65170SRuslan Bukin         err = ocsd_create_pkt_mon_cb(pElem->getProtocol(),(FnDefPktDataMon)p_fn_callback_data,p_context,&pDataInSink);
21317f65170SRuslan Bukin         if (err == OCSD_OK)
21417f65170SRuslan Bukin             err = pElem->getDecoderMngr()->attachPktMonitor(pElem->getDecoderHandle(), pDataInSink);
21517f65170SRuslan Bukin         break;
21617f65170SRuslan Bukin 
21717f65170SRuslan Bukin     default:
21817f65170SRuslan Bukin         err = OCSD_ERR_INVALID_PARAM_VAL;
21917f65170SRuslan Bukin     }
22017f65170SRuslan Bukin 
22117f65170SRuslan Bukin     if(err == OCSD_OK)
22217f65170SRuslan Bukin     {
22317f65170SRuslan Bukin         if (err == OCSD_OK)
22417f65170SRuslan Bukin         {
22517f65170SRuslan Bukin             // save object pointer for destruction later.
22617f65170SRuslan Bukin             std::map<dcd_tree_handle_t, lib_dt_data_list *>::iterator it;
22717f65170SRuslan Bukin             it = s_data_map.find(handle);
22817f65170SRuslan Bukin             if (it != s_data_map.end())
22917f65170SRuslan Bukin                 it->second->cb_objs.push_back(pDataInSink);
23017f65170SRuslan Bukin         }
23117f65170SRuslan Bukin         else
23217f65170SRuslan Bukin             delete pDataInSink;
23317f65170SRuslan Bukin     }
23417f65170SRuslan Bukin     return err;
23517f65170SRuslan Bukin }
23617f65170SRuslan Bukin 
23717f65170SRuslan Bukin /*** Decode tree set element output */
23817f65170SRuslan Bukin 
ocsd_dt_set_gen_elem_outfn(const dcd_tree_handle_t handle,FnTraceElemIn pFn,const void * p_context)23917f65170SRuslan Bukin OCSD_C_API ocsd_err_t ocsd_dt_set_gen_elem_outfn(const dcd_tree_handle_t handle, FnTraceElemIn pFn, const void *p_context)
24017f65170SRuslan Bukin {
24117f65170SRuslan Bukin 
24217f65170SRuslan Bukin     GenTraceElemCBObj * pCBObj = new (std::nothrow)GenTraceElemCBObj(pFn, p_context);
24317f65170SRuslan Bukin     if(pCBObj)
24417f65170SRuslan Bukin     {
24517f65170SRuslan Bukin         ((DecodeTree *)handle)->setGenTraceElemOutI(pCBObj);
24617f65170SRuslan Bukin         return OCSD_OK;
24717f65170SRuslan Bukin     }
24817f65170SRuslan Bukin     return OCSD_ERR_MEM;
24917f65170SRuslan Bukin }
25017f65170SRuslan Bukin 
25117f65170SRuslan Bukin 
25217f65170SRuslan Bukin /*** Default error logging */
25317f65170SRuslan Bukin 
ocsd_def_errlog_init(const ocsd_err_severity_t verbosity,const int create_output_logger)25417f65170SRuslan Bukin OCSD_C_API ocsd_err_t ocsd_def_errlog_init(const ocsd_err_severity_t verbosity, const int create_output_logger)
25517f65170SRuslan Bukin {
25617f65170SRuslan Bukin     if(DecodeTree::getDefaultErrorLogger()->initErrorLogger(verbosity,(bool)(create_output_logger != 0)))
25717f65170SRuslan Bukin         return OCSD_OK;
25817f65170SRuslan Bukin     return OCSD_ERR_NOT_INIT;
25917f65170SRuslan Bukin }
26017f65170SRuslan Bukin 
ocsd_def_errlog_config_output(const int output_flags,const char * log_file_name)26117f65170SRuslan Bukin OCSD_C_API ocsd_err_t ocsd_def_errlog_config_output(const int output_flags, const char *log_file_name)
26217f65170SRuslan Bukin {
26317f65170SRuslan Bukin     ocsdMsgLogger *pLogger = DecodeTree::getDefaultErrorLogger()->getOutputLogger();
26417f65170SRuslan Bukin     if(pLogger)
26517f65170SRuslan Bukin     {
26617f65170SRuslan Bukin         pLogger->setLogOpts(output_flags & C_API_MSGLOGOUT_MASK);
26717f65170SRuslan Bukin         if(log_file_name != NULL)
26817f65170SRuslan Bukin         {
26917f65170SRuslan Bukin             pLogger->setLogFileName(log_file_name);
27017f65170SRuslan Bukin         }
27117f65170SRuslan Bukin         return OCSD_OK;
27217f65170SRuslan Bukin     }
27317f65170SRuslan Bukin     return OCSD_ERR_NOT_INIT;
27417f65170SRuslan Bukin }
27517f65170SRuslan Bukin 
27617f65170SRuslan Bukin 
ocsd_def_errlog_set_strprint_cb(const dcd_tree_handle_t handle,void * p_context,FnDefLoggerPrintStrCB p_str_print_cb)27717f65170SRuslan Bukin 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)
27817f65170SRuslan Bukin {
27917f65170SRuslan Bukin     ocsdMsgLogger *pLogger = DecodeTree::getDefaultErrorLogger()->getOutputLogger();
28017f65170SRuslan Bukin     if (pLogger)
28117f65170SRuslan Bukin     {
28217f65170SRuslan Bukin         std::map<dcd_tree_handle_t, lib_dt_data_list *>::iterator it;
28317f65170SRuslan Bukin         it = s_data_map.find(handle);
28417f65170SRuslan Bukin         if (it != s_data_map.end())
28517f65170SRuslan Bukin         {
28617f65170SRuslan Bukin             DefLogStrCBObj *pCBObj = &(it->second->s_def_log_str_cb);
28717f65170SRuslan Bukin             pCBObj->setCBFn(p_context, p_str_print_cb);
28817f65170SRuslan Bukin             pLogger->setStrOutFn(pCBObj);
28917f65170SRuslan Bukin             int logOpts = pLogger->getLogOpts();
29017f65170SRuslan Bukin             logOpts |= (int)(ocsdMsgLogger::OUT_STR_CB);
29117f65170SRuslan Bukin             pLogger->setLogOpts(logOpts);
29217f65170SRuslan Bukin             return OCSD_OK;
29317f65170SRuslan Bukin         }
29417f65170SRuslan Bukin     }
29517f65170SRuslan Bukin     return OCSD_ERR_NOT_INIT;
29617f65170SRuslan Bukin }
29717f65170SRuslan Bukin 
ocsd_def_errlog_msgout(const char * msg)29817f65170SRuslan Bukin OCSD_C_API void ocsd_def_errlog_msgout(const char *msg)
29917f65170SRuslan Bukin {
30017f65170SRuslan Bukin     ocsdMsgLogger *pLogger = DecodeTree::getDefaultErrorLogger()->getOutputLogger();
30117f65170SRuslan Bukin     if(pLogger)
30217f65170SRuslan Bukin         pLogger->LogMsg(msg);
30317f65170SRuslan Bukin }
30417f65170SRuslan Bukin 
30517f65170SRuslan Bukin /*** Convert packet to string */
30617f65170SRuslan Bukin 
ocsd_pkt_str(const ocsd_trace_protocol_t pkt_protocol,const void * p_pkt,char * buffer,const int buffer_size)30717f65170SRuslan Bukin 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)
30817f65170SRuslan Bukin {
30917f65170SRuslan Bukin     ocsd_err_t err = OCSD_OK;
31017f65170SRuslan Bukin     if((buffer == NULL) || (buffer_size < 2))
31117f65170SRuslan Bukin         return OCSD_ERR_INVALID_PARAM_VAL;
31217f65170SRuslan Bukin 
31317f65170SRuslan Bukin     std::string pktStr = "";
31417f65170SRuslan Bukin     buffer[0] = 0;
31517f65170SRuslan Bukin 
31617f65170SRuslan Bukin     switch(pkt_protocol)
31717f65170SRuslan Bukin     {
31817f65170SRuslan Bukin     case OCSD_PROTOCOL_ETMV4I:
31917f65170SRuslan Bukin         trcPrintElemToString<EtmV4ITrcPacket,ocsd_etmv4_i_pkt>(p_pkt, pktStr);
32017f65170SRuslan Bukin         break;
32117f65170SRuslan Bukin 
32217f65170SRuslan Bukin     case OCSD_PROTOCOL_ETMV3:
32317f65170SRuslan Bukin         trcPrintElemToString<EtmV3TrcPacket,ocsd_etmv3_pkt>(p_pkt, pktStr);
32417f65170SRuslan Bukin         break;
32517f65170SRuslan Bukin 
32617f65170SRuslan Bukin     case OCSD_PROTOCOL_STM:
32717f65170SRuslan Bukin         trcPrintElemToString<StmTrcPacket,ocsd_stm_pkt>(p_pkt, pktStr);
32817f65170SRuslan Bukin         break;
32917f65170SRuslan Bukin 
33017f65170SRuslan Bukin     case OCSD_PROTOCOL_PTM:
33117f65170SRuslan Bukin         trcPrintElemToString<PtmTrcPacket,ocsd_ptm_pkt>(p_pkt, pktStr);
33217f65170SRuslan Bukin         break;
33317f65170SRuslan Bukin 
33417f65170SRuslan Bukin     default:
33517f65170SRuslan Bukin         if (OCSD_PROTOCOL_IS_CUSTOM(pkt_protocol))
33617f65170SRuslan Bukin             err = ocsd_cust_protocol_to_str(pkt_protocol, p_pkt, buffer, buffer_size);
33717f65170SRuslan Bukin         else
33817f65170SRuslan Bukin             err = OCSD_ERR_NO_PROTOCOL;
33917f65170SRuslan Bukin         break;
34017f65170SRuslan Bukin     }
34117f65170SRuslan Bukin 
34217f65170SRuslan Bukin     if(pktStr.size() > 0)
34317f65170SRuslan Bukin     {
34417f65170SRuslan Bukin         strncpy(buffer,pktStr.c_str(),buffer_size-1);
34517f65170SRuslan Bukin         buffer[buffer_size-1] = 0;
34617f65170SRuslan Bukin     }
34717f65170SRuslan Bukin     return err;
34817f65170SRuslan Bukin }
34917f65170SRuslan Bukin 
ocsd_gen_elem_str(const ocsd_generic_trace_elem * p_pkt,char * buffer,const int buffer_size)35017f65170SRuslan Bukin OCSD_C_API ocsd_err_t ocsd_gen_elem_str(const ocsd_generic_trace_elem *p_pkt, char *buffer, const int buffer_size)
35117f65170SRuslan Bukin {
35217f65170SRuslan Bukin     ocsd_err_t err = OCSD_OK;
35317f65170SRuslan Bukin     if((buffer == NULL) || (buffer_size < 2))
35417f65170SRuslan Bukin         return OCSD_ERR_INVALID_PARAM_VAL;
35517f65170SRuslan Bukin     std::string str;
35617f65170SRuslan Bukin     trcPrintElemToString<OcsdTraceElement,ocsd_generic_trace_elem>(p_pkt,str);
35717f65170SRuslan Bukin     if(str.size() > 0)
35817f65170SRuslan Bukin     {
35917f65170SRuslan Bukin         strncpy(buffer,str.c_str(),buffer_size -1);
36017f65170SRuslan Bukin         buffer[buffer_size-1] = 0;
36117f65170SRuslan Bukin     }
36217f65170SRuslan Bukin     return err;
36317f65170SRuslan Bukin }
36417f65170SRuslan Bukin 
36517f65170SRuslan Bukin /*** Decode tree -- memory accessor control */
36617f65170SRuslan Bukin 
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)36717f65170SRuslan Bukin 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)
36817f65170SRuslan Bukin {
36917f65170SRuslan Bukin     ocsd_err_t err = OCSD_OK;
37017f65170SRuslan Bukin     DecodeTree *pDT;
37117f65170SRuslan Bukin     err = ocsd_check_and_add_mem_acc_mapper(handle,&pDT);
37217f65170SRuslan Bukin     if(err == OCSD_OK)
37317f65170SRuslan Bukin         err = pDT->addBinFileMemAcc(address,mem_space,filepath);
37417f65170SRuslan Bukin     return err;
37517f65170SRuslan Bukin }
37617f65170SRuslan Bukin 
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)37717f65170SRuslan Bukin 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)
37817f65170SRuslan Bukin {
37917f65170SRuslan Bukin     ocsd_err_t err = OCSD_OK;
38017f65170SRuslan Bukin     DecodeTree *pDT;
38117f65170SRuslan Bukin     err = ocsd_check_and_add_mem_acc_mapper(handle,&pDT);
38217f65170SRuslan Bukin     if(err == OCSD_OK)
38317f65170SRuslan Bukin         err = pDT->addBinFileRegionMemAcc(region_array,num_regions,mem_space,filepath);
38417f65170SRuslan Bukin     return err;
38517f65170SRuslan Bukin }
38617f65170SRuslan Bukin 
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)38717f65170SRuslan Bukin 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)
38817f65170SRuslan Bukin {
38917f65170SRuslan Bukin     ocsd_err_t err = OCSD_OK;
39017f65170SRuslan Bukin     DecodeTree *pDT;
39117f65170SRuslan Bukin     err = ocsd_check_and_add_mem_acc_mapper(handle,&pDT);
39217f65170SRuslan Bukin     if(err == OCSD_OK)
39317f65170SRuslan Bukin         err = pDT->addBufferMemAcc(address,mem_space,p_mem_buffer,mem_length);
39417f65170SRuslan Bukin     return err;
39517f65170SRuslan Bukin }
39617f65170SRuslan Bukin 
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)39717f65170SRuslan Bukin 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)
39817f65170SRuslan Bukin {
39917f65170SRuslan Bukin     ocsd_err_t err = OCSD_OK;
40017f65170SRuslan Bukin     DecodeTree *pDT;
40117f65170SRuslan Bukin     err = ocsd_check_and_add_mem_acc_mapper(handle,&pDT);
40217f65170SRuslan Bukin     if(err == OCSD_OK)
40317f65170SRuslan Bukin         err = pDT->addCallbackMemAcc(st_address,en_address,mem_space,p_cb_func,p_context);
40417f65170SRuslan Bukin     return err;
40517f65170SRuslan Bukin }
40617f65170SRuslan Bukin 
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)407*fc502085SRuslan Bukin 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)
408*fc502085SRuslan Bukin {
409*fc502085SRuslan Bukin     ocsd_err_t err = OCSD_OK;
410*fc502085SRuslan Bukin     DecodeTree *pDT;
411*fc502085SRuslan Bukin     err = ocsd_check_and_add_mem_acc_mapper(handle, &pDT);
412*fc502085SRuslan Bukin     if (err == OCSD_OK)
413*fc502085SRuslan Bukin         err = pDT->addCallbackIDMemAcc(st_address, en_address, mem_space, p_cb_func, p_context);
414*fc502085SRuslan Bukin     return err;
415*fc502085SRuslan Bukin }
416*fc502085SRuslan Bukin 
417*fc502085SRuslan Bukin 
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)41817f65170SRuslan Bukin 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)
41917f65170SRuslan Bukin {
42017f65170SRuslan Bukin     ocsd_err_t err = OCSD_OK;
42117f65170SRuslan Bukin 
42217f65170SRuslan Bukin     if(handle != C_API_INVALID_TREE_HANDLE)
42317f65170SRuslan Bukin     {
42417f65170SRuslan Bukin         DecodeTree *pDT = static_cast<DecodeTree *>(handle);
42517f65170SRuslan Bukin         err = pDT->removeMemAccByAddress(st_address,mem_space);
42617f65170SRuslan Bukin     }
42717f65170SRuslan Bukin     else
42817f65170SRuslan Bukin         err = OCSD_ERR_INVALID_PARAM_VAL;
42917f65170SRuslan Bukin     return err;
43017f65170SRuslan Bukin }
43117f65170SRuslan Bukin 
ocsd_tl_log_mapped_mem_ranges(const dcd_tree_handle_t handle)43217f65170SRuslan Bukin OCSD_C_API void ocsd_tl_log_mapped_mem_ranges(const dcd_tree_handle_t handle)
43317f65170SRuslan Bukin {
43417f65170SRuslan Bukin     if(handle != C_API_INVALID_TREE_HANDLE)
43517f65170SRuslan Bukin     {
43617f65170SRuslan Bukin         DecodeTree *pDT = static_cast<DecodeTree *>(handle);
43717f65170SRuslan Bukin         pDT->logMappedRanges();
43817f65170SRuslan Bukin     }
43917f65170SRuslan Bukin }
44017f65170SRuslan Bukin 
ocsd_gen_elem_init(ocsd_generic_trace_elem * p_pkt,const ocsd_gen_trc_elem_t elem_type)44117f65170SRuslan Bukin OCSD_C_API void ocsd_gen_elem_init(ocsd_generic_trace_elem *p_pkt, const ocsd_gen_trc_elem_t elem_type)
44217f65170SRuslan Bukin {
44317f65170SRuslan Bukin     p_pkt->elem_type = elem_type;
44417f65170SRuslan Bukin     p_pkt->flag_bits = 0;
44517f65170SRuslan Bukin     p_pkt->ptr_extended_data = 0;
44617f65170SRuslan Bukin }
44717f65170SRuslan Bukin 
ocsd_dt_set_raw_frame_printer(const dcd_tree_handle_t handle,int flags)44817f65170SRuslan Bukin OCSD_C_API ocsd_err_t ocsd_dt_set_raw_frame_printer(const dcd_tree_handle_t handle, int flags)
44917f65170SRuslan Bukin {
45017f65170SRuslan Bukin     if (handle != C_API_INVALID_TREE_HANDLE)
45117f65170SRuslan Bukin         return ((DecodeTree *)handle)->addRawFramePrinter(0, (uint32_t)flags);
45217f65170SRuslan Bukin     return OCSD_ERR_NOT_INIT;
45317f65170SRuslan Bukin }
45417f65170SRuslan Bukin 
ocsd_dt_set_gen_elem_printer(const dcd_tree_handle_t handle)45517f65170SRuslan Bukin OCSD_C_API ocsd_err_t ocsd_dt_set_gen_elem_printer(const dcd_tree_handle_t handle)
45617f65170SRuslan Bukin {
45717f65170SRuslan Bukin     if (handle != C_API_INVALID_TREE_HANDLE)
45817f65170SRuslan Bukin         return ((DecodeTree *)handle)->addGenElemPrinter(0);
45917f65170SRuslan Bukin     return OCSD_ERR_NOT_INIT;
46017f65170SRuslan Bukin }
46117f65170SRuslan Bukin 
ocsd_dt_set_pkt_protocol_printer(const dcd_tree_handle_t handle,uint8_t cs_id,int monitor)46217f65170SRuslan Bukin OCSD_C_API ocsd_err_t ocsd_dt_set_pkt_protocol_printer(const dcd_tree_handle_t handle, uint8_t cs_id, int monitor)
46317f65170SRuslan Bukin {
46417f65170SRuslan Bukin     ocsd_err_t err = OCSD_ERR_NOT_INIT;
46517f65170SRuslan Bukin     if (handle != C_API_INVALID_TREE_HANDLE)
46617f65170SRuslan Bukin     {
46717f65170SRuslan Bukin         DecodeTree *p_tree = (DecodeTree *)handle;
46817f65170SRuslan Bukin         err = p_tree->addPacketPrinter(cs_id, (bool)(monitor != 0), 0);
46917f65170SRuslan Bukin     }
47017f65170SRuslan Bukin     return err;
47117f65170SRuslan Bukin }
47217f65170SRuslan Bukin 
47317f65170SRuslan Bukin /*******************************************************************************/
47417f65170SRuslan Bukin /* C API local fns                                                             */
47517f65170SRuslan Bukin /*******************************************************************************/
ocsd_create_pkt_sink_cb(ocsd_trace_protocol_t protocol,FnDefPktDataIn pPktInFn,const void * p_context,ITrcTypedBase ** ppCBObj)47617f65170SRuslan Bukin static ocsd_err_t ocsd_create_pkt_sink_cb(ocsd_trace_protocol_t protocol,  FnDefPktDataIn pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj )
47717f65170SRuslan Bukin {
47817f65170SRuslan Bukin     ocsd_err_t err = OCSD_OK;
47917f65170SRuslan Bukin     *ppCBObj = 0;
48017f65170SRuslan Bukin 
48117f65170SRuslan Bukin     switch(protocol)
48217f65170SRuslan Bukin     {
48317f65170SRuslan Bukin     case OCSD_PROTOCOL_ETMV4I:
48417f65170SRuslan Bukin         *ppCBObj = new (std::nothrow) PktCBObj<EtmV4ITrcPacket>(pPktInFn,p_context);
48517f65170SRuslan Bukin         break;
48617f65170SRuslan Bukin 
48717f65170SRuslan Bukin     case OCSD_PROTOCOL_ETMV3:
48817f65170SRuslan Bukin         *ppCBObj = new (std::nothrow) PktCBObj<EtmV3TrcPacket>(pPktInFn,p_context);
48917f65170SRuslan Bukin         break;
49017f65170SRuslan Bukin 
49117f65170SRuslan Bukin     case OCSD_PROTOCOL_PTM:
49217f65170SRuslan Bukin         *ppCBObj = new (std::nothrow) PktCBObj<PtmTrcPacket>(pPktInFn,p_context);
49317f65170SRuslan Bukin         break;
49417f65170SRuslan Bukin 
49517f65170SRuslan Bukin     case OCSD_PROTOCOL_STM:
49617f65170SRuslan Bukin         *ppCBObj = new (std::nothrow) PktCBObj<StmTrcPacket>(pPktInFn,p_context);
49717f65170SRuslan Bukin         break;
49817f65170SRuslan Bukin 
49917f65170SRuslan Bukin     default:
50017f65170SRuslan Bukin         if ((protocol >= OCSD_PROTOCOL_CUSTOM_0) && (protocol < OCSD_PROTOCOL_END))
50117f65170SRuslan Bukin         {
50217f65170SRuslan Bukin             *ppCBObj = new (std::nothrow) PktCBObj<void>(pPktInFn, p_context);
50317f65170SRuslan Bukin         }
50417f65170SRuslan Bukin         else
50517f65170SRuslan Bukin             err = OCSD_ERR_NO_PROTOCOL;
50617f65170SRuslan Bukin         break;
50717f65170SRuslan Bukin     }
50817f65170SRuslan Bukin 
50917f65170SRuslan Bukin     if((*ppCBObj == 0) && (err == OCSD_OK))
51017f65170SRuslan Bukin         err = OCSD_ERR_MEM;
51117f65170SRuslan Bukin 
51217f65170SRuslan Bukin     return err;
51317f65170SRuslan Bukin }
51417f65170SRuslan Bukin 
ocsd_create_pkt_mon_cb(ocsd_trace_protocol_t protocol,FnDefPktDataMon pPktInFn,const void * p_context,ITrcTypedBase ** ppCBObj)51517f65170SRuslan Bukin static ocsd_err_t ocsd_create_pkt_mon_cb(ocsd_trace_protocol_t protocol, FnDefPktDataMon pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj )
51617f65170SRuslan Bukin {
51717f65170SRuslan Bukin     ocsd_err_t err = OCSD_OK;
51817f65170SRuslan Bukin     *ppCBObj = 0;
51917f65170SRuslan Bukin 
52017f65170SRuslan Bukin     switch(protocol)
52117f65170SRuslan Bukin     {
52217f65170SRuslan Bukin     case OCSD_PROTOCOL_ETMV4I:
52317f65170SRuslan Bukin         *ppCBObj = new (std::nothrow) PktMonCBObj<EtmV4ITrcPacket>(pPktInFn,p_context);
52417f65170SRuslan Bukin         break;
52517f65170SRuslan Bukin 
52617f65170SRuslan Bukin     case OCSD_PROTOCOL_ETMV3:
52717f65170SRuslan Bukin         *ppCBObj = new (std::nothrow) PktMonCBObj<EtmV3TrcPacket>(pPktInFn,p_context);
52817f65170SRuslan Bukin         break;
52917f65170SRuslan Bukin 
53017f65170SRuslan Bukin     case OCSD_PROTOCOL_PTM:
53117f65170SRuslan Bukin         *ppCBObj = new (std::nothrow) PktMonCBObj<PtmTrcPacket>(pPktInFn,p_context);
53217f65170SRuslan Bukin         break;
53317f65170SRuslan Bukin 
53417f65170SRuslan Bukin     case OCSD_PROTOCOL_STM:
53517f65170SRuslan Bukin         *ppCBObj = new (std::nothrow) PktMonCBObj<StmTrcPacket>(pPktInFn,p_context);
53617f65170SRuslan Bukin         break;
53717f65170SRuslan Bukin 
53817f65170SRuslan Bukin     default:
53917f65170SRuslan Bukin         if ((protocol >= OCSD_PROTOCOL_CUSTOM_0) && (protocol < OCSD_PROTOCOL_END))
54017f65170SRuslan Bukin         {
54117f65170SRuslan Bukin             *ppCBObj = new (std::nothrow) PktMonCBObj<void>(pPktInFn, p_context);
54217f65170SRuslan Bukin         }
54317f65170SRuslan Bukin         else
54417f65170SRuslan Bukin             err = OCSD_ERR_NO_PROTOCOL;
54517f65170SRuslan Bukin         break;
54617f65170SRuslan Bukin     }
54717f65170SRuslan Bukin 
54817f65170SRuslan Bukin     if((*ppCBObj == 0) && (err == OCSD_OK))
54917f65170SRuslan Bukin         err = OCSD_ERR_MEM;
55017f65170SRuslan Bukin 
55117f65170SRuslan Bukin     return err;
55217f65170SRuslan Bukin }
55317f65170SRuslan Bukin 
ocsd_check_and_add_mem_acc_mapper(const dcd_tree_handle_t handle,DecodeTree ** ppDT)55417f65170SRuslan Bukin static ocsd_err_t ocsd_check_and_add_mem_acc_mapper(const dcd_tree_handle_t handle, DecodeTree **ppDT)
55517f65170SRuslan Bukin {
55617f65170SRuslan Bukin     *ppDT = 0;
55717f65170SRuslan Bukin     if(handle == C_API_INVALID_TREE_HANDLE)
55817f65170SRuslan Bukin         return OCSD_ERR_INVALID_PARAM_VAL;
55917f65170SRuslan Bukin     *ppDT = static_cast<DecodeTree *>(handle);
56017f65170SRuslan Bukin     if(!(*ppDT)->hasMemAccMapper())
56117f65170SRuslan Bukin         return (*ppDT)->createMemAccMapper();
56217f65170SRuslan Bukin     return OCSD_OK;
56317f65170SRuslan Bukin }
56417f65170SRuslan Bukin 
56517f65170SRuslan Bukin /*******************************************************************************/
56617f65170SRuslan Bukin /* C API Helper objects                                                        */
56717f65170SRuslan Bukin /*******************************************************************************/
56817f65170SRuslan Bukin 
56917f65170SRuslan Bukin /****************** Generic trace element output callback function  ************/
GenTraceElemCBObj(FnTraceElemIn pCBFn,const void * p_context)57017f65170SRuslan Bukin GenTraceElemCBObj::GenTraceElemCBObj(FnTraceElemIn pCBFn, const void *p_context) :
57117f65170SRuslan Bukin     m_c_api_cb_fn(pCBFn),
57217f65170SRuslan Bukin     m_p_cb_context(p_context)
57317f65170SRuslan Bukin {
57417f65170SRuslan Bukin }
57517f65170SRuslan Bukin 
TraceElemIn(const ocsd_trc_index_t index_sop,const uint8_t trc_chan_id,const OcsdTraceElement & elem)57617f65170SRuslan Bukin ocsd_datapath_resp_t GenTraceElemCBObj::TraceElemIn(const ocsd_trc_index_t index_sop,
57717f65170SRuslan Bukin                                               const uint8_t trc_chan_id,
57817f65170SRuslan Bukin                                               const OcsdTraceElement &elem)
57917f65170SRuslan Bukin {
58017f65170SRuslan Bukin     return m_c_api_cb_fn(m_p_cb_context, index_sop, trc_chan_id, &elem);
58117f65170SRuslan Bukin }
58217f65170SRuslan Bukin 
58317f65170SRuslan Bukin /* End of File ocsd_c_api.cpp */
584