Updates to allow registration of a string print callback for the client to log data as part of the application.
Updates to allow client to specify raw trace printing using built in library printer.
Signed-off-by: Mike Leach mike.leach@linaro.org --- decoder/include/c_api/ocsd_c_api_types.h | 2 + decoder/include/c_api/opencsd_c_api.h | 23 +++++++++++ decoder/include/common/trc_frame_deformatter.h | 1 + decoder/source/c_api/ocsd_c_api.cpp | 42 ++++++++++++++++++++ decoder/source/c_api/ocsd_c_api_obj.h | 35 +++++++++++++++- decoder/source/ocsd_msg_logger.cpp | 15 ++++++- decoder/source/trc_frame_deformatter.cpp | 9 +++++ decoder/tests/source/c_api_pkt_print_test.c | 55 +++++++++++++++++++++++++- 8 files changed, 179 insertions(+), 3 deletions(-)
diff --git a/decoder/include/c_api/ocsd_c_api_types.h b/decoder/include/c_api/ocsd_c_api_types.h index be7316f..8354d00 100644 --- a/decoder/include/c_api/ocsd_c_api_types.h +++ b/decoder/include/c_api/ocsd_c_api_types.h @@ -89,6 +89,8 @@ typedef void (* FnDefPktDataMon)(const void *p_context, const uint32_t size, const uint8_t *p_data);
+/** function pointer tyee for library default logger output to allow client to print zero terminated output string */ +typedef void (* FnDefLoggerPrintStrCB)(const void *p_context, const char *psz_msg_str, const int str_len);
/** Callback interface type when attaching monitor/sink to packet processor */ typedef enum _ocsd_c_api_cb_types { diff --git a/decoder/include/c_api/opencsd_c_api.h b/decoder/include/c_api/opencsd_c_api.h index 2795955..4fc8379 100644 --- a/decoder/include/c_api/opencsd_c_api.h +++ b/decoder/include/c_api/opencsd_c_api.h @@ -339,6 +339,16 @@ OCSD_C_API ocsd_err_t ocsd_def_errlog_init(const ocsd_err_severity_t verbosity, OCSD_C_API ocsd_err_t ocsd_def_errlog_config_output(const int output_flags, const char *log_file_name);
/*! + * Configure the library default error logger to send all strings it is outputting back to the client + * to allow printing within the client application. This is in additional to any other log destinations + * set in ocsd_def_errlog_init(). + * + * @param *p_context : opaque context pointer + * @param p_str_print_cb : client callback function to "print" logstring. + */ +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); + +/*! * Print a message via the library output printer - if enabled. * * @param *msg : Message to output. @@ -386,6 +396,19 @@ OCSD_C_API void ocsd_gen_elem_init(ocsd_generic_trace_elem *p_pkt, const ocsd_ge
/** @}*/
+/** @name Library packet and data printer control API + @brief Allows client to use libraries packet and data printers to log packets etc rather than attach callbacks. +@{*/ + +/*! + * Set a raw frame printer on the trace frame demuxer. Allows inspection of raw trace data frames for debug. + * Prints via the default error logging mechanisms. + */ +OCSD_C_API ocsd_err_t ocsd_set_raw_frame_printer(const dcd_tree_handle_t handle, int flags); + +/** @}*/ + + /** @name Custom Decoder API functions
@{*/ diff --git a/decoder/include/common/trc_frame_deformatter.h b/decoder/include/common/trc_frame_deformatter.h index 90057ba..c874c82 100644 --- a/decoder/include/common/trc_frame_deformatter.h +++ b/decoder/include/common/trc_frame_deformatter.h @@ -75,6 +75,7 @@ public:
/* configuration - set operational mode for incoming stream (has FSYNCS etc) */ ocsd_err_t Configure(uint32_t cfg_flags); + const uint32_t getConfigFlags() const;
/* enable / disable ID streams - default as all enabled */ ocsd_err_t OutputFilterIDs(std::vector<uint8_t> &id_list, bool bEnable); diff --git a/decoder/source/c_api/ocsd_c_api.cpp b/decoder/source/c_api/ocsd_c_api.cpp index 5738798..9794ffc 100644 --- a/decoder/source/c_api/ocsd_c_api.cpp +++ b/decoder/source/c_api/ocsd_c_api.cpp @@ -64,6 +64,7 @@ static ocsd_err_t ocsd_check_and_add_mem_acc_mapper(const dcd_tree_handle_t hand /* keep a list of interface objects for a decode tree for later disposal */ typedef struct _lib_dt_data_list { std::vector<ITrcTypedBase *> cb_objs; + DefLogStrCBObj s_def_log_str_cb; } lib_dt_data_list;
/* map lists to handles */ @@ -272,6 +273,28 @@ OCSD_C_API ocsd_err_t ocsd_def_errlog_config_output(const int output_flags, cons return OCSD_ERR_NOT_INIT; }
+ +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) +{ + ocsdMsgLogger *pLogger = DecodeTree::getDefaultErrorLogger()->getOutputLogger(); + if (pLogger) + { + std::map<dcd_tree_handle_t, lib_dt_data_list *>::iterator it; + it = s_data_map.find(handle); + if (it != s_data_map.end()) + { + DefLogStrCBObj *pCBObj = &(it->second->s_def_log_str_cb); + pCBObj->setCBFn(p_context, p_str_print_cb); + pLogger->setStrOutFn(pCBObj); + int logOpts = pLogger->getLogOpts(); + logOpts |= (int)(ocsdMsgLogger::OUT_STR_CB); + pLogger->setLogOpts(logOpts); + return OCSD_OK; + } + } + return OCSD_ERR_NOT_INIT; +} + OCSD_C_API void ocsd_def_errlog_msgout(const char *msg) { ocsdMsgLogger *pLogger = DecodeTree::getDefaultErrorLogger()->getOutputLogger(); @@ -411,6 +434,25 @@ OCSD_C_API void ocsd_gen_elem_init(ocsd_generic_trace_elem *p_pkt, const ocsd_ge p_pkt->ptr_extended_data = 0; }
+OCSD_C_API ocsd_err_t ocsd_set_raw_frame_printer(const dcd_tree_handle_t handle, int flags) +{ + if (handle != C_API_INVALID_TREE_HANDLE) + { + RawFramePrinter *pPrinter = PktPrinterFact::createRawFramePrinter(); + if (pPrinter) + { + pPrinter->setMessageLogger((DecodeTree::getDefaultErrorLogger()->getOutputLogger())); + TraceFormatterFrameDecoder *pFrameDecoder = ((DecodeTree *)handle)->getFrameDeformatter(); + int cfgFlags = pFrameDecoder->getConfigFlags(); + cfgFlags |= ((uint32_t)flags & (OCSD_DFRMTR_PACKED_RAW_OUT | OCSD_DFRMTR_UNPACKED_RAW_OUT)); + pFrameDecoder->Configure(cfgFlags); + return pFrameDecoder->getTrcRawFrameAttachPt()->attach(pPrinter); + } + return OCSD_ERR_MEM; + } + return OCSD_ERR_NOT_INIT; +} + /*******************************************************************************/ /* C API local fns */ /*******************************************************************************/ diff --git a/decoder/source/c_api/ocsd_c_api_obj.h b/decoder/source/c_api/ocsd_c_api_obj.h index 617aa5c..42e8a7d 100644 --- a/decoder/source/c_api/ocsd_c_api_obj.h +++ b/decoder/source/c_api/ocsd_c_api_obj.h @@ -10,7 +10,7 @@
#include "c_api/ocsd_c_api_types.h" #include "interfaces/trc_gen_elem_in_i.h" - +#include "common/ocsd_msg_logger.h"
class TraceElemCBBase { @@ -144,6 +144,39 @@ private: const void *m_p_context; };
+/* handler for default string print CB object */ +class DefLogStrCBObj : public ocsdMsgLogStrOutI +{ +public: + DefLogStrCBObj() + { + m_c_api_cb_fn = 0; + m_p_context = 0; + }; + + virtual ~DefLogStrCBObj() + { + m_c_api_cb_fn = 0; + m_p_context = 0; + }; + + void setCBFn(const void *p_context, FnDefLoggerPrintStrCB pCBFn) + { + m_c_api_cb_fn = pCBFn; + m_p_context = p_context; + }; + + virtual void printOutStr(const std::string &outStr) + { + if(m_c_api_cb_fn) + m_c_api_cb_fn(m_p_context, outStr.c_str(), outStr.length()); + } + +private: + FnDefLoggerPrintStrCB m_c_api_cb_fn; + const void *m_p_context; +}; + #endif // ARM_OCSD_C_API_OBJ_H_INCLUDED
/* End of File ocsd_c_api_obj.h */ diff --git a/decoder/source/ocsd_msg_logger.cpp b/decoder/source/ocsd_msg_logger.cpp index 2ddf4ee..287edfa 100644 --- a/decoder/source/ocsd_msg_logger.cpp +++ b/decoder/source/ocsd_msg_logger.cpp @@ -58,14 +58,27 @@ void ocsdMsgLogger::setLogOpts(int logOpts)
void ocsdMsgLogger::setLogFileName(const char *fileName) { - m_logFileName = fileName; + if (fileName == 0) + m_logFileName = ""; + else + m_logFileName = fileName; + if(m_out_file.is_open()) m_out_file.close(); + + if (m_logFileName.length()) + m_outFlags |= (int)ocsdMsgLogger::OUT_FILE; + else + m_outFlags &= ~((int)ocsdMsgLogger::OUT_FILE); }
void ocsdMsgLogger::setStrOutFn(ocsdMsgLogStrOutI *p_IstrOut) { m_pOutStrI = p_IstrOut; + if (p_IstrOut) + m_outFlags |= (int)ocsdMsgLogger::OUT_STR_CB; + else + m_outFlags &= ~((int)ocsdMsgLogger::OUT_STR_CB); }
void ocsdMsgLogger::LogMsg(const std::string &msg) diff --git a/decoder/source/trc_frame_deformatter.cpp b/decoder/source/trc_frame_deformatter.cpp index dad84e5..b4f40a2 100644 --- a/decoder/source/trc_frame_deformatter.cpp +++ b/decoder/source/trc_frame_deformatter.cpp @@ -821,6 +821,15 @@ ocsd_err_t TraceFormatterFrameDecoder::Configure(uint32_t cfg_flags) return OCSD_OK; }
+const uint32_t TraceFormatterFrameDecoder::getConfigFlags() const +{ + uint32_t flags = 0; + if(m_pDecoder) + flags = m_pDecoder->m_cfgFlags; + return flags; +} + + /* enable / disable ID streams - default as all enabled */ ocsd_err_t TraceFormatterFrameDecoder::OutputFilterIDs(std::vector<uint8_t> &id_list, bool bEnable) { diff --git a/decoder/tests/source/c_api_pkt_print_test.c b/decoder/tests/source/c_api_pkt_print_test.c index ad84bdf..bc64d4c 100644 --- a/decoder/tests/source/c_api_pkt_print_test.c +++ b/decoder/tests/source/c_api_pkt_print_test.c @@ -102,6 +102,11 @@ static int test_extern_decoder = 0; /* test the external decoder infrastructure. static ocsd_extern_dcd_fact_t *p_ext_fact; /* external decoder factory */ #define EXT_DCD_NAME "ext_echo"
+/* raw packet printing test */ +static int frame_raw_unpacked = 0; +static int frame_raw_packed = 0; +static int test_printstr = 0; + /* Process command line options - choose the operation to use for the test. */ static int process_cmd_line(int argc, char *argv[]) { @@ -157,6 +162,18 @@ static int process_cmd_line(int argc, char *argv[]) { test_extern_decoder = 1; } + else if (strcmp(argv[idx], "-raw") == 0) + { + frame_raw_unpacked = 1; + } + else if (strcmp(argv[idx], "-raw_packed") == 0) + { + frame_raw_packed = 1; + } + else if (strcmp(argv[idx], "-test_printstr") == 0) + { + test_printstr = 1; + } else if(strcmp(argv[idx],"-help") == 0) { return -1; @@ -173,6 +190,7 @@ static void print_cmd_line_help() printf("Usage:\n-etmv3|-stm|-ptm|-extern : choose protocol (one only, default etmv4)\n"); printf("-id <ID> : decode source for id <ID> (default 0x10)\n"); printf("-decode | -decode_only : full decode + trace packets / full decode packets only (default trace packets only)\n"); + printf("-raw / -raw_packed: print raw unpacked / packed data;\n"); printf("-test_region_file | -test_cb : mem accessor - test multi region file API | test callback API (default single memory file)\n\n"); }
@@ -662,6 +680,33 @@ static ocsd_err_t create_decoder_extern(dcd_tree_handle_t dcd_tree_h) return create_generic_decoder(dcd_tree_h, EXT_DCD_NAME, (void *)&trace_cfg_ext, 0); }
+static ocsd_err_t attach_raw_printers(dcd_tree_handle_t dcd_tree_h) +{ + ocsd_err_t err = OCSD_OK; + int flags = 0; + if (frame_raw_unpacked) + flags |= OCSD_DFRMTR_UNPACKED_RAW_OUT; + if (frame_raw_packed) + flags |= OCSD_DFRMTR_PACKED_RAW_OUT; + if (flags) + { + err = ocsd_set_raw_frame_printer(dcd_tree_h, flags); + } + return err; +} + +static void print_output_str(const void *p_context, const char *psz_msg_str, const int str_len) +{ + printf("** CUST_PRNTSTR: %s", psz_msg_str); +} + +static ocsd_err_t test_printstr_cb(dcd_tree_handle_t dcd_tree_h) +{ + ocsd_err_t err = OCSD_OK; + if (test_printstr) + err = ocsd_def_errlog_set_strprint_cb(dcd_tree_h, 0, print_output_str); + return err; +} /************************************************************************/
ocsd_err_t register_extern_decoder() @@ -781,6 +826,15 @@ int process_trace_data(FILE *pf) /* attach the generic trace element output callback */ ret = ocsd_dt_set_gen_elem_outfn(dcdtree_handle,gen_trace_elem_print,0);
+ + /* raw print and str print cb options tested in their init functions */ + if (ret == OCSD_OK) + ret = test_printstr_cb(dcdtree_handle); + + if (ret == OCSD_OK) + ret = attach_raw_printers(dcdtree_handle); + + /* now push the trace data through the packet processor */ while(!feof(pf) && (ret == OCSD_OK)) { @@ -855,7 +909,6 @@ int main(int argc, char *argv[]) /* print sign-on message in log */ sprintf(message, "C-API packet print test\nLibrary Version %s\n\n",ocsd_get_version_str()); ocsd_def_errlog_msgout(message); -
/* process the trace data */ if(ret == 0)