178 auto destination = flow.endDevice->module;
179 auto pcp = flow.startApplication->pcp;
180 b packetLength = flow.startApplication->packetLength;
181 std::deque<std::tuple<std::string, simtime_t, std::vector<std::string>>> todos;
182 todos.push_back({startNetworkNodeName, startTime, {}});
183 while (!todos.empty()) {
184 auto todo = todos.front();
186 for (
auto pathFragment : flow.pathFragments) {
187 if (!strcmp(pathFragment->networkNodes.front()->module->getFullName(), std::get<0>(todo).c_str())) {
188 simtime_t nextGateOpenTime = std::get<1>(todo);
189 std::vector<std::string> extendedPath = std::get<2>(todo);
190 for (
int i = 0; i < pathFragment->networkNodes.size() - 1; i++) {
191 auto networkNodeName = pathFragment->networkNodes[i]->module->getFullName();
192 extendedPath.push_back(networkNodeName);
193 auto networkNode = getParentModule()->getSubmodule(networkNodeName);
195 auto link = (Link *)
findLinkOut(node, pathFragment->networkNodes[i + 1]->module->getFullName());
196 auto interface = link->sourceInterface;
197 auto networkInterface = interface->networkInterface;
198 auto& interfaceSchedule = interfaceSchedules[networkInterface];
199 bps interfaceDatarate =
bps(networkInterface->getDatarate());
200 simtime_t transmissionDuration =
s(packetLength / interfaceDatarate).get();
201 simtime_t interFrameGap =
s(
b(96) / interfaceDatarate).get();
202 auto channel =
dynamic_cast<cDatarateChannel *
>(networkInterface->getTxTransmissionChannel());
203 simtime_t propagationDelay = channel !=
nullptr ? channel->getDelay() : 0;
204 simtime_t gateOpenDuration = transmissionDuration;
205 simtime_t gateOpenTime = nextGateOpenTime;
206 simtime_t gateCloseTime = gateOpenTime + gateOpenDuration;
207 for (
int i = 0; i < interfaceSchedule.size(); i++) {
208 if (interfaceSchedule[i].gateCloseTime + interFrameGap <= gateOpenTime || gateCloseTime + interFrameGap <= interfaceSchedule[i].gateOpenTime)
211 gateOpenTime = interfaceSchedule[i].gateCloseTime + interFrameGap;
212 gateCloseTime = gateOpenTime + gateOpenDuration;
216 simtime_t extraDelay = gateOpenTime - nextGateOpenTime;
219 throw cRuntimeError(
"Gate scheduling doesn't fit into cycle duration");
221 entry.gateOpenIndex = flow.gateIndex;
222 entry.gateOpenTime = gateOpenTime;
223 entry.gateCloseTime = gateCloseTime;
224 interfaceSchedule.push_back(entry);
225 nextGateOpenTime = gateCloseTime + propagationDelay;
227 auto endNetworkNodeName = pathFragment->networkNodes.back()->module->getFullName();
228 if (endNetworkNodeName == destination->getFullName() && nextGateOpenTime - startTime > flow.startApplication->maxLatency)
229 throw cRuntimeError(
"Cannot fit scheduling int maximum allowed latency");
230 if (endNetworkNodeName != destination->getFullName() &&
std::find(extendedPath.begin(), extendedPath.end(), endNetworkNodeName) == extendedPath.end())
231 todos.push_back({endNetworkNodeName, nextGateOpenTime, extendedPath});