Skip to content

Commit 123af20

Browse files
committed
EthernetMacPhy: Add optional support for emitting the receptionStarted signal
added new NED receptionMode parameter: "onStart" | "auto" | "onEnd" | "forceOnEnd"
1 parent a1ecbb8 commit 123af20

3 files changed

Lines changed: 102 additions & 3 deletions

File tree

src/inet/linklayer/ethernet/basic/EthernetMacPhy.cc

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,56 @@ EthernetMacPhy::EthernetMacPhy()
3030
{
3131
}
3232

33+
EthernetMacPhy::~EthernetMacPhy()
34+
{
35+
cancelAndDelete(endRxTimer);
36+
delete currentRxSignal;
37+
}
38+
3339
void EthernetMacPhy::initialize(int stage)
3440
{
3541
EthernetMacBase::initialize(stage);
3642

3743
if (stage == INITSTAGE_LOCAL) {
44+
// read parameters
3845
if (!par("duplexMode"))
3946
throw cRuntimeError("Half duplex operation is not supported by EthernetMacPhy, use the EthernetCsmaMacPhy module for that! (Please enable csmacdSupport on EthernetInterface)");
47+
48+
const char *receptionModeStr = par("receptionMode");
49+
if (!strcmp(receptionModeStr, "onStart"))
50+
receptionMode = ON_START;
51+
else if (!strcmp(receptionModeStr, "auto"))
52+
receptionMode = AUTO;
53+
else if (!strcmp(receptionModeStr, "onEnd"))
54+
receptionMode = ON_END;
55+
else if (!strcmp(receptionModeStr, "forceOnEnd"))
56+
receptionMode = FORCE_ON_END;
57+
else
58+
throw cRuntimeError("Unknown receptionMode value '%s'", receptionModeStr);
59+
4060
}
4161
else if (stage == INITSTAGE_LINK_LAYER) {
4262
beginSendFrames(); // FIXME choose an another stage for it
4363
}
64+
else if (stage == INITSTAGE_LAST) {
65+
switch (receptionMode) {
66+
case ON_START:
67+
setReceptionOnStartMode();
68+
break;
69+
case AUTO:
70+
if (hasListeners(receptionStartedSignal))
71+
setReceptionOnStartMode();
72+
break;
73+
case ON_END:
74+
if (hasListeners(receptionStartedSignal))
75+
throw cRuntimeError("Signal 'receptionStartedSignal' has active listeners subscribed, but the signal's release is disabled via parameter 'emitReceptionStarted' = false. Remove the listeners or set the parameter to true.");
76+
break;
77+
case FORCE_ON_END:
78+
break;
79+
default:
80+
throw cRuntimeError("Unknown receptionMode value '%d'", (int)receptionMode);
81+
}
82+
}
4483
}
4584

4685
void EthernetMacPhy::initializeStatistics()
@@ -51,12 +90,19 @@ void EthernetMacPhy::initializeStatistics()
5190
totalSuccessfulRxTime = 0.0;
5291
}
5392

93+
void EthernetMacPhy::setReceptionOnStartMode()
94+
{
95+
endRxTimer = new cMessage("EndReception", ENDRECEPTION);
96+
setTxUpdateSupport(true);
97+
physInGate->setDeliverImmediately(true);
98+
receptionOnStart = true;
99+
}
100+
54101
void EthernetMacPhy::initializeFlags()
55102
{
56103
EthernetMacBase::initializeFlags();
57104

58105
duplexMode = true;
59-
physInGate->setDeliverImmediately(false);
60106
}
61107

62108
void EthernetMacPhy::handleMessageWhenUp(cMessage *msg)
@@ -68,8 +114,31 @@ void EthernetMacPhy::handleMessageWhenUp(cMessage *msg)
68114
handleSelfMessage(msg);
69115
else if (msg->getArrivalGateId() == upperLayerInGateId)
70116
handleUpperPacket(check_and_cast<Packet *>(msg));
71-
else if (msg->getArrivalGate() == physInGate)
72-
processMsgFromNetwork(check_and_cast<Signal *>(msg));
117+
else if (msg->getArrivalGate() == physInGate) {
118+
Signal *signal = check_and_cast<Signal *>(msg);
119+
if (receptionOnStart) {
120+
if (signal->isUpdate()) {
121+
ASSERT(endRxTimer->isScheduled());
122+
ASSERT(currentRxSignal != nullptr);
123+
EV_DETAIL << "Rx update: " << signal << endl;
124+
delete currentRxSignal;
125+
currentRxSignal = signal;
126+
rescheduleAfter(currentRxSignal->getRemainingDuration(), endRxTimer);
127+
}
128+
else {
129+
EV_DETAIL << "Rx start: " << signal << endl;
130+
ASSERT(!endRxTimer->isScheduled());
131+
ASSERT(currentRxSignal == nullptr);
132+
simtime_t remainingDuration = signal->getRemainingDuration();
133+
currentRxSignal = signal;
134+
scheduleAfter(remainingDuration, endRxTimer);
135+
emit(receptionStartedSignal, signal);
136+
}
137+
}
138+
else {
139+
processMsgFromNetwork(signal);
140+
}
141+
}
73142
else
74143
throw cRuntimeError("Message received from unknown gate!");
75144
processAtHandleMessageFinished();
@@ -85,6 +154,12 @@ void EthernetMacPhy::handleSelfMessage(cMessage *msg)
85154
handleEndIFGPeriod();
86155
else if (msg == endPauseTimer)
87156
handleEndPausePeriod();
157+
else if (msg == endRxTimer) {
158+
EV_DETAIL << "Rx end: " << currentRxSignal << endl;
159+
processMsgFromNetwork(currentRxSignal);
160+
currentRxSignal = nullptr;
161+
processAtHandleMessageFinished();
162+
}
88163
else
89164
throw cRuntimeError("Unknown self message received!");
90165
}

