OpenCSD - CoreSight Trace Decode Library  1.3.3
trc_pkt_proc_base.h
Go to the documentation of this file.
1 
9 /*
10  * Redistribution and use in source and binary forms, with or without modification,
11  * are permitted provided that the following conditions are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright notice,
14  * this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright notice,
17  * this list of conditions and the following disclaimer in the documentation
18  * and/or other materials provided with the distribution.
19  *
20  * 3. Neither the name of the copyright holder nor the names of its contributors
21  * may be used to endorse or promote products derived from this software without
22  * specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #ifndef ARM_TRC_PKT_PROC_BASE_H_INCLUDED
37 #define ARM_TRC_PKT_PROC_BASE_H_INCLUDED
38 
43 
44 #include "trc_component.h"
45 #include "comp_attach_pt_t.h"
47 
65 class TrcPktProcI : public TraceComponent, public ITrcDataIn
66 {
67 public:
68  TrcPktProcI(const char *component_name);
69  TrcPktProcI(const char *component_name, int instIDNum);
70  virtual ~TrcPktProcI() {};
71 
75  const ocsd_trc_index_t index,
76  const uint32_t dataBlockSize,
77  const uint8_t *pDataBlock,
78  uint32_t *numBytesProcessed) = 0;
79 
80  virtual ocsd_err_t getStatsBlock(ocsd_decode_stats_t **pp_stats) = 0;
81  virtual void resetStats() = 0;
82 protected:
83 
84  /* implementation packet processing interface */
85 
88  const uint32_t dataBlockSize,
89  const uint8_t *pDataBlock,
90  uint32_t *numBytesProcessed) = 0;
91 
92  virtual ocsd_datapath_resp_t onEOT() = 0;
93  virtual ocsd_datapath_resp_t onReset() = 0;
94  virtual ocsd_datapath_resp_t onFlush() = 0;
95  virtual ocsd_err_t onProtocolConfig() = 0;
96  virtual const bool isBadPacket() const = 0;
97 };
98 
99 inline TrcPktProcI::TrcPktProcI(const char *component_name) :
100  TraceComponent(component_name)
101 {
102 }
103 
104 inline TrcPktProcI::TrcPktProcI(const char *component_name, int instIDNum) :
105  TraceComponent(component_name,instIDNum)
106 {
107 }
108 
125 template <class P, class Pt, class Pc>
127 {
128 public:
129  TrcPktProcBase(const char *component_name);
130  TrcPktProcBase(const char *component_name, int instIDNum);
131  virtual ~TrcPktProcBase();
132 
139  const ocsd_trc_index_t index,
140  const uint32_t dataBlockSize,
141  const uint8_t *pDataBlock,
142  uint32_t *numBytesProcessed);
143 
144 
145 /* component attachment points */
146 
151 
154 
155 /* protocol configuration */
157  virtual ocsd_err_t setProtocolConfig(const Pc *config);
159  virtual const Pc *getProtocolConfig() const { return m_config; };
160 
161 /* stats block access - derived class must init stats for the block to be returned. */
163  virtual void resetStats(); /* reset the counts - operates separately from decoder reset. */
164 
165 protected:
166 
167  /* data output functions */
169 
171  const P *pkt,
172  const uint32_t size,
173  const uint8_t *p_data);
174 
175  void indexPacket(const ocsd_trc_index_t index_sop, const Pt *packet_type);
176 
177  ocsd_datapath_resp_t outputOnAllInterfaces(const ocsd_trc_index_t index_sop, const P *pkt, const Pt *pkt_type, std::vector<uint8_t> &pktdata);
178 
179  ocsd_datapath_resp_t outputOnAllInterfaces(const ocsd_trc_index_t index_sop, const P *pkt, const Pt *pkt_type, const uint8_t *pktdata, uint32_t pktlen);
180 
184  const bool hasRawMon() const;
185 
186  /* the protocol configuration */
187  const Pc *m_config;
188 
189  void ClearConfigObj(); // remove our copy of the config
190 
191  const bool checkInit(); // return true if init (configured and at least one output sink attached), false otherwise.
192 
193  /* stats block updates - called by derived protocol specific decoder */
194  void statsAddTotalCount(const uint64_t count) { m_stats.channel_total += count; };
195  void statsAddUnsyncCount(const uint64_t count) { m_stats.channel_unsynced += count; };
196  void statsAddBadSeqCount(const uint32_t count) { m_stats.bad_sequence_errs += count; };
197  void statsAddBadHdrCount(const uint32_t count) { m_stats.bad_header_errs += count; };
198  void statsInit() { m_stats_init = true; }; /* mark stats as in use */
199 
200 
201 private:
202  /* decode control */
203  ocsd_datapath_resp_t Reset(const ocsd_trc_index_t index);
204  ocsd_datapath_resp_t Flush();
205  ocsd_datapath_resp_t EOT();
206 
207  componentAttachPt<IPktDataIn<P>> m_pkt_out_i;
208  componentAttachPt<IPktRawDataMon<P>> m_pkt_raw_mon_i;
209 
210  componentAttachPt<ITrcPktIndexer<Pt>> m_pkt_indexer_i;
211 
212  bool m_b_is_init;
213 
214  /* decode statistics block */
215  ocsd_decode_stats_t m_stats;
216  bool m_stats_init; /*< true if the specific decoder is using the stats */
217 
218 };
219 
220 template<class P,class Pt, class Pc> TrcPktProcBase<P, Pt, Pc>::TrcPktProcBase(const char *component_name) :
221  TrcPktProcI(component_name),
222  m_config(0),
223  m_b_is_init(false),
224  m_stats_init(false)
225 {
226  resetStats();
227 }
228 
229 template<class P,class Pt, class Pc> TrcPktProcBase<P, Pt, Pc>::TrcPktProcBase(const char *component_name, int instIDNum) :
230  TrcPktProcI(component_name, instIDNum),
231  m_config(0),
232  m_b_is_init(false),
233  m_stats_init(false)
234 {
235  resetStats();
236 }
237 
238 template<class P,class Pt, class Pc> TrcPktProcBase<P, Pt, Pc>::~TrcPktProcBase()
239 {
240  ClearConfigObj();
241 }
242 
244  const ocsd_trc_index_t index,
245  const uint32_t dataBlockSize,
246  const uint8_t *pDataBlock,
247  uint32_t *numBytesProcessed)
248 {
250 
251  switch(op)
252  {
253  case OCSD_OP_DATA:
254  if((dataBlockSize == 0) || (pDataBlock == 0) || (numBytesProcessed == 0))
255  {
256  if(numBytesProcessed)
257  *numBytesProcessed = 0; // ensure processed bytes value set to 0.
258  LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_INVALID_PARAM_VAL,"Packet Processor: Zero length data block or NULL pointer error\n"));
260  }
261  else
262  resp = processData(index,dataBlockSize,pDataBlock,numBytesProcessed);
263  break;
264 
265  case OCSD_OP_EOT:
266  resp = EOT();
267  break;
268 
269  case OCSD_OP_FLUSH:
270  resp = Flush();
271  break;
272 
273  case OCSD_OP_RESET:
274  resp = Reset(index);
275  break;
276 
277  default:
278  LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_INVALID_PARAM_VAL,"Packet Processor : Unknown Datapath operation\n"));
280  break;
281  }
282  return resp;
283 }
284 
285 
286 template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::Reset(const ocsd_trc_index_t index)
287 {
289 
290  // reset the trace decoder attachment on main data path.
291  if(m_pkt_out_i.hasAttachedAndEnabled())
292  resp = m_pkt_out_i.first()->PacketDataIn(OCSD_OP_RESET,index,0);
293 
294  // reset the packet processor implmentation
295  if(!OCSD_DATA_RESP_IS_FATAL(resp))
296  resp = onReset();
297 
298  // packet monitor
299  if(m_pkt_raw_mon_i.hasAttachedAndEnabled())
300  m_pkt_raw_mon_i.first()->RawPacketDataMon(OCSD_OP_RESET,index,0,0,0);
301 
302  return resp;
303 }
304 
305 template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::Flush()
306 {
309 
310  // the trace decoder attachment on main data path.
311  if(m_pkt_out_i.hasAttachedAndEnabled())
312  resp = m_pkt_out_i.first()->PacketDataIn(OCSD_OP_FLUSH,0,0); // flush up the data path first.
313 
314  // if the connected components are flushed, not flush this one.
315  if(OCSD_DATA_RESP_IS_CONT(resp))
316  resplocal = onFlush(); // local flush
317 
318  return (resplocal > resp) ? resplocal : resp;
319 }
320 
321 template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::EOT()
322 {
323  ocsd_datapath_resp_t resp = onEOT(); // local EOT - mark any part packet as incomplete type and prepare to send
324 
325  // the trace decoder attachment on main data path.
326  if(m_pkt_out_i.hasAttachedAndEnabled() && !OCSD_DATA_RESP_IS_FATAL(resp))
327  resp = m_pkt_out_i.first()->PacketDataIn(OCSD_OP_EOT,0,0);
328 
329  // packet monitor
330  if(m_pkt_raw_mon_i.hasAttachedAndEnabled())
331  m_pkt_raw_mon_i.first()->RawPacketDataMon(OCSD_OP_EOT,0,0,0,0);
332 
333  return resp;
334 }
335 
336 template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::outputDecodedPacket(const ocsd_trc_index_t index, const P *pkt)
337 {
339 
340  // bad packet filter.
341  if((getComponentOpMode() & OCSD_OPFLG_PKTPROC_NOFWD_BAD_PKTS) && isBadPacket())
342  return resp;
343 
344  // send a complete packet over the primary data path
345  if(m_pkt_out_i.hasAttachedAndEnabled())
346  resp = m_pkt_out_i.first()->PacketDataIn(OCSD_OP_DATA,index,pkt);
347  return resp;
348 }
349 
350 template<class P,class Pt, class Pc> void TrcPktProcBase<P, Pt, Pc>::outputRawPacketToMonitor(
351  const ocsd_trc_index_t index_sop,
352  const P *pkt,
353  const uint32_t size,
354  const uint8_t *p_data)
355 {
356  // never output 0 sized packets.
357  if(size == 0)
358  return;
359 
360  // bad packet filter.
361  if((getComponentOpMode() & OCSD_OPFLG_PKTPROC_NOMON_BAD_PKTS) && isBadPacket())
362  return;
363 
364  // packet monitor - this cannot return CONT / WAIT, but does get the raw packet data.
365  if(m_pkt_raw_mon_i.hasAttachedAndEnabled())
366  m_pkt_raw_mon_i.first()->RawPacketDataMon(OCSD_OP_DATA,index_sop,pkt,size,p_data);
367 }
368 
369 template<class P,class Pt, class Pc> const bool TrcPktProcBase<P, Pt, Pc>::hasRawMon() const
370 {
371  return m_pkt_raw_mon_i.hasAttachedAndEnabled();
372 }
373 
374 template<class P,class Pt, class Pc> void TrcPktProcBase<P, Pt, Pc>::indexPacket(const ocsd_trc_index_t index_sop, const Pt *packet_type)
375 {
376  // packet indexer - cannot return CONT / WAIT, just gets the current index and type.
377  if(m_pkt_indexer_i.hasAttachedAndEnabled())
378  m_pkt_indexer_i.first()->TracePktIndex(index_sop,packet_type);
379 }
380 
381 template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::outputOnAllInterfaces(const ocsd_trc_index_t index_sop, const P *pkt, const Pt *pkt_type, std::vector<uint8_t> &pktdata)
382 {
383  indexPacket(index_sop,pkt_type);
384  if(pktdata.size() > 0) // prevent out of range errors for 0 length vector.
385  outputRawPacketToMonitor(index_sop,pkt,(uint32_t)pktdata.size(),&pktdata[0]);
386  return outputDecodedPacket(index_sop,pkt);
387 }
388 
389 template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::outputOnAllInterfaces(const ocsd_trc_index_t index_sop, const P *pkt, const Pt *pkt_type, const uint8_t *pktdata, uint32_t pktlen)
390 {
391  indexPacket(index_sop,pkt_type);
392  outputRawPacketToMonitor(index_sop,pkt,pktlen,pktdata);
393  return outputDecodedPacket(index_sop,pkt);
394 }
395 
396 template<class P,class Pt, class Pc> ocsd_err_t TrcPktProcBase<P, Pt, Pc>::setProtocolConfig(const Pc *config)
397 {
399  if(config != 0)
400  {
401  ClearConfigObj();
402  m_config = new (std::nothrow) Pc(*config);
403  if(m_config != 0)
404  err = onProtocolConfig();
405  else
406  err = OCSD_ERR_MEM;
407  }
408  return err;
409 }
410 
411 template<class P,class Pt, class Pc> void TrcPktProcBase<P, Pt, Pc>::ClearConfigObj()
412 {
413  if(m_config)
414  {
415  delete m_config;
416  m_config = 0;
417  }
418 }
419 
420 template<class P,class Pt, class Pc> const bool TrcPktProcBase<P, Pt, Pc>::checkInit()
421 {
422  if(!m_b_is_init)
423  {
424  if( (m_config != 0) &&
425  (m_pkt_out_i.hasAttached() || m_pkt_raw_mon_i.hasAttached())
426  )
427  m_b_is_init = true;
428  }
429  return m_b_is_init;
430 }
431 
432 template<class P,class Pt, class Pc> ocsd_err_t TrcPktProcBase<P, Pt, Pc>::getStatsBlock(ocsd_decode_stats_t **pp_stats)
433 {
434 
435  *pp_stats = &m_stats;
436  return m_stats_init ? OCSD_OK : OCSD_ERR_NOT_INIT;
437 }
438 
439 template<class P,class Pt, class Pc> void TrcPktProcBase<P, Pt, Pc>::resetStats()
440 {
441  m_stats.version = OCSD_VER_NUM;
442  m_stats.revision = OCSD_STATS_REVISION;
443  m_stats.channel_total = 0;
444  m_stats.channel_unsynced = 0;
445  m_stats.bad_header_errs = 0;
446  m_stats.bad_sequence_errs = 0;
447  m_stats.demux.frame_bytes = 0;
448  m_stats.demux.no_id_bytes = 0;
449  m_stats.demux.valid_id_bytes = 0;
450 }
451 
454 #endif // ARM_TRC_PKT_PROC_BASE_H_INCLUDED
455 
456 /* End of File trc_pkt_proc_base.h */
Interface to either trace data frame deformatter or packet processor.
Base class for all decode components in the library.
Definition: trc_component.h:57
Packet Processor base class. Provides common infrastructure and interconnections for packet processor...
void statsAddBadSeqCount(const uint32_t count)
void statsAddUnsyncCount(const uint64_t count)
componentAttachPt< IPktRawDataMon< P > > * getRawPacketMonAttachPt()
Attachment point for the protocol packet monitor.
componentAttachPt< IPktDataIn< P > > * getPacketOutAttachPt()
Attachement point for the protocol packet output.
void statsAddTotalCount(const uint64_t count)
componentAttachPt< ITrcPktIndexer< Pt > > * getTraceIDIndexerAttachPt()
Attachment point for a packet indexer.
virtual const Pc * getProtocolConfig() const
void statsAddBadHdrCount(const uint32_t count)
Base Packet processing interface.
virtual ocsd_datapath_resp_t TraceDataIn(const ocsd_datapath_op_t op, const ocsd_trc_index_t index, const uint32_t dataBlockSize, const uint8_t *pDataBlock, uint32_t *numBytesProcessed)=0
virtual ocsd_datapath_resp_t processData(const ocsd_trc_index_t index, const uint32_t dataBlockSize, const uint8_t *pDataBlock, uint32_t *numBytesProcessed)=0
Implementation function for the OCSD_OP_DATA operation.
virtual ocsd_datapath_resp_t onFlush()=0
Implementation function for the OCSD_OP_FLUSH operation.
virtual ocsd_err_t getStatsBlock(ocsd_decode_stats_t **pp_stats)=0
virtual const bool isBadPacket() const =0
check if the current packet is an error / bad packet
virtual ocsd_err_t onProtocolConfig()=0
Called when the configuration object is passed to the decoder.
virtual void resetStats()=0
virtual ocsd_datapath_resp_t onReset()=0
Implementation function for the OCSD_OP_RESET operation.
virtual ocsd_datapath_resp_t onEOT()=0
Implementation function for the OCSD_OP_EOT operation.
virtual ~TrcPktProcI()
Single component interface pointer attachment point.
OpenCSD : Component attachment point interface class.
#define OCSD_DATA_RESP_IS_FATAL(x)
#define OCSD_STATS_REVISION
uint32_t ocsd_trc_index_t
Definition: ocsd_if_types.h:67
enum _ocsd_datapath_resp_t ocsd_datapath_resp_t
#define OCSD_DATA_RESP_IS_CONT(x)
#define OCSD_VER_NUM
enum _ocsd_datapath_op_t ocsd_datapath_op_t
enum _ocsd_err_t ocsd_err_t
#define OCSD_OPFLG_PKTPROC_NOMON_BAD_PKTS
#define OCSD_OPFLG_PKTPROC_NOFWD_BAD_PKTS
@ OCSD_OK
Definition: ocsd_if_types.h:88
@ OCSD_ERR_INVALID_PARAM_VAL
Definition: ocsd_if_types.h:94
@ OCSD_ERR_NOT_INIT
Definition: ocsd_if_types.h:91
@ OCSD_ERR_MEM
Definition: ocsd_if_types.h:90
@ OCSD_RESP_CONT
@ OCSD_RESP_FATAL_INVALID_PARAM
@ OCSD_RESP_FATAL_INVALID_OP
@ OCSD_OP_EOT
@ OCSD_OP_FLUSH
@ OCSD_OP_DATA
@ OCSD_OP_RESET
@ OCSD_ERR_SEV_ERROR
ocsd_datapath_resp_t outputOnAllInterfaces(const ocsd_trc_index_t index_sop, const P *pkt, const Pt *pkt_type, std::vector< uint8_t > &pktdata)
void outputRawPacketToMonitor(const ocsd_trc_index_t index_sop, const P *pkt, const uint32_t size, const uint8_t *p_data)
virtual ocsd_err_t getStatsBlock(ocsd_decode_stats_t **pp_stats)
TrcPktProcI(const char *component_name)
void indexPacket(const ocsd_trc_index_t index_sop, const Pt *packet_type)
virtual ocsd_err_t setProtocolConfig(const Pc *config)
< Set the protocol specific configuration for the decoder.
const bool hasRawMon() const
virtual ~TrcPktProcBase()
const bool checkInit()
virtual ocsd_datapath_resp_t TraceDataIn(const ocsd_datapath_op_t op, const ocsd_trc_index_t index, const uint32_t dataBlockSize, const uint8_t *pDataBlock, uint32_t *numBytesProcessed)
TrcPktProcBase(const char *component_name)
ocsd_datapath_resp_t outputOnAllInterfaces(const ocsd_trc_index_t index_sop, const P *pkt, const Pt *pkt_type, const uint8_t *pktdata, uint32_t pktlen)
TrcPktProcBase(const char *component_name, int instIDNum)
ocsd_datapath_resp_t outputDecodedPacket(const ocsd_trc_index_t index_sop, const P *pkt)
virtual void resetStats()
uint32_t bad_header_errs
uint32_t bad_sequence_errs
uint64_t channel_unsynced
OpenCSD : Base trace decode component.