Omnet ++ - Ieee8022LlcSocket - ethe rnet реализация - PullRequest
0 голосов
/ 03 марта 2020

Я пытаюсь реализовать модуль, способный принимать и отправлять Ethe rnet пакеты, аналогичные EtherApplications в Inet. Я смог немного поэкспериментировать и создал модуль coumpound, в котором есть два приложения: одно получает пакеты, а другое отправляет их. Однако моя главная цель - сделать одно приложение, которое может сделать и то, и другое. Изучив код обоих EtherAppServer и EtherAppClient , я не вижу причин, по которым EtherAppClient не может принимать пакеты от других EtherAppClients . Я также создал сеть, равную twoHosts в папке inet / examples / Ethe rnet и, если вы удалите EtherAppServer из сети, один хост отправляет пакет, но когда другой получает, модули ll c выводят сообщение: "Получено (inet :: Packet) X от нижнего уровня", "Неизвестный протокол, отбрасывание пакета", Я просто хотел понять, почему это происходит.

Код для моих приложений следующий:

Отправитель:

Define_Module(masterDispatcher);

void masterDispatcher::initialize(int stage)
{
    if (stage == inet::INITSTAGE_LOCAL) {
        llcSocket.setOutputGate(gate("lowerLayerOut"));
        llcSocket.setCallback(this);
    }

    else if(stage ==inet::INITSTAGE_APPLICATION_LAYER){
        llcSocket.open(-1, 0xf0);
        destMACAddress = destMACAddress.BROADCAST_ADDRESS;
    }
}

void masterDispatcher::handleMessage(cMessage *msg)
{
    std:: string GateName = msg -> getArrivalGate() -> getFullName();
    std:: string Gate1 = "in";

    if(Gate1.compare(GateName.substr(0,GateName.length())) == 0){
        sendPacket();
    }
    else{
        llcSocket.processMessage(msg);
    }
}


void masterDispatcher::socketClosed(inet::Ieee8022LlcSocket *socket)
{
    //if (operationalState == State::STOPPING_OPERATION && !llcSocket.isOpen())
     //   inet::startActiveOperationExtraTimeOrFinish(par("stopOperationExtraTime"));
}

void masterDispatcher::sendPacket()
{

    EV_INFO << "Generating packet " << "'\n";

    inet::Packet *datapacket = new inet::Packet("test", inet::IEEE802CTRL_DATA);

    const auto& frame = inet::makeShared<EthernetFrame>();
    frame->setChunkLength(inet::B(60));
    frame->setTestEther(24);
    datapacket->insertAtBack(frame);

    // Header
    datapacket->addTagIfAbsent<inet::MacAddressReq>()->setDestAddress(destMACAddress);


    auto ieee802SapReq = datapacket->addTagIfAbsent<inet::Ieee802SapReq>();
    ieee802SapReq->setSsap(0xf0);
    ieee802SapReq->setDsap(0xf1);

    emit(inet::packetSentSignal, datapacket);
    llcSocket.send(datapacket);
}



void masterDispatcher::socketDataArrived(inet::Ieee8022LlcSocket*, inet::Packet *msg)
{
    EV_INFO << "Received packet" << msg->getName() << "'\n";

    emit(inet::packetReceivedSignal, msg);

    delete msg;
}

void masterDispatcher::finish()
{
    cancelAndDelete(timerMsg);
    timerMsg = nullptr;
}

Получатель:

Define_Module(rec);

void rec::initialize(int stage)
{
    if (stage == inet::INITSTAGE_LOCAL) {
        localSap = par("localSAP");

        // socket
        llcSocket.setOutputGate(gate("out"));
        llcSocket.setCallback(this);

    }
    else if(stage == inet::INITSTAGE_APPLICATION_LAYER)
        registerDsap(localSap);

}

void rec::socketClosed(inet::Ieee8022LlcSocket *socket)
{
 //   if (operationalState == State::STOPPING_OPERATION && !llcSocket.isOpen())
   //     startActiveOperationExtraTimeOrFinish(par("stopOperationExtraTime"));
}

void rec::handleMessage(cMessage *msg)
{
    llcSocket.processMessage(msg);
}

void rec::socketDataArrived(inet::Ieee8022LlcSocket*, inet::Packet *msg)
{
    EV_INFO << "Received packet `" << msg->getName() << "'\n";
    const auto& req = msg->peekAtFront<EthernetFrame>();
    if (req == nullptr)
        throw cRuntimeError("data type error: not an EtherAppReq arrived in packet %s", msg->str().c_str());
    emit(inet::packetReceivedSignal, msg);

    inet::MacAddress srcAddr = msg->getTag<inet::MacAddressInd>()->getSrcAddress();
    int srcSap = msg->getTag<inet::Ieee802SapInd>()->getSsap();

    EV << "REC VAL:" << req-> getTestEther() << "\n";
    delete msg;
}

void rec::sendPacket(inet::Packet *datapacket, const inet::MacAddress& destAddr, int destSap)
{
    /*datapacket->addTagIfAbsent<MacAddressReq>()->setDestAddress(destAddr);
    auto ieee802SapReq = datapacket->addTagIfAbsent<Ieee802SapReq>();
    ieee802SapReq->setSsap(localSap);
    ieee802SapReq->setDsap(destSap);

    emit(packetSentSignal, datapacket);
    llcSocket.send(datapacket);
    packetsSent++;*/
}

void rec::registerDsap(int dsap)
{
    EV_DEBUG << getFullPath() << " registering DSAP " << dsap << "\n";

    llcSocket.open(-1, dsap);
}

void rec::finish()
{
}

Это реализованный модуль и сеть : используемые сетевые и составные модули . В этой тестовой сети простой модуль s от master [0] отправляет сообщение диспетчеру , заставляя его отправлять пакет. master [1 получает пакет с модулем server и печатает полученное значение. Я хотел бы подчеркнуть, что оба модуля - отправитель и получатель (диспетчер и сервер) - это cSimpleModules , а не ApplicationBase , но я не думаю, что это проблема, так как я тестировал с twoHosts сеть от inet.

Буду признателен за любую помощь.

...