src/inet/linklayer/ethernet/basic/EthernetMacPhy.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@ class INET_API EthernetMacPhy : public EthernetMacBase
2222
{
2323
public:
2424
EthernetMacPhy();
25+
virtual ~EthernetMacPhy();
2526

2627
// IActivePacketSink:
2728
virtual void handleCanPullPacketChanged(const cGate *gate) override;
2829

2930
protected:
31+
enum ReceptionMode {ON_START, AUTO, ON_END, FORCE_ON_END};
32+
3033
virtual int numInitStages() const override { return NUM_INIT_STAGES; }
3134
virtual void initialize(int stage) override;
3235
virtual void initializeStatistics() override;
@@ -43,6 +46,7 @@ class INET_API EthernetMacPhy : public EthernetMacBase
4346
virtual void handleSelfMessage(cMessage *msg) override;
4447

4548
// helpers
49+
virtual void setReceptionOnStartMode();
4650
virtual void startFrameTransmission();
4751
virtual void handleUpperPacket(Packet *pk) override;
4852
virtual void processMsgFromNetwork(Signal *signal);
@@ -52,6 +56,17 @@ class INET_API EthernetMacPhy : public EthernetMacBase
5256
virtual void scheduleEndPausePeriod(int pauseUnits);
5357
virtual void beginSendFrames();
5458

59+
// parameter values
60+
ReceptionMode receptionMode = AUTO;
61+
62+
bool receptionOnStart = false;
63+
64+
// self messages
65+
cMessage *endRxTimer = nullptr;
66+
67+
// other variables
68+
Signal *currentRxSignal = nullptr;
69+
5570
// statistics
5671
simtime_t totalSuccessfulRxTime; // total duration of successful transmissions on channel
5772
};

src/inet/linklayer/ethernet/basic/EthernetMacPhy.ned

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,14 @@ module EthernetMacPhy extends Module like IEtherMac
115115
bool duplexMode; // Must be set to "true", as EthernetMacPhy does not support half-duplex operation
116116
// (parameter is present to reduce the risk of accidental misconfiguration)
117117
bool allowNonstandardBitrate = default(false); // Allows any bitrate and uses the first larger bitrate specified parameters
118+
119+
// Receiviving mode of incoming ethernet frames:
120+
// - onStart: receiving on start of frame
121+
// - auto: receiving on start frame when module has any subscribers to receptionStart signal, otherwise receiving on end of frame
122+
// - onEnd: receiving on end of frame, throws error at end of initialize module when has any subscribers to receptionStart signal
123+
// - forceOnEnd: receiving on end of frame, silently skip emit receptionStart signal
124+
string receptionMode @enum("onStart", "auto", "onEnd", "forceOnEnd") = default("auto");
125+
118126
int mtu @unit(B) = default(1500B);
119127
string fcsMode @enum("declared", "computed");
120128
@lifecycleSupport;
@@ -137,6 +145,7 @@ module EthernetMacPhy extends Module like IEtherMac
137145
@signal[receptionStateChanged](type=long); // Enum=MacReceiveState
138146
@signal[transmissionStarted](type=inet::physicallayer::EthernetSignalBase);
139147
@signal[transmissionEnded](type=inet::physicallayer::EthernetSignalBase);
148+
@signal[receptionStarted](type=inet::physicallayer::Signal);
140149
@signal[receptionEnded](type=inet::physicallayer::Signal);
141150

142151
@statistic[transmitting](title="transmitting state"; type=int; source=count(transmissionStarted) - count(transmissionEnded); record=vector; interpolationmode=sample-hold);

0 commit comments

Comments
 (0)