{"action":"closed","issue":{"url":"https://api.github.com/repos/inet-framework/inet/issues/221","repository_url":"https://api.github.com/repos/inet-framework/inet","labels_url":"https://api.github.com/repos/inet-framework/inet/issues/221/labels{/name}","comments_url":"https://api.github.com/repos/inet-framework/inet/issues/221/comments","events_url":"https://api.github.com/repos/inet-framework/inet/issues/221/events","html_url":"https://github.com/inet-framework/inet/issues/221","id":189152030,"number":221,"title":"Using PriorityScheduler with EtherMAC interface","user":{"login":"Abughazala","id":12843879,"avatar_url":"https://avatars.githubusercontent.com/u/12843879?v=3","gravatar_id":"","url":"https://api.github.com/users/Abughazala","html_url":"https://github.com/Abughazala","followers_url":"https://api.github.com/users/Abughazala/followers","following_url":"https://api.github.com/users/Abughazala/following{/other_user}","gists_url":"https://api.github.com/users/Abughazala/gists{/gist_id}","starred_url":"https://api.github.com/users/Abughazala/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Abughazala/subscriptions","organizations_url":"https://api.github.com/users/Abughazala/orgs","repos_url":"https://api.github.com/users/Abughazala/repos","events_url":"https://api.github.com/users/Abughazala/events{/privacy}","received_events_url":"https://api.github.com/users/Abughazala/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-11-14T16:06:09Z","updated_at":"2016-11-14T17:12:58Z","closed_at":"2016-11-14T17:12:58Z","body":"My problem is using the option given in the inet/linklayer/EthernetInterface.ned \r\n`string egressTCType = default(\"TrafficConditioner\"); // a module type implementing ~ITrafficConditioner for optional traffic conditioning of outgoing traffic`\r\n\r\nI created a new simulation in which hostA and hostB both sending to hostC (of type Etherhost2.ned) through a switch which is having an egress port containing classifer (made by me) forwarding to two queues and both queues are forwarding to PriorityScheduler which is connected to the output port of the output of egress port.\r\n\r\nhostA >>       switch  egress (classifier > queue1 > Scheduler)      >> hostC\r\n\r\nhostB >>       switch egress (classifier > queue2 > Scheduler)       >> hostC\r\n                     \r\nClassifier is working fine by forwarding the packets to the queues. The problem starts after the queue which invoke PacketEnqueued() function but priorityScheduler or EtherMAC is not reacting to this invoke.\r\n\r\nI tried to look for existing example and found in diffserve/simple example in the router a similar example using PPP port. instead of TrafficConditioner file it is QosEtherQueue  and it also contains in the output traffic direction (classifer + 2 queues + priorityScheduler) connected to PPP interface. \r\nThe difference is that PPP and PriorityScheduler react to the PacketEnqueued() invoked by the queues.\r\n\r\nAlthough both PPP.cc and EtherMACBase.cc include the same functions reacting to PacketEnqueued()\r\n\r\nI did a debug and found the first difference that \r\n\r\nin PPP.cc\r\n```\r\nclass INET_API PPP : public MACBase\r\n{\r\n  protected:\r\n    IPassiveQueue *queueModule = nullptr;\r\n    virtual void initialize(int stage) override;\r\n    ...\r\n}\r\nvoid PPP::initialize(int stage)\r\n{\r\n    MACBase::initialize(stage);\r\n    if (stage == INITSTAGE_LOCAL) {\r\n    ... }\r\n  queueModule = nullptr;\r\n\r\n        if (par(\"queueModule\").stringValue()[0]) {   // this condition is true in initialize\r\n            cModule *mod = getModuleFromPar<cModule>(par(\"queueModule\"), this);\r\n            if (mod->isSimple())\r\n                queueModule = check_and_cast<IPassiveQueue *>(mod);\r\n            else {\r\n                cGate *queueOut = mod->gate(\"out\")->getPathStartGate();\r\n                queueModule = check_and_cast<IPassiveQueue *>(queueOut->getOwnerModule());\r\n            }\r\n        }\r\n...\r\n}\r\n```\r\n\r\n\r\nWhile in EtherMacBase.cc it is as below,\r\n```\r\nclass INET_API EtherMACBase : public Mac Base\r\n{\r\n  public:\r\n    virtual void initializeQueueModule();\r\n...}\r\n\r\nvoid EtherMACBase::initializeQueueModule()\r\n{\r\n    queueModule = nullptr;\r\n    if (par(\"queueModule\").stringValue()[0]) {  // now this condition is false in the beginning\r\n        cModule *module = getModuleFromPar<cModule>(par(\"queueModule\"), this);\r\n        if (module->isSimple())\r\n            queueModule = check_and_cast<IPassiveQueue *>(module);\r\n        else {\r\n            cGate *queueOut = module->gate(\"out\")->getPathStartGate();\r\n            queueModule = check_and_cast<IPassiveQueue *>(queueOut->getOwnerModule()); \r\n        }\r\n\r\n        EV_DETAIL << \"Requesting first frame from queue module\\n\";\r\n        txQueue.setExternalQueue(queueModule);\r\n\r\n        if (txQueue.extQueue->getNumPendingRequests() == 0)\r\n            txQueue.extQueue->requestPacket();\r\n    }\r\n    else {\r\n        txQueue.setInternalQueue(\"txQueue\", par(\"txQueueLimit\").longValue());\r\n    }\r\n}\r\n```\r\nThis difference is causing a big change, I did a debug to see what is happening \r\nif you ran the simulation of diffserve you will find\r\n- Queue invoke PacketEnqueued()\r\n- Then PPP funtion mentioned above runs several times\r\n- then another function in PPP.cc runs as shown below,\r\n```\r\n    else if (stage == INITSTAGE_LINK_LAYER) {\r\n        // register our interface entry in IInterfaceTable\r\n        registerInterface();\r\n\r\n        // prepare to fire notifications\r\n        notifDetails.setInterfaceEntry(interfaceEntry);\r\n\r\n        // request first frame to send\r\n        if (queueModule && 0 == queueModule->getNumPendingRequests()) {\r\n            EV_DETAIL << \"Requesting first frame from queue module\\n\";\r\n            queueModule->requestPacket(); // invoke requestPacket() in PriorityScheduler\r\n        }\r\n    }\r\n```\r\n- Then PriorityScheduler send requestPacket()\r\n\r\nThe effect of this is that Priority Scheduler in my case always goes to the option of notifyListeners() while in diffserve case the SchedulePacket() is called due to the requestPacket() invoked by PPP.cc\r\n```\r\nvoid SchedulerBase::packetEnqueued(IPassiveQueue *inputQueue)\r\n{\r\n    Enter_Method(\"packetEnqueued(...)\");\r\n\r\n    if (packetsToBeRequestedFromInputs > 0) {\r\n        bool success = schedulePacket();\r\n        if (success)\r\n            packetsToBeRequestedFromInputs--;\r\n    }\r\n    else if (packetsRequestedFromUs == 0)\r\n        notifyListeners();\r\n}\r\n```\r\n\r\nTheoretically it is normal to have priority scheduler in the switch so using it with EtherMAC shouldn't be a problem.\r\n\r\nI am attaching my example files as well as my classifier and the TrafficConditioner file I am using\r\n[simulation.zip](https://github.com/inet-framework/inet/files/589719/simulation.zip)\r\n\r\n1.png is showing my simulation inside the egress port where queue is invoking PacketEnqueued() for each message received with no output from PriorityScheduler or EtherMAC interface connected to it.\r\n![1](https://cloud.githubusercontent.com/assets/12843879/20271054/b6a20936-aa89-11e6-8cfa-139a5d0d4746.png)\r\n\r\n13.png shows  only the diffserv example when PPP which is invoking requestPacket() although in initialization is always envoked by priorityScheduler() as explained above\r\n![13](https://cloud.githubusercontent.com/assets/12843879/20271147/1e4c7256-aa8a-11e6-8cd1-868be7966a08.png)\r\n\r\n\r\n\r\n"}}
{"actor":{"display_login":"Abughazala"}}