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>
48namespace std { const nothrow_t nothrow = nothrow_t(); }
49#endif
50#endif
51
52/*******************************************************************************/
53/* C API internal helper function declarations                                 */
54/*******************************************************************************/
55
56static ocsd_err_t ocsd_create_pkt_sink_cb(ocsd_trace_protocol_t protocol, FnDefPktDataIn pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj );
57static ocsd_err_t ocsd_create_pkt_mon_cb(ocsd_trace_protocol_t protocol, FnDefPktDataMon pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj );
58static 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 */
65typedef 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 */
71static 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 */
78OCSD_C_API uint32_t ocsd_get_version(void)
79{
80    return ocsdVersion::vers_num();
81}
82
83/** Get library version string */
84OCSD_C_API const char * ocsd_get_version_str(void)
85{
86    return ocsdVersion::vers_str();
87}
88
89
90/*** Decode tree creation etc. */
91
92OCSD_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
112OCSD_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
142OCSD_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
157OCSD_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
184OCSD_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
190OCSD_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
237OCSD_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
246OCSD_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 */
255OCSD_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    if(pCBObj)
260    {
261        ((DecodeTree *)handle)->setGenTraceElemOutI(pCBObj);
262        return OCSD_OK;
263    }
264    return OCSD_ERR_MEM;
265}
266
267
268/*** Default error logging */
269
270OCSD_C_API ocsd_err_t ocsd_def_errlog_init(const ocsd_err_severity_t verbosity, const int create_output_logger)
271{
272    if(DecodeTree::getDefaultErrorLogger()->initErrorLogger(verbosity,(bool)(create_output_logger != 0)))
273        return OCSD_OK;
274    return OCSD_ERR_NOT_INIT;
275}
276
277OCSD_C_API ocsd_err_t ocsd_def_errlog_config_output(const int output_flags, const char *log_file_name)
278{
279    ocsdMsgLogger *pLogger = DecodeTree::getDefaultErrorLogger()->getOutputLogger();
280    if(pLogger)
281    {
282        pLogger->setLogOpts(output_flags & C_API_MSGLOGOUT_MASK);
283        if(log_file_name != NULL)
284        {
285            pLogger->setLogFileName(log_file_name);
286        }
287        return OCSD_OK;
288    }
289    return OCSD_ERR_NOT_INIT;
290}
291
292
293OCSD_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)
294{
295    ocsdMsgLogger *pLogger = DecodeTree::getDefaultErrorLogger()->getOutputLogger();
296    if (pLogger)
297    {
298        std::map<dcd_tree_handle_t, lib_dt_data_list *>::iterator it;
299        it = s_data_map.find(handle);
300        if (it != s_data_map.end())
301        {
302            DefLogStrCBObj *pCBObj = &(it->second->s_def_log_str_cb);
303            pCBObj->setCBFn(p_context, p_str_print_cb);
304            pLogger->setStrOutFn(pCBObj);
305            int logOpts = pLogger->getLogOpts();
306            logOpts |= (int)(ocsdMsgLogger::OUT_STR_CB);
307            pLogger->setLogOpts(logOpts);
308            return OCSD_OK;
309        }
310    }
311    return OCSD_ERR_NOT_INIT;
312}
313
314OCSD_C_API void ocsd_def_errlog_msgout(const char *msg)
315{
316    ocsdMsgLogger *pLogger = DecodeTree::getDefaultErrorLogger()->getOutputLogger();
317    if(pLogger)
318        pLogger->LogMsg(msg);
319}
320
321/*** Convert packet to string */
322
323OCSD_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)
324{
325    ocsd_err_t err = OCSD_OK;
326    if((buffer == NULL) || (buffer_size < 2))
327        return OCSD_ERR_INVALID_PARAM_VAL;
328
329    std::string pktStr = "";
330    buffer[0] = 0;
331
332    switch(pkt_protocol)
333    {
334    case OCSD_PROTOCOL_ETMV4I:
335        trcPrintElemToString<EtmV4ITrcPacket,ocsd_etmv4_i_pkt>(p_pkt, pktStr);
336        break;
337
338    case OCSD_PROTOCOL_ETMV3:
339        trcPrintElemToString<EtmV3TrcPacket,ocsd_etmv3_pkt>(p_pkt, pktStr);
340        break;
341
342    case OCSD_PROTOCOL_STM:
343        trcPrintElemToString<StmTrcPacket,ocsd_stm_pkt>(p_pkt, pktStr);
344        break;
345
346    case OCSD_PROTOCOL_PTM:
347        trcPrintElemToString<PtmTrcPacket,ocsd_ptm_pkt>(p_pkt, pktStr);
348        break;
349
350    default:
351        if (OCSD_PROTOCOL_IS_CUSTOM(pkt_protocol))
352            err = ocsd_cust_protocol_to_str(pkt_protocol, p_pkt, buffer, buffer_size);
353        else
354            err = OCSD_ERR_NO_PROTOCOL;
355        break;
356    }
357
358    if(pktStr.size() > 0)
359    {
360        strncpy(buffer,pktStr.c_str(),buffer_size-1);
361        buffer[buffer_size-1] = 0;
362    }
363    return err;
364}
365
366OCSD_C_API ocsd_err_t ocsd_gen_elem_str(const ocsd_generic_trace_elem *p_pkt, char *buffer, const int buffer_size)
367{
368    ocsd_err_t err = OCSD_OK;
369    if((buffer == NULL) || (buffer_size < 2))
370        return OCSD_ERR_INVALID_PARAM_VAL;
371    std::string str;
372    trcPrintElemToString<OcsdTraceElement,ocsd_generic_trace_elem>(p_pkt,str);
373    if(str.size() > 0)
374    {
375        strncpy(buffer,str.c_str(),buffer_size -1);
376        buffer[buffer_size-1] = 0;
377    }
378    return err;
379}
380
381/*** Decode tree -- memory accessor control */
382
383OCSD_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)
384{
385    ocsd_err_t err = OCSD_OK;
386    DecodeTree *pDT;
387    err = ocsd_check_and_add_mem_acc_mapper(handle,&pDT);
388    if(err == OCSD_OK)
389        err = pDT->addBinFileMemAcc(address,mem_space,filepath);
390    return err;
391}
392
393OCSD_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)
394{
395    ocsd_err_t err = OCSD_OK;
396    DecodeTree *pDT;
397    err = ocsd_check_and_add_mem_acc_mapper(handle,&pDT);
398    if(err == OCSD_OK)
399        err = pDT->addBinFileRegionMemAcc(region_array,num_regions,mem_space,filepath);
400    return err;
401}
402
403OCSD_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)
404{
405    ocsd_err_t err = OCSD_OK;
406    DecodeTree *pDT;
407    err = ocsd_check_and_add_mem_acc_mapper(handle,&pDT);
408    if(err == OCSD_OK)
409        err = pDT->addBufferMemAcc(address,mem_space,p_mem_buffer,mem_length);
410    return err;
411}
412
413OCSD_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)
414{
415    ocsd_err_t err = OCSD_OK;
416    DecodeTree *pDT;
417    err = ocsd_check_and_add_mem_acc_mapper(handle,&pDT);
418    if(err == OCSD_OK)
419        err = pDT->addCallbackMemAcc(st_address,en_address,mem_space,p_cb_func,p_context);
420    return err;
421}
422
423OCSD_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)
424{
425    ocsd_err_t err = OCSD_OK;
426    DecodeTree *pDT;
427    err = ocsd_check_and_add_mem_acc_mapper(handle, &pDT);
428    if (err == OCSD_OK)
429        err = pDT->addCallbackIDMemAcc(st_address, en_address, mem_space, p_cb_func, p_context);
430    return err;
431}
432
433
434OCSD_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)
435{
436    ocsd_err_t err = OCSD_OK;
437
438    if(handle != C_API_INVALID_TREE_HANDLE)
439    {
440        DecodeTree *pDT = static_cast<DecodeTree *>(handle);
441        err = pDT->removeMemAccByAddress(st_address,mem_space);
442    }
443    else
444        err = OCSD_ERR_INVALID_PARAM_VAL;
445    return err;
446}
447
448OCSD_C_API void ocsd_tl_log_mapped_mem_ranges(const dcd_tree_handle_t handle)
449{
450    if(handle != C_API_INVALID_TREE_HANDLE)
451    {
452        DecodeTree *pDT = static_cast<DecodeTree *>(handle);
453        pDT->logMappedRanges();
454    }
455}
456
457OCSD_C_API void ocsd_gen_elem_init(ocsd_generic_trace_elem *p_pkt, const ocsd_gen_trc_elem_t elem_type)
458{
459    p_pkt->elem_type = elem_type;
460    p_pkt->flag_bits = 0;
461    p_pkt->ptr_extended_data = 0;
462}
463
464OCSD_C_API ocsd_err_t ocsd_dt_set_raw_frame_printer(const dcd_tree_handle_t handle, int flags)
465{
466    if (handle != C_API_INVALID_TREE_HANDLE)
467        return ((DecodeTree *)handle)->addRawFramePrinter(0, (uint32_t)flags);
468    return OCSD_ERR_NOT_INIT;
469}
470
471OCSD_C_API ocsd_err_t ocsd_dt_set_gen_elem_printer(const dcd_tree_handle_t handle)
472{
473    if (handle != C_API_INVALID_TREE_HANDLE)
474        return ((DecodeTree *)handle)->addGenElemPrinter(0);
475    return OCSD_ERR_NOT_INIT;
476}
477
478OCSD_C_API ocsd_err_t ocsd_dt_set_pkt_protocol_printer(const dcd_tree_handle_t handle, uint8_t cs_id, int monitor)
479{
480    ocsd_err_t err = OCSD_ERR_NOT_INIT;
481    if (handle != C_API_INVALID_TREE_HANDLE)
482    {
483        DecodeTree *p_tree = (DecodeTree *)handle;
484        err = p_tree->addPacketPrinter(cs_id, (bool)(monitor != 0), 0);
485    }
486    return err;
487}
488
489OCSD_C_API void ocsd_err_str(const ocsd_err_t err, char *buffer, const int buffer_size)
490{
491    std::string err_str;
492    err_str = ocsdError::getErrorString(ocsdError(OCSD_ERR_SEV_ERROR, err));
493    strncpy(buffer, err_str.c_str(), buffer_size - 1);
494    buffer[buffer_size - 1] = 0;
495}
496
497OCSD_C_API ocsd_err_t ocsd_get_last_err(ocsd_trc_index_t *index, uint8_t *chan_id, char *message, const int message_len)
498{
499    ocsdError *p_err;
500    ocsd_err_t err = OCSD_OK;
501    std::string err_str;
502
503    p_err = DecodeTree::getDefaultErrorLogger()->GetLastError();
504    if (p_err)
505    {
506        *index = p_err->getErrorIndex();
507        *chan_id = p_err->getErrorChanID();
508        err_str = p_err->getErrorString(ocsdError(p_err));
509        strncpy(message, err_str.c_str(), message_len - 1);
510        message[message_len - 1] = 0;
511        err = p_err->getErrorCode();
512    }
513    else
514    {
515        message[0] = 0;
516        *index = OCSD_BAD_TRC_INDEX;
517        *chan_id = OCSD_BAD_CS_SRC_ID;
518    }
519    return err;
520}
521
522/*******************************************************************************/
523/* C API local fns                                                             */
524/*******************************************************************************/
525static ocsd_err_t ocsd_create_pkt_sink_cb(ocsd_trace_protocol_t protocol,  FnDefPktDataIn pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj )
526{
527    ocsd_err_t err = OCSD_OK;
528    *ppCBObj = 0;
529
530    switch(protocol)
531    {
532    case OCSD_PROTOCOL_ETMV4I:
533        *ppCBObj = new (std::nothrow) PktCBObj<EtmV4ITrcPacket>(pPktInFn,p_context);
534        break;
535
536    case OCSD_PROTOCOL_ETMV3:
537        *ppCBObj = new (std::nothrow) PktCBObj<EtmV3TrcPacket>(pPktInFn,p_context);
538        break;
539
540    case OCSD_PROTOCOL_PTM:
541        *ppCBObj = new (std::nothrow) PktCBObj<PtmTrcPacket>(pPktInFn,p_context);
542        break;
543
544    case OCSD_PROTOCOL_STM:
545        *ppCBObj = new (std::nothrow) PktCBObj<StmTrcPacket>(pPktInFn,p_context);
546        break;
547
548    default:
549        if ((protocol >= OCSD_PROTOCOL_CUSTOM_0) && (protocol < OCSD_PROTOCOL_END))
550        {
551            *ppCBObj = new (std::nothrow) PktCBObj<void>(pPktInFn, p_context);
552        }
553        else
554            err = OCSD_ERR_NO_PROTOCOL;
555        break;
556    }
557
558    if((*ppCBObj == 0) && (err == OCSD_OK))
559        err = OCSD_ERR_MEM;
560
561    return err;
562}
563
564static ocsd_err_t ocsd_create_pkt_mon_cb(ocsd_trace_protocol_t protocol, FnDefPktDataMon pPktInFn, const void *p_context, ITrcTypedBase **ppCBObj )
565{
566    ocsd_err_t err = OCSD_OK;
567    *ppCBObj = 0;
568
569    switch(protocol)
570    {
571    case OCSD_PROTOCOL_ETMV4I:
572        *ppCBObj = new (std::nothrow) PktMonCBObj<EtmV4ITrcPacket>(pPktInFn,p_context);
573        break;
574
575    case OCSD_PROTOCOL_ETMV3:
576        *ppCBObj = new (std::nothrow) PktMonCBObj<EtmV3TrcPacket>(pPktInFn,p_context);
577        break;
578
579    case OCSD_PROTOCOL_PTM:
580        *ppCBObj = new (std::nothrow) PktMonCBObj<PtmTrcPacket>(pPktInFn,p_context);
581        break;
582
583    case OCSD_PROTOCOL_STM:
584        *ppCBObj = new (std::nothrow) PktMonCBObj<StmTrcPacket>(pPktInFn,p_context);
585        break;
586
587    default:
588        if ((protocol >= OCSD_PROTOCOL_CUSTOM_0) && (protocol < OCSD_PROTOCOL_END))
589        {
590            *ppCBObj = new (std::nothrow) PktMonCBObj<void>(pPktInFn, p_context);
591        }
592        else
593            err = OCSD_ERR_NO_PROTOCOL;
594        break;
595    }
596
597    if((*ppCBObj == 0) && (err == OCSD_OK))
598        err = OCSD_ERR_MEM;
599
600    return err;
601}
602
603static ocsd_err_t ocsd_check_and_add_mem_acc_mapper(const dcd_tree_handle_t handle, DecodeTree **ppDT)
604{
605    *ppDT = 0;
606    if(handle == C_API_INVALID_TREE_HANDLE)
607        return OCSD_ERR_INVALID_PARAM_VAL;
608    *ppDT = static_cast<DecodeTree *>(handle);
609    if(!(*ppDT)->hasMemAccMapper())
610        return (*ppDT)->createMemAccMapper();
611    return OCSD_OK;
612}
613
614/*******************************************************************************/
615/* C API Helper objects                                                        */
616/*******************************************************************************/
617
618/****************** Generic trace element output callback function  ************/
619GenTraceElemCBObj::GenTraceElemCBObj(FnTraceElemIn pCBFn, const void *p_context) :
620    m_c_api_cb_fn(pCBFn),
621    m_p_cb_context(p_context)
622{
623}
624
625ocsd_datapath_resp_t GenTraceElemCBObj::TraceElemIn(const ocsd_trc_index_t index_sop,
626                                              const uint8_t trc_chan_id,
627                                              const OcsdTraceElement &elem)
628{
629    return m_c_api_cb_fn(m_p_cb_context, index_sop, trc_chan_id, &elem);
630}
631
632/* End of File ocsd_c_api.cpp */
633