trc_pkt_proc_base.h
Go to the documentation of this file.
/*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ARM_TRC_PKT_PROC_BASE_H_INCLUDED
#define ARM_TRC_PKT_PROC_BASE_H_INCLUDED
#include "interfaces/trc_data_raw_in_i.h"
#include "interfaces/trc_pkt_in_i.h"
#include "interfaces/trc_pkt_raw_in_i.h"
#include "interfaces/trc_indexer_pkt_i.h"
#include "trc_component.h"
#include "comp_attach_pt_t.h"
class TrcPktProcI : public TraceComponent, public ITrcDataIn
{
public:
TrcPktProcI(const char *component_name);
TrcPktProcI(const char *component_name, int instIDNum);
virtual ~TrcPktProcI() {};
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;
protected:
/* implementation packet processing interface */
virtual ocsd_datapath_resp_t processData( const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed) = 0;
virtual ocsd_datapath_resp_t onEOT() = 0;
virtual ocsd_datapath_resp_t onReset() = 0;
virtual ocsd_datapath_resp_t onFlush() = 0;
virtual ocsd_err_t onProtocolConfig() = 0;
virtual const bool isBadPacket() const = 0;
};
inline TrcPktProcI::TrcPktProcI(const char *component_name) :
TraceComponent(component_name)
{
}
inline TrcPktProcI::TrcPktProcI(const char *component_name, int instIDNum) :
TraceComponent(component_name,instIDNum)
{
}
template <class P, class Pt, class Pc>
class TrcPktProcBase : public TrcPktProcI
{
public:
TrcPktProcBase(const char *component_name);
TrcPktProcBase(const char *component_name, int instIDNum);
virtual ~TrcPktProcBase();
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);
/* component attachment points */
componentAttachPt<IPktDataIn<P>> *getPacketOutAttachPt() { return &m_pkt_out_i; };
componentAttachPt<IPktRawDataMon<P>> *getRawPacketMonAttachPt() { return &m_pkt_raw_mon_i; };
componentAttachPt<ITrcPktIndexer<Pt>> *getTraceIDIndexerAttachPt() { return &m_pkt_indexer_i; };
/* protocol configuration */
virtual ocsd_err_t setProtocolConfig(const Pc *config);
virtual const Pc *getProtocolConfig() const { return m_config; };
protected:
/* data output functions */
ocsd_datapath_resp_t outputDecodedPacket(const ocsd_trc_index_t index_sop, const P *pkt);
void outputRawPacketToMonitor( const ocsd_trc_index_t index_sop,
const P *pkt,
const uint32_t size,
const uint8_t *p_data);
void indexPacket(const ocsd_trc_index_t index_sop, const Pt *packet_type);
ocsd_datapath_resp_t outputOnAllInterfaces(const ocsd_trc_index_t index_sop, const P *pkt, const Pt *pkt_type, std::vector<uint8_t> &pktdata);
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);
const bool hasRawMon() const;
/* the protocol configuration */
const Pc *m_config;
void ClearConfigObj(); // remove our copy of the config
const bool checkInit(); // return true if init (configured and at least one output sink attached), false otherwise.
private:
/* decode control */
ocsd_datapath_resp_t Reset(const ocsd_trc_index_t index);
ocsd_datapath_resp_t Flush();
ocsd_datapath_resp_t EOT();
componentAttachPt<IPktDataIn<P>> m_pkt_out_i;
componentAttachPt<IPktRawDataMon<P>> m_pkt_raw_mon_i;
componentAttachPt<ITrcPktIndexer<Pt>> m_pkt_indexer_i;
bool m_b_is_init;
};
template<class P,class Pt, class Pc> TrcPktProcBase<P, Pt, Pc>::TrcPktProcBase(const char *component_name) :
TrcPktProcI(component_name),
m_config(0),
m_b_is_init(false)
{
}
template<class P,class Pt, class Pc> TrcPktProcBase<P, Pt, Pc>::TrcPktProcBase(const char *component_name, int instIDNum) :
TrcPktProcI(component_name, instIDNum),
m_config(0),
m_b_is_init(false)
{
}
template<class P,class Pt, class Pc> TrcPktProcBase<P, Pt, Pc>::~TrcPktProcBase()
{
ClearConfigObj();
}
template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::TraceDataIn( const ocsd_datapath_op_t op,
const ocsd_trc_index_t index,
const uint32_t dataBlockSize,
const uint8_t *pDataBlock,
uint32_t *numBytesProcessed)
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
switch(op)
{
case OCSD_OP_DATA:
if((dataBlockSize == 0) || (pDataBlock == 0) || (numBytesProcessed == 0))
{
if(numBytesProcessed)
*numBytesProcessed = 0; // ensure processed bytes value set to 0.
LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_INVALID_PARAM_VAL,"Packet Processor: Zero length data block or NULL pointer error\n"));
resp = OCSD_RESP_FATAL_INVALID_PARAM;
}
else
resp = processData(index,dataBlockSize,pDataBlock,numBytesProcessed);
break;
case OCSD_OP_EOT:
resp = EOT();
break;
case OCSD_OP_FLUSH:
resp = Flush();
break;
case OCSD_OP_RESET:
resp = Reset(index);
break;
default:
LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_INVALID_PARAM_VAL,"Packet Processor : Unknown Datapath operation\n"));
resp = OCSD_RESP_FATAL_INVALID_OP;
break;
}
return resp;
}
template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::Reset(const ocsd_trc_index_t index)
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
// reset the trace decoder attachment on main data path.
if(m_pkt_out_i.hasAttachedAndEnabled())
resp = m_pkt_out_i.first()->PacketDataIn(OCSD_OP_RESET,index,0);
// reset the packet processor implmentation
if(!OCSD_DATA_RESP_IS_FATAL(resp))
resp = onReset();
// packet monitor
if(m_pkt_raw_mon_i.hasAttachedAndEnabled())
m_pkt_raw_mon_i.first()->RawPacketDataMon(OCSD_OP_RESET,index,0,0,0);
return resp;
}
template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::Flush()
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
ocsd_datapath_resp_t resplocal = OCSD_RESP_CONT;
// the trace decoder attachment on main data path.
if(m_pkt_out_i.hasAttachedAndEnabled())
resp = m_pkt_out_i.first()->PacketDataIn(OCSD_OP_FLUSH,0,0); // flush up the data path first.
// if the connected components are flushed, not flush this one.
if(OCSD_DATA_RESP_IS_CONT(resp))
resplocal = onFlush(); // local flush
return (resplocal > resp) ? resplocal : resp;
}
template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::EOT()
{
ocsd_datapath_resp_t resp = onEOT(); // local EOT - mark any part packet as incomplete type and prepare to send
// the trace decoder attachment on main data path.
if(m_pkt_out_i.hasAttachedAndEnabled() && !OCSD_DATA_RESP_IS_FATAL(resp))
resp = m_pkt_out_i.first()->PacketDataIn(OCSD_OP_EOT,0,0);
// packet monitor
if(m_pkt_raw_mon_i.hasAttachedAndEnabled())
m_pkt_raw_mon_i.first()->RawPacketDataMon(OCSD_OP_EOT,0,0,0,0);
return resp;
}
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)
{
ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
// bad packet filter.
if((getComponentOpMode() & OCSD_OPFLG_PKTPROC_NOFWD_BAD_PKTS) && isBadPacket())
return resp;
// send a complete packet over the primary data path
if(m_pkt_out_i.hasAttachedAndEnabled())
resp = m_pkt_out_i.first()->PacketDataIn(OCSD_OP_DATA,index,pkt);
return resp;
}
template<class P,class Pt, class Pc> void TrcPktProcBase<P, Pt, Pc>::outputRawPacketToMonitor(
const ocsd_trc_index_t index_sop,
const P *pkt,
const uint32_t size,
const uint8_t *p_data)
{
// never output 0 sized packets.
if(size == 0)
return;
// bad packet filter.
if((getComponentOpMode() & OCSD_OPFLG_PKTPROC_NOMON_BAD_PKTS) && isBadPacket())
return;
// packet monitor - this cannot return CONT / WAIT, but does get the raw packet data.
if(m_pkt_raw_mon_i.hasAttachedAndEnabled())
m_pkt_raw_mon_i.first()->RawPacketDataMon(OCSD_OP_DATA,index_sop,pkt,size,p_data);
}
template<class P,class Pt, class Pc> const bool TrcPktProcBase<P, Pt, Pc>::hasRawMon() const
{
return m_pkt_raw_mon_i.hasAttachedAndEnabled();
}
template<class P,class Pt, class Pc> void TrcPktProcBase<P, Pt, Pc>::indexPacket(const ocsd_trc_index_t index_sop, const Pt *packet_type)
{
// packet indexer - cannot return CONT / WAIT, just gets the current index and type.
if(m_pkt_indexer_i.hasAttachedAndEnabled())
m_pkt_indexer_i.first()->TracePktIndex(index_sop,packet_type);
}
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)
{
indexPacket(index_sop,pkt_type);
if(pktdata.size() > 0) // prevent out of range errors for 0 length vector.
outputRawPacketToMonitor(index_sop,pkt,(uint32_t)pktdata.size(),&pktdata[0]);
return outputDecodedPacket(index_sop,pkt);
}
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)
{
indexPacket(index_sop,pkt_type);
outputRawPacketToMonitor(index_sop,pkt,pktlen,pktdata);
return outputDecodedPacket(index_sop,pkt);
}
template<class P,class Pt, class Pc> ocsd_err_t TrcPktProcBase<P, Pt, Pc>::setProtocolConfig(const Pc *config)
{
ocsd_err_t err = OCSD_ERR_INVALID_PARAM_VAL;
if(config != 0)
{
ClearConfigObj();
m_config = new (std::nothrow) Pc(*config);
if(m_config != 0)
err = onProtocolConfig();
else
err = OCSD_ERR_MEM;
}
return err;
}
template<class P,class Pt, class Pc> void TrcPktProcBase<P, Pt, Pc>::ClearConfigObj()
{
if(m_config)
{
delete m_config;
m_config = 0;
}
}
template<class P,class Pt, class Pc> const bool TrcPktProcBase<P, Pt, Pc>::checkInit()
{
if(!m_b_is_init)
{
if( (m_config != 0) &&
(m_pkt_out_i.hasAttached() || m_pkt_raw_mon_i.hasAttached())
)
m_b_is_init = true;
}
return m_b_is_init;
}
#endif // ARM_TRC_PKT_PROC_BASE_H_INCLUDED
/* End of File trc_pkt_proc_base.h */
ocsd_err_t
enum _ocsd_err_t ocsd_err_t
TrcPktProcBase::outputDecodedPacket
ocsd_datapath_resp_t outputDecodedPacket(const ocsd_trc_index_t index_sop, const P *pkt)
Definition: trc_pkt_proc_base.h:312
OCSD_OP_RESET
Definition: ocsd_if_types.h:184
TrcPktProcBase::m_config
const Pc * m_config
Definition: trc_pkt_proc_base.h:180
trc_pkt_in_i.h
TrcPktProcBase::checkInit
const bool checkInit()
Definition: trc_pkt_proc_base.h:396
ocsdError
Definition: ocsd_error.h:58
TrcPktProcI::~TrcPktProcI
virtual ~TrcPktProcI()
Definition: trc_pkt_proc_base.h:69
TrcPktProcBase::indexPacket
void indexPacket(const ocsd_trc_index_t index_sop, const Pt *packet_type)
Definition: trc_pkt_proc_base.h:350
TrcPktProcBase::getTraceIDIndexerAttachPt
componentAttachPt< ITrcPktIndexer< Pt > > * getTraceIDIndexerAttachPt()
Attachment point for a packet indexer.
Definition: trc_pkt_proc_base.h:150
OCSD_DATA_RESP_IS_CONT
#define OCSD_DATA_RESP_IS_CONT(x)
Definition: ocsd_if_types.h:213
TrcPktProcI::onReset
virtual ocsd_datapath_resp_t onReset()=0
Implementation function for the OCSD_OP_RESET operation.
TrcPktProcBase::getPacketOutAttachPt
componentAttachPt< IPktDataIn< P > > * getPacketOutAttachPt()
Attachement point for the protocol packet output.
Definition: trc_pkt_proc_base.h:145
TrcPktProcI::onProtocolConfig
virtual ocsd_err_t onProtocolConfig()=0
Called when the configuration object is passed to the decoder.
TrcPktProcBase::TraceDataIn
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)
Definition: trc_pkt_proc_base.h:219
TrcPktProcBase::hasRawMon
const bool hasRawMon() const
Definition: trc_pkt_proc_base.h:345
TrcPktProcBase::getRawPacketMonAttachPt
componentAttachPt< IPktRawDataMon< P > > * getRawPacketMonAttachPt()
Attachment point for the protocol packet monitor.
Definition: trc_pkt_proc_base.h:147
OCSD_RESP_FATAL_INVALID_OP
Definition: ocsd_if_types.h:198
TrcPktProcI::onFlush
virtual ocsd_datapath_resp_t onFlush()=0
Implementation function for the OCSD_OP_FLUSH operation.
TrcPktProcI::onEOT
virtual ocsd_datapath_resp_t onEOT()=0
Implementation function for the OCSD_OP_EOT operation.
TraceComponent
Base class for all decode components in the library.
Definition: trc_component.h:56
trc_component.h
OpenCSD : Base trace decode component.
OCSD_ERR_MEM
Definition: ocsd_if_types.h:90
OCSD_ERR_INVALID_PARAM_VAL
Definition: ocsd_if_types.h:94
ocsd_trc_index_t
uint32_t ocsd_trc_index_t
Definition: ocsd_if_types.h:67
TrcPktProcI::processData
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.
componentAttachPt
Single component interface pointer attachment point.
Definition: comp_attach_pt_t.h:61
OCSD_RESP_CONT
Definition: ocsd_if_types.h:191
ocsd_datapath_op_t
enum _ocsd_datapath_op_t ocsd_datapath_op_t
TrcPktProcI::TraceDataIn
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
comp_attach_pt_t.h
OpenCSD : Component attachment point interface class.
trc_pkt_raw_in_i.h
OCSD_OP_DATA
Definition: ocsd_if_types.h:181
TrcPktProcBase::getProtocolConfig
virtual const Pc * getProtocolConfig() const
Definition: trc_pkt_proc_base.h:156
OCSD_OP_EOT
Definition: ocsd_if_types.h:182
TrcPktProcBase::~TrcPktProcBase
virtual ~TrcPktProcBase()
Definition: trc_pkt_proc_base.h:214
TrcPktProcI::TrcPktProcI
TrcPktProcI(const char *component_name)
Definition: trc_pkt_proc_base.h:96
TrcPktProcI::isBadPacket
virtual const bool isBadPacket() const =0
check if the current packet is an error / bad packet
trc_indexer_pkt_i.h
OCSD_OP_FLUSH
Definition: ocsd_if_types.h:183
TrcPktProcBase::TrcPktProcBase
TrcPktProcBase(const char *component_name)
Definition: trc_pkt_proc_base.h:200
OCSD_OPFLG_PKTPROC_NOMON_BAD_PKTS
#define OCSD_OPFLG_PKTPROC_NOMON_BAD_PKTS
Definition: ocsd_if_types.h:501
TrcPktProcI
Base Packet processing interface.
Definition: trc_pkt_proc_base.h:64
TrcPktProcBase
Packet Processor base class. Provides common infrastructure and interconnections for packet processor...
Definition: trc_pkt_proc_base.h:123
ocsd_datapath_resp_t
enum _ocsd_datapath_resp_t ocsd_datapath_resp_t
OCSD_RESP_FATAL_INVALID_PARAM
Definition: ocsd_if_types.h:199
TrcPktProcBase::outputOnAllInterfaces
ocsd_datapath_resp_t outputOnAllInterfaces(const ocsd_trc_index_t index_sop, const P *pkt, const Pt *pkt_type, std::vector< uint8_t > &pktdata)
Definition: trc_pkt_proc_base.h:357
TrcPktProcBase::ClearConfigObj
void ClearConfigObj()
Definition: trc_pkt_proc_base.h:387
trc_data_raw_in_i.h
TrcPktProcBase::setProtocolConfig
virtual ocsd_err_t setProtocolConfig(const Pc *config)
< Set the protocol specific configuration for the decoder.
Definition: trc_pkt_proc_base.h:372
OCSD_OPFLG_PKTPROC_NOFWD_BAD_PKTS
#define OCSD_OPFLG_PKTPROC_NOFWD_BAD_PKTS
Definition: ocsd_if_types.h:500
OCSD_DATA_RESP_IS_FATAL
#define OCSD_DATA_RESP_IS_FATAL(x)
Definition: ocsd_if_types.h:205
ITrcDataIn
Interface to either trace data frame deformatter or packet processor.
Definition: trc_data_raw_in_i.h:52
OCSD_ERR_SEV_ERROR
Definition: ocsd_if_types.h:168
TrcPktProcBase::outputRawPacketToMonitor
void outputRawPacketToMonitor(const ocsd_trc_index_t index_sop, const P *pkt, const uint32_t size, const uint8_t *p_data)
Definition: trc_pkt_proc_base.h:326