星期六, 6月 06, 2015

Omnet++ INET UDPBasicApp生命週期觀察

Summary:

1. UDPBasicApp::initialize(int stage)
2. if (stage == INITSTAGE_LOCAL) {
   selfMsg = new cMessage("sendTimer");

2.1 selfMsg變數表「排程狀態」,用來當事件參數 OperationalBase::handleMessage(cMessage *message),做狀態機,控制用。

3. stage ++
4. 直到stage=12, i.e,  isInitializeStage(stage)==true, 執行     handleNodeStart(nullptr);
5.  handleNodeStart,     排程
selfMsg->setKind(START);
        scheduleAt(start, selfMsg);

以上是戴入omnet.ini就會執行的code

6. 至於真正的封包排程, schedule要等到按run才會執行, 此時 if (isOperational)為真
7. 事件發生,執行handleMessage, 會再呼叫  handleMessageWhenUp(message);
8. 會再呼叫processStart(), 正式app的啟動,
     case START:
                processStart();
                break;
9. processStart()呼叫 processSend();
10.  processSend()依設定的sendInterval參數, 送出封包後,再排程下次傳送時間點 
11. 重覆7-11, 執行
            case SEND:
                processSend();


                break;


-----------------------------------------------------------------
Details:

omnet++載入時omnet.ini會執行

0. stage=0, i.e, INITSTAGE_LOCAL
1. 一開始初始化階段,執行程式碼
   ApplicationBase::initialize(stage);
  if (stage == INITSTAGE_LOCAL) {
  EV_INFO << "hsuth: INITSTAGE_LOCAL"<< endl;
程式碼,進行初始化。
}

2. 每次跑完stage++
3. 在stage=12時, isInitializeStage(stage)會傳回 true, 此時會跑 handleNodeStart(nullptr);

void OperationalBase::initialize(int stage)
{
    if (isInitializeStage(stage)) {
        NodeStatus *nodeStatus = dynamic_cast(findContainingNode(this)->getSubmodule("status"));
        setOperational(!nodeStatus || nodeStatus->getState() == NodeStatus::UP);
        if (isOperational) {
            EV_INFO << "hsuth: OperationalBase::handleNodeStart"<< endl;
            handleNodeStart(nullptr);
        }
    }
}
會呼叫
bool UDPBasicApp::handleNodeStart(IDoneCallback *doneCallback)
{
    EV_INFO << "hsuth: UDPBasicApp::handleNodeStart"<< endl;
    simtime_t start = std::max(startTime, simTime());
    if ((stopTime < SIMTIME_ZERO) || (start < stopTime) || (start == stopTime && startTime == stopTime)) {
        selfMsg->setKind(START);
        scheduleAt(start, selfMsg);
    }
    return true;
}


當按run時,才會跑排程
排程,時間到呼叫handleMessage, 在
void OperationalBase::handleMessage(cMessage *message)
{
    if (isOperational)
        handleMessageWhenUp(message);
    else
        handleMessageWhenDown(message);
}
會呼叫 UDPBasicApp::handleMessageWhenUp

接著會跑到
void UDPBasicApp::handleMessageWhenUp(cMessage *msg)
{
    if (msg->isSelfMessage()) {
        ASSERT(msg == selfMsg);
        switch (selfMsg->getKind()) {
            case START:
                processStart();
                break;

執行
void UDPBasicApp::processStart()
{

if (!destAddresses.empty()) {
        selfMsg->setKind(SEND);
        processSend();
    }

}

執行

void UDPBasicApp::processSend()
{
    sendPacket();
    simtime_t d = simTime() + par("sendInterval").doubleValue();
    if (stopTime < SIMTIME_ZERO || d < stopTime) {
        selfMsg->setKind(SEND);
        scheduleAt(d, selfMsg);
    }
    else {
        selfMsg->setKind(STOP);
        scheduleAt(stopTime, selfMsg);
    }

}

重覆


void UDPBasicApp::handleMessageWhenUp(cMessage *msg)
{
    if (msg->isSelfMessage()) {
        ASSERT(msg == selfMsg);
        switch (selfMsg->getKind()) {
            case START:
                processStart();
                break;

            case SEND:
                processSend();
                break;

取得sendInterval,一直重覆,直到simulation end

void UDPBasicApp::processSend()
{
    sendPacket();
    simtime_t d = simTime() + par("sendInterval").doubleValue();
    if (stopTime < SIMTIME_ZERO || d < stopTime) {
        selfMsg->setKind(SEND);
        scheduleAt(d, selfMsg);
    }
    else {
        selfMsg->setKind(STOP);
        scheduleAt(stopTime, selfMsg);
    }
}

沒有留言: