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