check_and_cast():在Omnet ++中无法转换(inet :: Indication *)ERROR以键入'inet :: Packet *'吗?

时间:2019-05-23 08:25:09

标签: omnet++ inet

我实现了一个继承自ApplicationBase和UdpSocket的新应用。在handleSelfMessage()函数中,我发送了广播以获取邻居,这很好用。在功能handleMessageWhenUp()中,我从邻居那里收到了问候消息,并且工作正常。
我的问题是:当我收到邻居发来的问候消息时,我得到了它的地址,因此我使用UdpSocket向他发送了XEDMsg,这时出现错误:

  

check_and_cast():无法转换(inet :: Indication *)ERROR来键入'inet :: Packet *'

这是我的代码:

class myApp : public ApplicationBase, public UdpSocket::ICallback
{
    protected:
        int localPort = -1, destPort = -1;
        bool dontFragment = false;
        const char *packetName = nullptr;

        simtime_t startTime;
        simtime_t stopTime;

        // state
        UdpSocket socket;
        cMessage *selfMsg = nullptr;
        cModule *host = nullptr;
        cMessage *event = nullptr;
        cPar *broadcastDelay = nullptr;
        unsigned int sequencenumber = 0;
        simtime_t helloInterval;
        IInterfaceTable *ift = nullptr;
        InterfaceEntry *interface80211ptr = nullptr;
        int interfaceId = -1;
        list<L3Address> neighbors;

        /********** XED **********/
        class XED
        {
          public:
            L3Address originatorAddr, destinationAddr;
            unsigned int random;
            XED(const L3Address& originatorAddr, const L3Address& destinationAddr, unsigned int random)
            : originatorAddr(originatorAddr), destinationAddr(destinationAddr), random(random) {};
            bool operator==(const XED& other) const
            {
                return this->originatorAddr == other.originatorAddr && this->destinationAddr == other.destinationAddr
                        && this->random == other.random;
            }
        };

        list<XED> lr,ls;

    protected:
        virtual int numInitStages() const override { return NUM_INIT_STAGES; }
        virtual void initialize(int stage) override;
        virtual void handleMessageWhenUp(cMessage *msg) override;

        void handleSelfMessage(cMessage *msg);

        // lifecycle
        virtual void handleStartOperation(LifecycleOperation *operation) override { start(); }
        virtual void handleStopOperation(LifecycleOperation *operation) override { stop(); }
        virtual void handleCrashOperation(LifecycleOperation *operation) override  { stop(); }
        void start();
        void stop();

        virtual void socketDataArrived(UdpSocket *socket, Packet *packet) override;
        virtual void socketErrorArrived(UdpSocket *socket, Indication *indication) override;
        virtual void socketClosed(UdpSocket *socket) override;

        virtual double generateRandom();

    public:
       myApp() {}
       ~myApp();
};

Define_Module(myApp);

myApp::~myApp()
{
    cancelAndDelete(selfMsg);
}

void myApp::initialize(int stage)
{
    ApplicationBase::initialize(stage);

    if (stage == INITSTAGE_LOCAL)
    {
        sequencenumber = 0;
        ift = getModuleFromPar<IInterfaceTable>(par("interfaceTableModule"), this);
        event = new cMessage("event");
        broadcastDelay = &par("broadcastDelay");
        helloInterval = par("helloInterval");
        localPort = par("localPort");
        destPort = par("destPort");
        packetName = par("packetName");
        startTime = par("startTime");
        stopTime = par("stopTime");
    }
    else if (stage == INITSTAGE_ROUTING_PROTOCOLS)
    {
        registerService(Protocol::manet, nullptr, gate("socketIn"));
        registerProtocol(Protocol::manet, gate("socketOut"), nullptr);
    }
}

