обратный вызов (переустановка) модуля через другой модуль во время выполнения с изменением параметра

Я использую эту иерархию модулей:

Node: {udpApp[0]<->udp<->networkLayer->wlan[0]} and wlan[0]: {CNPCBeacon<->mac<->radio}

С некоторым параметром ini для udpApp как:
Я дал некоторый начальный параметр в INI-файле для udpApp как:

**.host*.numUdpApps = 2
**.host*.udpApp[0].typename = "UDPBasicApp"**.host*.udpApp[0].destAddresses = "gw1"**.host*.udpApp[0].startTime = 1.32s
**.host*.udpApp[0].stopTime = 1.48s

Но во время выполнения я хочу изменить startTime и stopTime для udpAPP [0] через модуль CNPCBeacon.

Поэтому я изменил CNPCBeacon.cc как: —

cModule* parentmod = getParentModule();
cModule* grantParentmod = parentmod->getParentModule();
cModule* udpmod = grantParentmod->getSubmodule("udpApp",0);
double varHoldingStartTime = udpmod->par("startTime").doubleValue();
double varGoldingStopTime = udpmod->par("stopTime").doubleValue();
varHoldingStartTime = SIMTIME_DBL(4.2);
varGoldingStopTime = SIMTIME_DBL(4.5);
udpmod->par("startTime").setDoubleValue(varHoldingStartTime);
udpmod->par("stopTime").setDoubleValue(varGoldingStopTime);
EV<<"New start and stop time is "<<udpmod->par("startTime").str()<<"\t"<<udpmod->par("stopTime").str()<<endl;`

Которые успешно меняют параметры. Однако это не инициирует udpApp[0] модуль снова. Поэтому я стараюсь использовать динамическое приведение этого модуля как:

UDPBasicApp* udpBasicMod = dynamic_cast<UDPBasicApp*>(udpmod);
sendTimer = new cMessage("sendTimer");
scheduleAt(iniSchduleTime, sendTimer);

и это привело к следующей ошибке:

ошибка в модуле (CNPCBeacon) BSoneNode.gw1.wlan [0] .CNPCBeacon (id = 23) в событии # 1496, t = 4: scheduleAt () модуля (UDPBasicApp) BSoneNode.gw1.udpApp [0], вызванного в контексте модуля (CNPCBeacon) BSoneNode.gw1.wlan [0] .CNPCBeacon: в методе, вызываемом из последнего модуля, отсутствует метод Enter_Method () или Enter_Method_Silent () ?.

Есть ли также какой-либо другой способ создания экземпляра модуля через другой субмодуль.

Спасибо за эту помощь.

1

Решение

Я немного растерялся в иерархии и отношениях между вашими модулями и подмодулями, однако я думаю, что если вы хотите динамически создавать (или заново создавать) модуль, вы можете использовать встроенный подход, предложенный OMNeT ++: https://omnetpp.org/doc/omnetpp/manual/usman.html#sec186

Возможно, вы могли бы использовать однострочник сразу после того, как вы (повторно) определили значения параметров:

cModuleType *moduleType = cModuleType::get("foo.nodes.WirelessNode");
cModule *mod = moduleType->createScheduleInit("node", this);

С другой стороны, вы получаете сообщение об ошибке: Enter_Method() и / или Enter_Method_Silent()

Эти макросы следует использовать в случае, если вы пытаетесь вызвать функцию модуля (пример X::get()) из другого модуля:

Y::doSmthWithXsGet()
{
x->get();
}

Чтобы это работало Enter_Method() (или же Enter_Method_Silent()) должен быть написан в начале X::get()

X::get()
{
Enter_Method();
/* rest of the code */
}

Ты можешь читать Прямые вызовы методов раздел пользователя OMNeT ++, чтобы увидеть, что это значит.


Странно то, что вы получаете эту ошибку для scheduleAt() метод, который является методом, который принадлежит к фундаментальному классу OMNeT ++ cSimpleModule, Это означает, что для использования этого метода в вашем классе вам придется наследовать от cSimpleModule в вашем определении класса.

Может быть, просто сделать что-то вроде:

class MyCurrentClass: public cSimpleModule
{
/* further class definition */
};

… может решить вашу проблему.

0

Другие решения

Решением для повторной инициализации модуля (целевого модуля) через другой модуль (запрашивающий модуль) является создание функции handleParamterChange () в целевом модуле. handleParameterChange () используется для перечитывания измененного параметра во время настройки. Однако он не запустит событие scheduleAt () для повторной инициализации события для целевого модуля. Поэтому я добавил событие scheduleAt () в эту функцию как:

void UDPBasicApp:: handleParameterChange(const char* parname)
{
if(parname)
{
if((strcmp(parname, "startTime")==0) &&
(startTime !=  par("startTime").doubleValue())
startTime = par("startTime").doubleValue();
if(strcmp(parname,"stopTime")==0)&&
(stopTime !=  par("stopTime").doubleValue())
{
stopTime = par("stopTime").doubleValue();
selfMsg->setKind(START);
scheduleAt((simtime_t)(startTime), selfMsg);
}
}

Обратите внимание, что selfMsg определен в функции инициализации UdpBasciApp.cc в среде INET.

0

По вопросам рекламы [email protected]