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_gen_elem_init(ocsd_generic_trace_elem * p_pkt,const ocsd_gen_trc_elem_t elem_type)465 OCSD_C_API void ocsd_gen_elem_init(ocsd_generic_trace_elem *p_pkt, const ocsd_gen_trc_elem_t elem_type)
466 {
467 p_pkt->elem_type = elem_type;
468 p_pkt->flag_bits = 0;
469 p_pkt->ptr_extended_data = 0;
470 }
471
ocsd_dt_set_raw_frame_printer(const dcd_tree_handle_t handle,int flags)472 OCSD_C_API ocsd_err_t ocsd_dt_set_raw_frame_printer(const dcd_tree_handle_t handle, int flags)
473 {
474 if (handle != C_API_INVALID_TREE_HANDLE)
475 return ((DecodeTree *)handle)->addRawFramePrinter(0, (uint32_t)flags);
476 return OCSD_ERR_NOT_INIT;
477 }
478
ocsd_dt_set_gen_elem_printer(const dcd_tree_handle_t handle)479 OCSD_C_API ocsd_err_t ocsd_dt_set_gen_elem_printer(const dcd_tree_handle_t handle)
480 {
481 if (handle != C_API_INVALID_TREE_HANDLE)
482 return ((DecodeTree *)handle)->addGenElemPrinter(0);
483 return OCSD_ERR_NOT_INIT;
484 }
485
ocsd_dt_set_pkt_protocol_printer(const dcd_tree_handle_t handle,uint8_t cs_id,int monitor)486 OCSD_C_API ocsd_err_t ocsd_dt_set_pkt_protocol_printer(const dcd_tree_handle_t handle, uint8_t cs_id, int monitor)
487 {
488 ocsd_err_t err = OCSD_ERR_NOT_INIT;
489 if (handle != C_API_INVALID_TREE_HANDLE)
490 {
491 DecodeTree *p_tree = (DecodeTree *)handle;
492 err = p_tree->addPacketPrinter(cs_id, (bool)(monitor != 0), 0);
493 }
494 return err;
495 }
496
ocsd_err_str(const ocsd_err_t err,char * buffer,const int buffer_size)497 OCSD_C_API void ocsd_err_str(const ocsd_err_t err, char *buffer, const int buffer_size)
498 {
499 std::string err_str;
500 err_str = ocsdError::getErrorString(ocsdError(OCSD_ERR_SEV_ERROR, err));
501 strncpy(buffer, err_str.c_str(), buffer_size - 1);
502 buffer[buffer_size - 1] = 0;
503 }
504
ocsd_get_last_err(ocsd_trc_index_t * index,uint8_t * chan_id,char * message,const int message_len)505 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)
506 {
507 ocsdError *p_err;
508 ocsd_err_t err = OCSD_OK;
509 std::string err_str;
510
511 p_err = DecodeTree::getDefaultErrorLogger()->GetLastError();
512 if (p_err)
513 {
514 *index = p_err->getErrorIndex();
515 *chan_id = p_err->getErrorChanID();
516 err_str = p_err->getErrorString(ocsdError(p_err));
517 strncpy(message, err_str.c_str(), message_len - 1);
518 message[message_len - 1] = 0;
519 err = p_err->getErrorCode();
520 }
521 else
522 {
523 message[0] = 0;
524 *index = OCSD_BAD_TRC_INDEX;
525 *chan_id = OCSD_BAD_CS_SRC_ID;
526 }
527 return err;
528 }
529
530 /*******************************************************************************/
531 /* C API local fns */
532 /*******************************************************************************/
ocsd_create_pkt_sink_cb(ocsd_trace_protocol_t protocol,FnDefPktDataIn pPktInFn,const void * p_context,ITrcTypedBase ** ppCBObj)533 static ocsd_err_t ocsd_create_pkt_sink_cb(ocsd_trace_protocol_t protocol, FnDefPktDataIn pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj )
534 {
535 ocsd_err_t err = OCSD_OK;
536 *ppCBObj = 0;
537
538 switch(protocol)
539 {
540 case OCSD_PROTOCOL_ETMV4I:
541 *ppCBObj = new (std::nothrow) PktCBObj<EtmV4ITrcPacket>(pPktInFn,p_context);
542 break;
543
544 case OCSD_PROTOCOL_ETMV3:
545 *ppCBObj = new (std::nothrow) PktCBObj<EtmV3TrcPacket>(pPktInFn,p_context);
546 break;
547
548 case OCSD_PROTOCOL_PTM:
549 *ppCBObj = new (std::nothrow) PktCBObj<PtmTrcPacket>(pPktInFn,p_context);
550 break;
551
552 case OCSD_PROTOCOL_STM:
553 *ppCBObj = new (std::nothrow) PktCBObj<StmTrcPacket>(pPktInFn,p_context);
554 break;
555
556 default:
557 if ((protocol >= OCSD_PROTOCOL_CUSTOM_0) && (protocol < OCSD_PROTOCOL_END))
558 {
559 *ppCBObj = new (std::nothrow) PktCBObj<void>(pPktInFn, p_context);
560 }
561 else
562 err = OCSD_ERR_NO_PROTOCOL;
563 break;
564 }
565
566 if((*ppCBObj == 0) && (err == OCSD_OK))
567 err = OCSD_ERR_MEM;
568
569 return err;
570 }
571
ocsd_create_pkt_mon_cb(ocsd_trace_protocol_t protocol,FnDefPktDataMon pPktInFn,const void * p_context,ITrcTypedBase ** ppCBObj)572 static ocsd_err_t ocsd_create_pkt_mon_cb(ocsd_trace_protocol_t protocol, FnDefPktDataMon pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj )
573 {
574 ocsd_err_t err = OCSD_OK;
575 *ppCBObj = 0;
576
577 switch(protocol)
578 {
579 case OCSD_PROTOCOL_ETMV4I:
580 *ppCBObj = new (std::nothrow) PktMonCBObj<EtmV4ITrcPacket>(pPktInFn,p_context);
581 break;
582
583 case OCSD_PROTOCOL_ETMV3:
584 *ppCBObj = new (std::nothrow) PktMonCBObj<EtmV3TrcPacket>(pPktInFn,p_context);
585 break;
586
587 case OCSD_PROTOCOL_PTM:
588 *ppCBObj = new (std::nothrow) PktMonCBObj<PtmTrcPacket>(pPktInFn,p_context);
589 break;
590
591 case OCSD_PROTOCOL_STM:
592 *ppCBObj = new (std::nothrow) PktMonCBObj<StmTrcPacket>(pPktInFn,p_context);
593 break;
594
595 default:
596 if ((protocol >= OCSD_PROTOCOL_CUSTOM_0) && (protocol < OCSD_PROTOCOL_END))
597 {
598 *ppCBObj = new (std::nothrow) PktMonCBObj<void>(pPktInFn, p_context);
599 }
600 else
601 err = OCSD_ERR_NO_PROTOCOL;
602 break;
603 }
604
605 if((*ppCBObj == 0) && (err == OCSD_OK))
606 err = OCSD_ERR_MEM;
607
608 return err;
609 }
610
ocsd_check_and_add_mem_acc_mapper(const dcd_tree_handle_t handle,DecodeTree ** ppDT)611 static ocsd_err_t ocsd_check_and_add_mem_acc_mapper(const dcd_tree_handle_t handle, DecodeTree **ppDT)
612 {
613 *ppDT = 0;
614 if(handle == C_API_INVALID_TREE_HANDLE)
615 return OCSD_ERR_INVALID_PARAM_VAL;
616 *ppDT = static_cast<DecodeTree *>(handle);
617 if(!(*ppDT)->hasMemAccMapper())
618 return (*ppDT)->createMemAccMapper();
619 return OCSD_OK;
620 }
621
622 /*******************************************************************************/
623 /* C API Helper objects */
624 /*******************************************************************************/
625
626 /****************** Generic trace element output callback function ************/
GenTraceElemCBObj(FnTraceElemIn pCBFn,const void * p_context)627 GenTraceElemCBObj::GenTraceElemCBObj(FnTraceElemIn pCBFn, const void *p_context) :
628 m_c_api_cb_fn(pCBFn),
629 m_p_cb_context(p_context)
630 {
631 }
632
TraceElemIn(const ocsd_trc_index_t index_sop,const uint8_t trc_chan_id,const OcsdTraceElement & elem)633 ocsd_datapath_resp_t GenTraceElemCBObj::TraceElemIn(const ocsd_trc_index_t index_sop,
634 const uint8_t trc_chan_id,
635 const OcsdTraceElement &elem)
636 {
637 return m_c_api_cb_fn(m_p_cb_context, index_sop, trc_chan_id, &elem);
638 }
639
640 /* End of File ocsd_c_api.cpp */
641