#ifndef _MGEN_FLOW
#define _MGEN_FLOW
#include "mgenEvent.h"
#include "mgenSocketList.h"
#include "gpsPub.h"
#include "protokit.h"
#include <stdio.h> // for FILE
// Prototype for function to retrieve position/status
// (See gpsPub.h for GPSPosition definition)
typedef bool (MgenPositionFunc)(const void* clientData,
GPSPosition& gpsPosition);
// protocol SINK may be used as an alternative to socket
// based protocols (e.g. UDP). In this case, class Mgen
// (and its flows) must be assigned a pointer to an
// instance of class MgenSink which has a "SendMgenMessage()"
// method which is used instead of a socket send() or sendto()
class MgenSink
{
public:
MgenSink();
virtual ~MgenSink();
virtual bool SendMgenMessage(const char* txBuffer,
unsigned int len,
const ProtoAddress& dstAddr) = 0;
virtual void StartNotifying(class MgenFlow* theFlow)
{notify_flow= theFlow;}
virtual void StopNotifying()
{notify_flow= NULL;}
bool IsNotifying()
{return (NULL != notify_flow);}
protected:
class MgenFlow* notify_flow;
}; // end class MgenSink
class MgenFlow
{
friend class MgenFlowList;
public:
MgenFlow(unsigned int flowId,
ProtoTimerMgr& timerMgr,
MgenSocketList& socketList,
unsigned long defaultV6Label = 0);
~MgenFlow();
void SetPositionCallback(MgenPositionFunc* callback,
const void* clientData)
{
get_position = callback;
get_position_data = clientData;
}
#ifdef HAVE_GPS
void SetPayloadHandle(GPSHandle payloadHandle)
{payload_handle = payloadHandle;}
#endif // HAVE_GPS
void SetSink(MgenSink* theSink) {sink = theSink;}
void SetLogFile(FILE* logFile, bool binary, bool logFlush)
{log_file = logFile; log_binary = binary; log_flush = logFlush;}
void SetHostAddress(const ProtoAddress hostAddr)
{
host_addr = hostAddr;
if (socket) host_addr.SetPort(socket->GetPort());
}
void ClearHostAddress() {host_addr.Invalidate();}
void EnableChecksums() {checksum_enable = true;}
bool InsertEvent(MgenEvent* event, bool mgenStarted, double currentTime);
bool ValidateEvent(const MgenEvent* event);
bool Start(double offsetTime);
bool Update(const MgenEvent* event);
bool IsActive() const;
double GetCurrentOffset() const;
#ifdef HAVE_IPV6
void SetLabel(UINT32 label) {flow_label = label;}
#endif //HAVE_IPV6
void Notify() {OnTxTimeout(tx_timer);}
private:
bool OnTxTimeout(ProtoTimer& theTimer);
bool OnEventTimeout(ProtoTimer& theTimer);
FILE* log_file;
bool log_binary;
bool log_flush;
bool checksum_enable;
unsigned long flow_id;
MgenBaseEvent::Protocol protocol;
ProtoAddress dst_addr;
unsigned short src_port;
ProtoAddress host_addr; // src addr concept
MgenPattern pattern;
UINT32 flow_label;
ProtoTimer tx_timer;
MgenSocketList::Item* socket_item;
ProtoSocket* socket;
MgenSink* sink; // for protocol "SINK"
unsigned long seq_num;
double last_interval;
MgenEventList event_list;
MgenEvent* next_event;
ProtoTimer event_timer;
bool started;
ProtoTimerMgr& timer_mgr;
MgenSocketList& socket_list;
MgenPositionFunc* get_position;
const void* get_position_data;
#ifdef HAVE_GPS
GPSHandle payload_handle;
#endif // HAVE_GPS
MgenFlow* prev;
MgenFlow* next;
}; // end class MgenFlow
class MgenFlowList
{
public:
MgenFlowList();
~MgenFlowList();
void Destroy();
void Append(MgenFlow* theFlow);
void SetLogFile(FILE* filePtr, bool binary, bool flush);
void EnableChecksums();
void SetSink(MgenSink* theSink);
void SetHostAddress(const ProtoAddress& hostAddr);
void ClearHostAddress();
MgenFlow* FindFlowById(unsigned int flowId);
bool IsEmpty() {return (NULL == head);}
bool Start(double offsetTime);
double GetCurrentOffset() const;
bool SaveFlowSequences(FILE* file) const;
void SetDefaultLabel(UINT32 label);
private:
MgenFlow* head;
MgenFlow* tail;
}; // end class MgenFlowList
#endif // _MGEN_FLOW
syntax highlighted by Code2HTML, v. 0.9.1