void myApp::handleSelfMessage(cMessage *msg)
{
    if (msg == event)
    {
        auto hello = makeShared<HelloMsg>();
        Ipv4Address source = (interface80211ptr->getProtocolData<Ipv4InterfaceData>()->getIPAddress());
        hello->setChunkLength(b(128)); 
        hello->setSrcAddress(source);
        sequencenumber += 2;
        hello->setSequencenumber(sequencenumber);
        hello->setNextAddress(source);
        hello->setHopdistance(1);
        auto packet = new Packet("Hello", hello);
        packet->addTagIfAbsent<L3AddressReq>()->setDestAddress(Ipv4Address(255, 255, 255, 255));
        packet->addTagIfAbsent<L3AddressReq>()->setSrcAddress(source);
        packet->addTagIfAbsent<InterfaceReq>()->setInterfaceId(interface80211ptr->getInterfaceId());
        packet->addTagIfAbsent<PacketProtocolTag>()->setProtocol(&Protocol::manet);
        packet->addTagIfAbsent<DispatchProtocolReq>()->setProtocol(&Protocol::ipv4);

        send(packet, "socketOut");
        packet = nullptr;
        hello = nullptr;
        scheduleAt(simTime()+helloInterval+broadcastDelay->doubleValue(), event);
        bubble("Sending new hello message");
    }
}

void myApp::handleMessageWhenUp(cMessage *msg)
{
    if (msg->isSelfMessage())
    {
        handleSelfMessage(msg);
    }
    else if (check_and_cast<Packet *>(msg)->getTag<PacketProtocolTag>()->getProtocol() == &Protocol::manet)
    {

        auto recHello = staticPtrCast<HelloMsg>(check_and_cast<Packet *>(msg)->peekData<HelloMsg>()->dupShared());
        if (msg->arrivedOn("socketIn"))
        {
            bubble("Received hello message");
            Ipv4Address source = interface80211ptr->getProtocolData<Ipv4InterfaceData>()->getIPAddress();
            Ipv4Address src;
            unsigned int msgsequencenumber;
            int numHops;
            Ipv4Address next;

            src = recHello->getSrcAddress();
            msgsequencenumber = recHello->getSequencenumber();
            next = recHello->getNextAddress();
            numHops = recHello->getHopdistance();

            if (src == source)
            {
                EV_INFO << "Hello msg dropped. This message returned to the original creator.\n";
                delete msg;
                return;
            }
            else
            {
                neighbors.push_back(src);
                auto xed = makeShared<XedMsg>();
                Ipv4Address source = (interface80211ptr->getProtocolData<Ipv4InterfaceData>()->getIPAddress());
                xed->setChunkLength(b(128));
                xed->setSrcAddress(source);
                xed->setDstAddress(src);
                double random = generateRandom();
                xed->setRandom(random);
                auto packet = new Packet("XED", xed);
                socket.setOutputGate(gate("socketOut"));
                socket.setCallback(this);
                socket.bind(source, localPort);
                emit(packetSentSignal, packet);
                socket.sendTo(packet, src, destPort);

                packet = nullptr;
                xed = nullptr;
            }
            delete msg;
        }
        else
                throw cRuntimeError("Message arrived on unknown gate %s", msg->getArrivalGate()->getName());
    }
}

void myApp::start()
{
        int  num_80211 = 0;
        InterfaceEntry *ie;
        InterfaceEntry *i_face;
        const char *name;
        broadcastDelay = &par("broadcastDelay");
        for (int i = 0; i < ift->getNumInterfaces(); i++)
        {
            ie = ift->getInterface(i);
            name = ie->getInterfaceName();
            if (strstr(name, "wlan") != nullptr)
            {
                i_face = ie;
                num_80211++;
                interfaceId = i;
            }
        }

        if (num_80211 == 1)
            interface80211ptr = i_face;
        else
            throw cRuntimeError("Node has found %i 80211 interfaces", num_80211);
        scheduleAt(simTime() + uniform(0.0, par("maxVariance").doubleValue()), event);
}

double myApp::generateRandom()
{
    double lower_bound = 10000;
    double upper_bound = 100000;
    uniform_real_distribution<double> unif(lower_bound,upper_bound);
    default_random_engine re;
    double a_random_double = unif(re);
    return a_random_double;
}

void myApp::stop()
{
    cancelEvent(event);
}

void myApp::socketDataArrived(UdpSocket *socket, Packet *packet)
{
    emit(packetReceivedSignal, packet);
    EV_INFO << "Received packet: " << UdpSocket::getReceivedPacketInfo(packet) << endl;
    EV << "Data Arrived " << endl;
}

void myApp::socketErrorArrived(UdpSocket *socket, Indication *indication)
{
    EV << "Error Arrived" << endl;
    EV_WARN << "Ignoring UDP error report " << indication->getName() << endl;
    delete indication;
}

void myApp::socketClosed(UdpSocket *socket)
{
    EV << "Close socket" << endl;
}

0 个答案:

没有答案