13#ifndef STACK_D2D_PHY_D2DUEPHY_H_
14#define STACK_D2D_PHY_D2DUEPHY_H_
16#include "simu5g/stack/phy/PhyUe.h"
17#include "simu5g/stack/phy/packet/LteFeedbackPkt.h"
18#include "simu5g/stack/rrc/ConnectionControlUe.h"
19#include "simu5g/stack/d2d/phy/D2dUePhyHelper.h"
20#include "simu5g/stack/d2d/binder/D2dBinder.h"
21#include "simu5g/common/LteControlInfoTags_m.h"
25using namespace omnetpp;
48 D2dUePhyHelper d2dHelper_{
this};
53 cMessage *d2dDecodingTimer_ =
nullptr;
58 simsignal_t averageCqiD2DSignal_ = SIMSIGNAL_NULL;
62 inet::ModuleRefByPar<D2dBinder> d2dBinder_;
64 void initialize(
int stage)
override;
65 void handleSelfMessage(cMessage *msg)
override;
72 return lteInfo->getDirection() != D2D && lteInfo->getDirection() != D2D_MULTI
73 && lteInfo->getSourceId() != this->servingNodeId_;
80 if (this->binder_->isInMulticastGroup(this->nodeId_, lteInfo->getPacketMulticastGroupId()))
81 lteInfo->setDestId(this->nodeId_);
87 return type == D2DMODESWITCHPKT || Base::isControlFrameType(type);
93 if (!(d2dHelper_.getMulticastEnableCaptureEffect() && this->binder_->isInMulticastGroup(this->nodeId_, lteInfo->getPacketMulticastGroupId())))
97 if (d2dDecodingTimer_ ==
nullptr) {
98 d2dDecodingTimer_ =
new cMessage(
"d2dDecodingTimer");
99 d2dDecodingTimer_->setSchedulingPriority(10);
100 this->scheduleAt(NOW, d2dDecodingTimer_);
104 frame->setControlInfo(lteInfo);
105 d2dHelper_.storeAirFrame(frame);
118 if (info->getDirection() == D2D || info->getDirection() == D2D_MULTI)
119 this->emit(averageCqiD2DSignal_, cqi);
125 switch (info->getFrameType()) {
128 case RACPKT:
return "harqFeedback-grant";
129 default:
return "airframe";
133 void stampExtraTxControlInfo(UserControlInfo *info)
override
135 info->setD2dTxPower(d2dHelper_.getD2dTxPower());
139 void transmitFrame(LteAirFrame *frame,
const UserControlInfo *info)
override
141 if (info->getDirection() == D2D_MULTI)
144 this->sendUnicast(frame);
156 double getTxPwr(Direction dir = UNKNOWN_DIRECTION)
override
159 return d2dHelper_.getD2dTxPower();
160 return this->txPower_;
165void D2dUePhy<Base>::initialize(
int stage)
167 Base::initialize(stage);
168 if (stage == inet::INITSTAGE_LOCAL) {
169 averageCqiD2DSignal_ = cComponent::registerSignal(
"averageCqiD2D");
170 d2dHelper_.setD2dTxPower(this->par(
"d2dTxPower"));
171 d2dHelper_.setMulticastEnableCaptureEffect(this->par(
"d2dMulticastCaptureEffect"));
172 d2dHelper_.setMulticastD2DRangeCheckEnabled(this->par(
"enableMulticastD2DRangeCheck"));
173 d2dHelper_.setMulticastD2DRange(this->par(
"multicastD2DRange"));
174 d2dBinder_.reference(
this,
"d2dBinderModule",
true);
175 d2dHelper_.initWatches();
177 else if (stage == INITSTAGE_SIMU5G_BINDER_ACCESS) {
180 d2dBinder_->registerD2dPhy(this->nodeId_,
this);
185void D2dUePhy<Base>::handleSelfMessage(cMessage *msg)
187 if (msg->isName(
"d2dDecodingTimer")) {
189 d2dHelper_.decodeStoredFrames();
192 d2dDecodingTimer_ =
nullptr;
195 Base::handleSelfMessage(msg);
201 UserControlInfo *ci = check_and_cast<UserControlInfo *>(frame->getControlInfo());
204 MacNodeId groupId = ci->getPacketMulticastGroupId();
206 throw cRuntimeError(
"D2dUePhy::sendMulticast - Error. Group ID %d is not valid.", num(groupId));
209 frame->setAdditionalInfo(*ci);
210 delete frame->removeControlInfo();
213 for (
auto [destId, nodeInfo] : this->binder_->getNodeInfoMap()) {
215 if (isNrUe(destId) != this->isNr_)
218 if (destId != this->nodeId_ && this->binder_->isInMulticastGroup(destId, groupId)) {
219 EV << NOW <<
" D2dUePhy::sendMulticast - node " << destId <<
" is in the multicast group" << endl;
222 cModule *receiver = nodeInfo.moduleRef;
224 if (d2dHelper_.getMulticastD2DRangeCheckEnabled()) {
227 PhyBase *recvPhy = d2dBinder_->getD2dPhy(destId);
228 if (recvPhy ==
nullptr)
229 throw cRuntimeError(
"D2dUePhy::sendMulticast - node %d is in multicast group %d but has no registered D2D PHY",
230 num(destId), num(groupId));
232 double dist = recvPhy->getCoord().distance(this->getRadioPosition());
234 if (dist > d2dHelper_.getMulticastD2DRange()) {
235 EV << NOW <<
" D2dUePhy::sendMulticast - node too far (" << dist <<
" > " << d2dHelper_.getMulticastD2DRange() <<
". skipping transmission" << endl;
240 EV << NOW <<
" D2dUePhy::sendMulticast - sending frame to node " << destId << endl;
243 LteAirFrame *frameToSend = frame->dup();
244 this->sendDirect(frameToSend, 0, frame->getDuration(), receiver, this->getReceiverGateIndex(receiver, destId));
void recordExtraTxCqi(double cqi, const UserControlInfo *info) override
D2D CQI accounting for outgoing data packets.
Definition D2dUePhy.h:116
bool isStaleFrame(const UserControlInfo *lteInfo) override
D2D/D2D_MULTI frames legitimately arrive from peers, not the serving cell.
Definition D2dUePhy.h:70
bool isControlFrameType(LtePhyFrameType type) override
D2D mode-switch notifications are control frames too.
Definition D2dUePhy.h:85
void frameAccepted(UserControlInfo *lteInfo) override
Definition D2dUePhy.h:78
void transmitFrame(LteAirFrame *frame, const UserControlInfo *info) override
one-to-many D2D transmissions go out via sendDirect to all group members
Definition D2dUePhy.h:139
void sendMulticast(LteAirFrame *frame)
Definition D2dUePhy.h:199
void validateOutgoingFrame(const UserControlInfo *info) override
Definition D2dUePhy.h:113
bool interceptIncomingFrame(LteAirFrame *frame, UserControlInfo *lteInfo) override
D2D-multicast capture effect: store the frame and decode it at the end of the TTI.
Definition D2dUePhy.h:91
const char * airFrameNameFor(const UserControlInfo *info) override
keep the historical D2D frame naming (all control frames named "harqFeedback-grant")
Definition D2dUePhy.h:123
Definition AlertReceiver.h:24
constexpr MacNodeId NODEID_NONE
MAC node ID.
Definition LteTypes.h:54