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