97 bool isReuseD2DEnabled()
override
99 return d2dEnbHelper_.getReuseD2D();
102 bool isReuseD2DMultiEnabled()
override
104 return d2dEnbHelper_.getReuseD2DMulti();
107 ConflictGraph *getConflictGraph()
override
109 return d2dEnbHelper_.getConflictGraph();
112 void deleteHarqBuffersMirrorD2D(MacNodeId txPeer, MacNodeId rxPeer)
override;
123 HarqBuffersMirrorD2D *getHarqBuffersMirrorD2D(GHz carrierFrequency)
override;
126 virtual void deleteHarqBuffersMirrorD2D(MacNodeId nodeId);
129 void sendModeSwitchNotification(MacNodeId srcId, MacNodeId dst, LteD2DMode oldMode, LteD2DMode newMode)
override;
131 bool isMsHarqInterrupt()
override {
return d2dEnbHelper_.getMsHarqInterrupt(); }
137 Base::initialize(stage);
138 if (stage == inet::INITSTAGE_LOCAL) {
139 connectionControl_.reference(
this,
"connectionControlModule",
true);
140 d2dBinder_.reference(
this,
"d2dBinderModule",
true);
141 d2dEnbHelper_.initWatches();
146 if (stage == inet::INITSTAGE_LAST) {
147 d2dEnbHelper_.setReuseD2D(this->par(
"reuseD2D"));
148 d2dEnbHelper_.setReuseD2DMulti(this->par(
"reuseD2DMulti"));
150 if (d2dEnbHelper_.getReuseD2D() || d2dEnbHelper_.getReuseD2DMulti()) {
151 d2dEnbHelper_.setConflictGraphUpdatePeriod(this->par(
"conflictGraphUpdatePeriod"));
153 d2dEnbHelper_.createDistanceBasedConflictGraph(this->binder_, d2dBinder_.get(), this->par(
"conflictGraphThreshold"),
154 this->par(
"conflictGraphD2DInterferenceRadius"), this->par(
"conflictGraphD2DMultiTxRadius"), this->par(
"conflictGraphD2DMultiInterferenceRadius"));
156 this->scheduleAt(NOW + 0.05,
new cMessage(
"updateConflictGraph"));
159 else if (stage == INITSTAGE_SIMU5G_AMC_SETUP) {
160 bool usePreconfiguredTxParams = this->par(
"usePreconfiguredTxParams");
161 Cqi d2dCqi = this->par(
"d2dCqi");
162 if (usePreconfiguredTxParams)
163 check_and_cast<AmcPilotD2D *>(this->amc_->getPilot())->setPreconfiguredTxParams(d2dCqi);
165 d2dEnbHelper_.setMsHarqInterrupt(this->par(
"msHarqInterrupt").boolValue());
166 d2dEnbHelper_.setMsClearRlcBuffer(this->par(
"msClearRlcBuffer").boolValue());
171void D2dEnbMacBase<Base>::macHandleFeedbackPkt(cPacket *pktAux)
173 auto pkt = check_and_cast<inet::Packet *>(pktAux);
174 auto fb = pkt->peekAtFront<LteFeedbackPkt>();
175 auto lteInfo = pkt->getTag<UserControlInfo>();
177 std::map<MacNodeId, LteFeedbackDoubleVector> fbMapD2D = fb->getLteFeedbackDoubleVectorD2D();
180 if (!fbMapD2D.empty()) {
182 ID2dAmc *d2dAmc = check_and_cast<ID2dAmc *>(this->amc_);
184 MacNodeId
id = fb->getSourceNodeId();
187 for (
const auto& mapIt : fbMapD2D) {
188 MacNodeId peerId = mapIt.first;
189 for (
const auto& it : mapIt.second) {
190 for (
const auto& jt : it) {
191 if (!jt.isEmptyFeedback()) {
192 d2dAmc->pushFeedbackD2D(
id, jt, peerId, lteInfo->getCarrierFrequency());
198 Base::macHandleFeedbackPkt(pkt);
204 if (msg->isSelfMessage() && msg->isName(
"D2DModeSwitchNotification")) {
205 cPacket *pkt = check_and_cast<cPacket *>(msg);
206 d2dEnbHelper_.macHandleD2DModeSwitch(pkt);
209 else if (msg->isSelfMessage() && msg->isName(
"updateConflictGraph")) {
211 d2dEnbHelper_.computeConflictGraph();
213 this->scheduleAt(NOW + d2dEnbHelper_.getConflictGraphUpdatePeriod(), msg);
216 Base::handleMessage(msg);
220HarqBuffersMirrorD2D *D2dEnbMacBase<Base>::getHarqBuffersMirrorD2D(GHz carrierFrequency)
222 return d2dEnbHelper_.getHarqBuffersMirrorD2D(carrierFrequency);
228 Base::deleteQueues(nodeId);
229 deleteHarqBuffersMirrorD2D(nodeId);
233void D2dEnbMacBase<Base>::deleteHarqBuffersMirrorD2D(MacNodeId nodeId)
235 d2dEnbHelper_.deleteHarqBuffersMirrorD2D(nodeId);
239void D2dEnbMacBase<Base>::deleteHarqBuffersMirrorD2D(MacNodeId txPeer, MacNodeId rxPeer)
241 d2dEnbHelper_.deleteHarqBuffersMirrorD2D(txPeer, rxPeer);
245void D2dEnbMacBase<Base>::sendModeSwitchNotification(MacNodeId srcId, MacNodeId dstId, LteD2DMode oldMode, LteD2DMode newMode)
247 Enter_Method_Silent(
"sendModeSwitchNotification");
249 EV << NOW <<
" D2dEnbMacBase::sendModeSwitchNotification - " << srcId <<
" --> " << dstId <<
" going from " << d2dModeToA(oldMode) <<
" to " << d2dModeToA(newMode) << endl;
253 auto pktTx =
new inet::Packet(
"D2DModeSwitchNotification");
255 auto switchPktTx = inet::makeShared<D2DModeSwitchNotification>();
256 switchPktTx->setTxSide(
true);
257 switchPktTx->setPeerId(dstId);
258 switchPktTx->setOldMode(oldMode);
259 switchPktTx->setNewMode(newMode);
260 switchPktTx->setInterruptHarq(d2dEnbHelper_.getMsHarqInterrupt());
261 switchPktTx->setClearRlcBuffer(d2dEnbHelper_.getMsClearRlcBuffer());
263 pktTx->addTagIfAbsent<UserControlInfo>()->setSourceId(this->nodeId_);
264 pktTx->addTagIfAbsent<UserControlInfo>()->setDestId(srcId);
265 pktTx->addTagIfAbsent<UserControlInfo>()->setFrameType(D2DMODESWITCHPKT);
267 pktTx->insertAtFront(switchPktTx);
268 auto switchPktTx_local = pktTx->dup();
269 this->sendLowerPackets(pktTx);
271 auto pktRx =
new inet::Packet(
"D2DModeSwitchNotification");
272 auto switchPktRx = inet::makeShared<D2DModeSwitchNotification>();
273 switchPktRx->setTxSide(
false);
274 switchPktRx->setPeerId(srcId);
275 switchPktRx->setOldMode(oldMode);
276 switchPktRx->setNewMode(newMode);
277 switchPktRx->setInterruptHarq(d2dEnbHelper_.getMsHarqInterrupt());
278 switchPktRx->setClearRlcBuffer(d2dEnbHelper_.getMsClearRlcBuffer());
280 pktRx->addTagIfAbsent<UserControlInfo>()->setSourceId(this->nodeId_);
281 pktRx->addTagIfAbsent<UserControlInfo>()->setDestId(dstId);
282 pktRx->addTagIfAbsent<UserControlInfo>()->setFrameType(D2DMODESWITCHPKT);
283 pktRx->insertAtFront(switchPktRx);
285 auto switchPktRx_local = pktRx->dup();
286 this->sendLowerPackets(pktRx);
288 this->scheduleAt(NOW + TTI, switchPktTx_local);
289 this->scheduleAt(NOW + TTI, switchPktRx_local);
295 Base::flushHarqBuffers();
298 for (
auto& mirr_mit : d2dEnbHelper_.getHarqBuffersMirrorD2DMap()) {
299 for (
auto& mirr_it : mirr_mit.second)
300 mirr_it.second->markSelectedAsWaiting();
307 Direction dir = (Direction)userInfo->getDirection();
308 if (dir == D2D || dir == D2D_MULTI)
309 return new LteHarqBufferRxD2D(this->harqProcesses_,
this, this->binder_, src, (dir == D2D_MULTI));
310 return Base::createRxHarqBuffer(src, userInfo);
316 auto pkt = check_and_cast<inet::Packet *>(pktAux);
317 auto userInfo = pkt->getTag<UserControlInfo>();
318 if (userInfo->getFrameType() == HARQPKT) {
319 MacNodeId src = userInfo->getSourceId();
320 GHz carrierFrequency = userInfo->getCarrierFrequency();
323 auto hfbpkt = pkt->peekAtFront<LteHarqFeedback>();
324 if (!hfbpkt->getD2dFeedback()) {
330 auto mfbpkt = pkt->peekAtFront<LteHarqFeedbackMirror>();
331 MacNodeId d2dSender = mfbpkt->getD2dSenderId();
332 MacNodeId d2dReceiver = mfbpkt->getD2dReceiverId();
333 D2DPair pair(d2dSender, d2dReceiver);
334 auto& harqBuffersMirrorD2D = d2dEnbHelper_.getHarqBuffersMirrorD2DMap();
335 HarqBuffersMirrorD2D::iterator hit = harqBuffersMirrorD2D[carrierFrequency].find(pair);
336 EV << NOW <<
"D2dEnbMacBase::fromPhy - node " << this->nodeId_ <<
" Received HARQ Feedback pkt (mirrored)" << endl;
337 if (hit == harqBuffersMirrorD2D[carrierFrequency].end()) {
341 if (connectionControl_->isHandingOver(src))
345 LteHarqBufferMirrorD2D *hb =
new LteHarqBufferMirrorD2D((
unsigned int)this->harqProcesses_, (
unsigned char)this->par(
"maxHarqRtx"),
this);
346 harqBuffersMirrorD2D[carrierFrequency][pair] = hb;
347 hb->receiveHarqFeedback(pkt);
350 hit->second->receiveHarqFeedback(pkt);