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
66{
67public:
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
81 virtual void resetStats() = 0;
82protected:
83
84 /* implementation packet processing interface */
85
88 const uint32_t dataBlockSize,
89 const uint8_t *pDataBlock,
90 uint32_t *numBytesProcessed) = 0;
91
96 virtual const bool isBadPacket() const = 0;
97};
98
99inline TrcPktProcI::TrcPktProcI(const char *component_name) :
100 TraceComponent(component_name)
101{
102}
103
104inline TrcPktProcI::TrcPktProcI(const char *component_name, int instIDNum) :
105 TraceComponent(component_name,instIDNum)
106{
107}
108
125template <class P, class Pt, class Pc>
127{
128public:
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
165protected:
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
201private:
202 /* decode control */
203 ocsd_datapath_resp_t Reset(const ocsd_trc_index_t index);
204 ocsd_datapath_resp_t Flush();
206
209
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
220template<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
229template<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
238template<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
286template<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
305template<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
321template<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
336template<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
350template<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
369template<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
374template<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
381template<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
389template<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
396template<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
411template<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
420template<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
432template<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
439template<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)
virtual const Pc * getProtocolConfig() const
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.
componentAttachPt< IPktRawDataMon< P > > * getRawPacketMonAttachPt()
Attachment point for the protocol packet monitor.
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.