Switch to unified view

a b/src/DAF/IRM/IRM.cc
1
//
2
// This program is free software: you can redistribute it and/or modify
3
// it under the terms of the GNU Lesser General Public License as published by
4
// the Free Software Foundation, either version 3 of the License, or
5
// (at your option) any later version.
6
// 
7
// This program is distributed in the hope that it will be useful,
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
// GNU Lesser General Public License for more details.
11
// 
12
// You should have received a copy of the GNU Lesser General Public License
13
// along with this program.  If not, see http://www.gnu.org/licenses/.
14
// 
15
16
17
#include "IRM.h"
18
19
Define_Module(IRM);
20
21
IRM::IRM() {
22
}
23
24
IRM::~IRM() {
25
}
26
27
void IRM::initPointers() {
28
    ConTable = ModuleAccess<ConnectionTable>(MOD_CONNTABLE).get();
29
    DifAllocator = ModuleAccess<DA>(MOD_DA).get();
30
}
31
32
void IRM::initialize() {
33
    initPointers();
34
    initSignalsAndListeners();
35
}
36
37
void IRM::handleMessage(cMessage* msg) {
38
    if (!msg->isSelfMessage()) {
39
        //Find output gate based on input
40
        cGate* g = ConTable->findOutputGate(msg->getArrivalGate());
41
        //Send out if gate exist
42
        if (g)
43
            send(msg, g);
44
        else {
45
            EV << "Received message but destination gate is not in the ConnectionTable!" << endl;
46
        }
47
    }
48
    //Process self-message
49
    else {
50
51
    }
52
53
}
54
55
void IRM::initSignalsAndListeners() {
56
    cModule* catcher = this->getParentModule()->getParentModule();
57
58
    //Signals that this module emits
59
    sigIRMAllocReq      = registerSignal(SIG_IRM_AllocateRequest);
60
    sigIRMDeallocReq    = registerSignal(SIG_IRM_DeallocateRequest);
61
    sigIRMAllocResPosi  = registerSignal(SIG_IRM_AllocateResponsePositive);
62
    sigIRMAllocResNega  = registerSignal(SIG_IRM_AllocateResponseNegative);
63
64
    //Signals that this module is processing
65
    //  AllocationResponseNegative from FA
66
    lisAllocResNegaFa = new LisIRMAllocResNegaFa(this);
67
    catcher->subscribe(SIG_FA_AllocateResponseNegative, this->lisAllocResNegaFa);
68
    //  AllocationResponseNegative from FAI
69
    lisAllocResNegaFai = new LisIRMAllocResNegaFai(this);
70
    catcher->subscribe(SIG_FAI_AllocateResponseNegative, this->lisAllocResNegaFai);
71
    //  AllocationRequest from FAI
72
    this->lisAllocReqFai = new LisIRMAllocReqFai(this);
73
    catcher->subscribe(SIG_FAI_AllocateRequest, this->lisAllocReqFai);
74
    //  Allocate Request from App
75
    this->lisAllocReq = new LisIRMAllocReq(this);
76
    catcher->subscribe(SIG_AE_AllocateRequest, this->lisAllocReq);
77
    //  Deallocate Request from App
78
    this->lisDeallocReq = new LisIRMDeallocReq(this);
79
    catcher->subscribe(SIG_AE_DeallocateRequest, this->lisDeallocReq);
80
}
81
82
bool IRM::createBindings(Flow* flow) {
83
    EV << "Attempts to create bindings and bind registration of gates"<< endl;
84
    //Retrieve IPC process with allocated flow and prepared bindings
85
86
    cModule* Ipc = ConTable->findEntryByFlow(flow)->getIpc();
87
    cModule* Ap = this->getParentModule();
88
89
    //Create connections
90
91
    //  Retrieve IPC gates
92
    std::ostringstream nam1;
93
    nam1 << GATE_NORTHIO << flow->getSrcPortId();
94
    cGate* g1i = Ipc->gateHalf(nam1.str().c_str(), cGate::INPUT);
95
    cGate* g1o = Ipc->gateHalf(nam1.str().c_str(), cGate::OUTPUT);
96
97
    //   Add AP gates
98
    std::ostringstream nam2;
99
    nam2 << GATE_SOUTHIO << flow->getSrcPortId();
100
    Ap->addGate(nam2.str().c_str(), cGate::INOUT, false);
101
    cGate* g2i = Ap->gateHalf(nam2.str().c_str(), cGate::INPUT);
102
    cGate* g2o = Ap->gateHalf(nam2.str().c_str(), cGate::OUTPUT);
103
104
    //   Add IRM gates
105
    this->addGate(nam2.str().c_str(), cGate::INOUT, false);
106
    cGate* g3i = this->gateHalf(nam2.str().c_str(), cGate::INPUT);
107
    cGate* g3o = this->gateHalf(nam2.str().c_str(), cGate::OUTPUT);
108
109
    //TODO: Status check
110
111
    //   Connect gates together
112
    g1o->connectTo(g2o);
113
    g2o->connectTo(g3i);
114
115
    g3o->connectTo(g2i);
116
    g2i->connectTo(g1i);
117
118
    //Set south-half of the routing in ConnectionTable
119
    bool status = ConTable->setSouthGates(flow, g3i, g3o);
120
121
    return status;
122
}
123
124
void IRM::receiveAllocationRequest(cObject* obj) {
125
    Enter_Method("receiveAllocateRequest()");
126
    EV << this->getFullPath() << " received Allocation Request" << endl;
127
128
    Flow* flow = dynamic_cast<Flow*>(obj);
129
130
    //Ask DA which IPC to use to reach dst App
131
    DirectoryEntry* de = DifAllocator->resolveApn(flow->getDstApni().getApn());
132
133
    if (de == NULL) {
134
        EV << "DA does not know target application" << endl;
135
        return;
136
    }
137
138
    //TODO: Vesely - Now using first available APN to DIFMember mapping
139
    Address addr = de->getSupportedDifs().front();
140
141
    //TODO: Vesely - New IPC must be enrolled or DIF created
142
    if (!DifAllocator->isDifLocal(addr.getDifName())) {
143
        EV << "Local CS does not have any IPC in DIF " << addr.getDifName() << endl;
144
        return;
145
    }
146
147
    //Retrieve DIF's local IPC member
148
    cModule* targetIpc = DifAllocator->getDifMember(addr.getDifName());
149
150
    //Store info into ConnectionTable
151
    ConTable->setFa(flow, DifAllocator->findFaInsideIpc(targetIpc));
152
153
154
    //Command target FA to allocate flow
155
    bool status = ConTable->getFa(flow)->receiveAllocateRequest(flow);
156
157
    //If AllocationRequest ended by creating connections
158
    if (status)
159
        status = createBindings(flow);
160
    //Allocation either failed OR app not found
161
    else
162
       EV << "Flow not allocated!\n" << flow << endl;
163
164
    //TODO: Vesely - Change ConnectionTable status
165
}
166
167
void IRM::receiveDeallocationRequest(cObject* obj) {
168
    Enter_Method("receiveDeallocateRequest()");
169
    EV << this->getFullPath() << " received DeallocationRequest" << endl;
170
    Flow* fl = dynamic_cast<Flow*>(obj);
171
    signalizeDeallocateRequest(fl);
172
}
173
174
void IRM::receiveAllocationResponseNegativeAppNotFound(cObject* obj) {
175
    EV << this->getFullPath() << " received Negative Allocation Response App not found" << endl;
176
}
177
178
void IRM::receiveAllocationResponseNegative(cObject* obj) {
179
    //Flow* fl = dynamic_cast<Flow*>(obj);
180
    EV << this->getFullPath() << " received Negative Allocation Response" << endl;
181
}
182
183
void IRM::receiveAllocationRequestFromFAI(cObject* obj) {
184
    //EV << this->getFullPath() << " received AllocationRequest from FAI" << endl;
185
    Flow* fl = dynamic_cast<Flow*>(obj);
186
    //TODO: Vesely - Simulate AllocationResponses
187
    if (true) {
188
        this->signalizeAllocateResponsePositive(fl);
189
    }
190
    else {
191
        this->signalizeAllocateResponseNegative(fl);
192
    }
193
}
194
195
void IRM::signalizeAllocateRequest(Flow* flow) {
196
    //EV << "!!!!VYemitovano" << endl;
197
    //EV << "Emits AllocReq Flow = " << flow->getSrcApni() << "_" << flow->getDstApni() << endl;
198
    emit(sigIRMAllocReq, flow);
199
}
200
201
void IRM::signalizeDeallocateRequest(Flow* flow) {
202
    emit(sigIRMDeallocReq, flow);
203
}
204
205
void IRM::signalizeAllocateResponsePositive(Flow* flow) {
206
    emit(sigIRMAllocResPosi, flow);
207
}
208
209
void IRM::signalizeAllocateResponseNegative(Flow* flow) {
210
    emit(sigIRMAllocResNega, flow);
211
}