xref: /freebsd-src/contrib/opencsd/decoder/include/common/trc_pkt_proc_base.h (revision 46e6e290975f19ea62d03f90ac3e523af4dae557)
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