|
EPONImplementationforOMNet++
0.8Beta
|
OLTMacCtl_NP class controls the below MAC layer transmission times. More...
#include <OLTMacCtl_NP.h>
Public Member Functions | |
| virtual | ~OLTMacCtl_NP () |
Protected Member Functions | |
| virtual void | initialize () |
| virtual void | handleMessage (cMessage *msg) |
| virtual void | processFrameFromHigherLayer (cMessage *msg) |
| virtual void | processFrameFromMAC (cMessage *msg) |
| virtual void | clockSync () |
| virtual void | handleTxEnd () |
| virtual void | doTransmit (cMessage *msg) |
| Handle transmissions and queue. | |
| virtual cModule * | getNeighbourOnGate (const char *gate) |
Protected Attributes | |
| uint32_t | clock_reg |
| IPassiveQueue * | queue_mod |
| cQueue | tmp_queue |
| int | transmitState |
| cMessage * | txEnd |
| int | numFramesFromHL |
| int | numFramesFromLL |
OLTMacCtl_NP class controls the below MAC layer transmission times.
For the OLT is simpler since we continuously transmit. This class has a pointer to the EPON_Q_mgmt module and it uses it as a simple queue in order to get frames. Finally note that missing mac addresses and LLIDs (from frames) are filled in here, cause the lower layer expects them.
| OLTMacCtl_NP::~OLTMacCtl_NP | ( | ) | [virtual] |
{
cancelAndDelete(txEnd);
}
| void OLTMacCtl_NP::clockSync | ( | ) | [protected, virtual] |
| void OLTMacCtl_NP::doTransmit | ( | cMessage * | msg | ) | [protected, virtual] |
Handle transmissions and queue.
{
cPacket * packet = check_and_cast<cPacket *>(msg);
if (!packet)
error("Queue module returned NULL frame");
// Calculate TX and remaining time
// NOTE: Change here for more bandwidth
uint64_t txrate=GIGABIT_ETHERNET_TXRATE;
uint32_t nextMsgSize = packet->getByteLength();
if (nextMsgSize == 0) {
error("Message size 0");
}
uint32_t bytes=nextMsgSize+PREAMBLE_BYTES+SFD_BYTES;
bytes+=INTERFRAME_GAP_BITS/8;
// TODO: Add laser on/off delay
simtime_t timereq= ((double)(bytes*8)/txrate);
EV << "Bytes: "<<bytes<<" bits: "<<bytes*8<<" TX RATE: "<<txrate<<endl;
EV << "TX State: "<<transmitState<<endl;
EV << "Scheduled after "<<(double)(bytes*8)/txrate<<"ns"<<endl;
if (transmitState == TX_IDLE){
transmitState=TX_SENDING;
// Calculate the tx time
EV << "EndTx Scheduled after "<< timereq.raw() << " time_now: "<<simTime().raw()<<endl;
scheduleAt(simTime()+timereq, txEnd);
EV << " Sending..."<<endl;
send(msg, "lowerLayerOut");
}
else{
error ("OLTMacCtl_NP: Packet Arrived from higher layer"
"while we where in transmission. This should never happen"
"(normally).");
}
}
| cModule * OLTMacCtl_NP::getNeighbourOnGate | ( | const char * | gate | ) | [protected, virtual] |
{
return gate(g)->getNextGate()->getOwnerModule();
}
| void OLTMacCtl_NP::handleMessage | ( | cMessage * | msg | ) | [protected, virtual] |
{
// Do clock_reg sync
clockSync();
// Self Message
if (msg->isSelfMessage())
{
EV << "Self-message " << msg << " received\n";
if (msg->getKind() == TXENDMSG)
handleTxEnd();
else
EV << "UnKnown Self Message\n";
return;
}
// Network Message
cGate *ingate = msg->getArrivalGate();
EV << "Frame " << msg << " arrived on port " << ingate->getName() << "...\n";
if (ingate->getId() == gate( "lowerLayerIn")->getId()){
processFrameFromMAC(msg);
}
else if (ingate->getId() == gate( "upperLayerIn")->getId()){
processFrameFromHigherLayer(msg);
}else{
EV << "OLTMacCtl_NP: Message came FROM THE WRONG DIRRECTION???? Dropping\n";
delete msg;
}
}
| void OLTMacCtl_NP::handleTxEnd | ( | ) | [protected, virtual] |
{
transmitState=TX_IDLE;
if (tmp_queue.isEmpty()) {
queue_mod->requestPacket();
return;
}
doTransmit(dynamic_cast<cMessage *>(tmp_queue.pop()) );
}
| void OLTMacCtl_NP::initialize | ( | ) | [protected, virtual] |
{
clock_reg=0;
// Watch the clock!!!
// (AND TRY NOT TO TOUCH IT)
WATCH(clock_reg);
txEnd = new cMessage("TxEnd",TXENDMSG);
transmitState=TX_IDLE;
WATCH(transmitState);
// Initialize the Q mgmt module
queue_mod = dynamic_cast<IPassiveQueue *>(getNeighbourOnGate("upperLayerOut"));
if (!queue_mod)
error("ONUMacCtl: A IPassiveQueue is needed above mac control");
}
| void OLTMacCtl_NP::processFrameFromHigherLayer | ( | cMessage * | msg | ) | [protected, virtual] |
{
EV << "OLTMacCtl_NP: Incoming to PON area...\n";
EthernetIIFrame * frame = dynamic_cast<EthernetIIFrame *>(msg);
if (frame && frame->getEtherType() == MPCP_TYPE){
MPCP * mpcp = check_and_cast<MPCP *>(msg);
mpcp->setTs(MPCPTools::simTimeToNS16());
}
EV << "OLTMacCtl_NP::Enqueue Frame" <<endl;
tmp_queue.insert(msg);
// handle tx end will react like
// a transmission just finished ==
// check the Q module and keep on sending.
if (transmitState == TX_IDLE){
EV << "OLTMacCtl_NP::We where IDLE... starting transmission" <<endl;
handleTxEnd();
}
}
| void OLTMacCtl_NP::processFrameFromMAC | ( | cMessage * | msg | ) | [protected, virtual] |
{
EV << "OLTMacCtl_NP: Message from PON area, forwarding to higher layer\n";
// Not Control
send(msg,"upperLayerOut");
numFramesFromLL++;
}
uint32_t OLTMacCtl_NP::clock_reg [protected] |
int OLTMacCtl_NP::numFramesFromHL [protected] |
int OLTMacCtl_NP::numFramesFromLL [protected] |
IPassiveQueue* OLTMacCtl_NP::queue_mod [protected] |
cQueue OLTMacCtl_NP::tmp_queue [protected] |
int OLTMacCtl_NP::transmitState [protected] |
cMessage* OLTMacCtl_NP::txEnd [protected] |