Version 4 (modified by 19 years ago) ( diff ) | ,
---|
Orbit > OTG > Function Specifications > How to design a new TG
How to design a TG for OTG software
Zhibin Wu
Introduction
The traffic generator component is current not an independent part of the OTG software. Therefore, whenever a new kind of traffic generator is to be designed, the new codes have to be compiled with other source files under a same Makefile. Thus, it has to obey some common interface requirements.
Interface between TG and OTG
The standard interface between TG and OTG is a member function of the Generator class called “nextPacket (Packet *p)”. The parameter is a pointer to an empty Packet object and the generator need to set following properties of this object:
- size: packet's payload size which does not include any frame headers.
- timestamp: this is the absolute timing value since the generator is created and initialized. The OTG program will check this timestamp and determine the exact time to transmit this packet into socket interface. In other words, the timing difference between the timestamp of current packet and previous packet is the packet arrival interval. This is a float-point number with unit in seconds.
- payload (optional)
Whenever this function is called, a packet object is passed as the input parameter. And in the instantiation of this function, the generator should set the above parameters of this packet object.
To introduce a new traffic generator, these following things have to be done:
Generator Class
Every generator derives from the Generator class. This virtual class does not define any member variables. There are two functions the child class must override.
- void init()
- bool nextPacket (Packet* p)
The exact implementation of init() function is up to you. This function will be called when the OTG program begins and before the generator creates the first packet. Therefore, some initial parameter setting could be done here.
Set Packet Property
As the nextPacket function will return a Packet point to the generated packet. The designed generator must (and only need) set two properties of this Packet object by using the following functions of the Packet class.
- void setPayloadSize (int size)
- void setTimeStamp (double stamp)
- int fillPayload(int size, char *inputstream);
The first two functions are self-evident. The third function read a certain size of bytes from the inputstream into the payload of this packet. If successful, return value is 0.
Interface with POPT command line parser
To let the user to specify the parameters of this new generator from command-line, some interface functions need to be defined. Currently, the OTG software uses the POPT library to create user interface. The interface with POPT is usually conducted by a callback function which would call those parameter-setting interface functions of the generator. Please refer to cbr_generator_helper.h and cbr_generator_helper.cpp files for creating similar interface for your new generator. In the future, those interface functions will be automatically generated from an xml file which defines the generator.
Important Note: if you allow user to change generator parameter on-the-fly. Design the interface functions carefully to be sure this change take effects in run-time.
getOptions Function
getOptions() function is to be defined as a member function of the new generator class. This function will be called in otg.cpp file to generate the available generator-specific options for user to choose.
Compile with OTG
The new source files are going to be included in the Makefile. Then the make process would create the OTG with the new TG component. In the future, a generator definition XML file has to be included in the make process to automatically download the codes for command-line interface.
Design Example
If you are implementing traffic generator "foo", you should do the following:
- Create file "foo_generator.cpp" and "foo_generator.h"
- Create file "foo_generator_helper.cpp" and "foo_generator_helper.h"
- Modify "otg.cpp" file
- Modify "Makefile"
For example, in file foo_generator.h, define class:
#ifndef FOO_GENERATOR_H #define FOO_GENERATOR_H #include <popt.h> #include "packet.h" #include "generator.h" /** FOO GENERATOR Module * */ class FooGenerator: public Generator { public: FooGenerator(int size=512); /** * Function to initialize the generator */ void init(); /* Implement virtual methods */ bool nextPacket(Packet* p); // Function to set properties of this generator void setPacketSize(int size); /** * Function to get POPT options for command-line interface */ const struct poptOption* getOptions(); private: ... Some private variables }; #endif
In file foo_generator.cpp, the implementation of nextPacket () and getOptions() functions are
bool FooGenerator::nextPacket (Packet* p) { ... Some generation algorithm } const struct poptOption* FooGenerator::getOptions() { return foo_generator_get_options(this, NULL); }
In file foo_generator_helper.cpp, we design the functions to parse one parameter “packet size” from user input for the foo_generator.
static void callback( poptContext con, enum poptCallbackReason reason, const struct poptOption * opt, char * arg, void * data ) { FooGenerator* gen = (FooGenerator*)data; if (strcmp(opt->longName, "size") == 0) { gen->setPktSize(atoi(arg)); } } const struct poptOption* foo_generator_get_options( const FooGenerator* gen, const char* prefix ) { struct poptOption* opts = (struct poptOption*)calloc(3, sizeof(struct poptOption)); struct poptOption* p = opts; popt_set(p++, NULL, NULL, '\0', POPT_ARG_CALLBACK, (void*)callback, 0, (char*)gen); popt_set(p++, prefix, "size", '\0', POPT_ARG_INT, NULL, 0, "Size of packet", "bytes"); popt_set(p); return opts; }
In the beginning of otg.cpp
See:
struct poptOption options_phase1[] = { POPT_AUTOHELP { "protocol", '\0', POPT_ARG_STRING, NULL, 0, "Name of protocol", "[tcp|udp|raw_packet]"}, { "generator", '\0', POPT_ARG_STRING, NULL, 0, "Name of generator", "[cbr|expoo]"}, { NULL, 0, 0, NULL, 0 } };
change the 4th line to
{ "generator", '\0', POPT_ARG_STRING, NULL, 0, "Name of generator", "[cbr|expoo|foo]"},
Also, in
Generator* createGenerator( char* generator_name ) { Generator* gen = NULL; if (strcmp(generator_name, "cbr") == 0 ){ gen = new CBR_Generator(); }else if(strcmp(generator_name, "expoo") == 0){ gen = new Expo_Generator(); }else { cerr << "Error: Unknown Generator '" << generator_name << "'." << endl; exit(-1); } return gen; }
adding…
... else if(strcmp(generator_name, "foo") == 0){ gen = new FooGenerator(); } ...
In Makefile
CPP_FILES += ....foo_generator.cpp ….. auto/foo_generator_helper.cpp