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