Skip to content

Commit 59b8305

Browse files
torokati44avarga
authored andcommitted
BearerConfigurator: a remembered multicast flow belongs to its sender, not just its group
multicastFlows_ was keyed by multicast group id alone, with the first sender to establish the bearer winning and the entry never removed. Both halves of that are wrong once the node population changes during the simulation: - Nothing dropped the entry when its sender left, so multicastGroupJoined() kept provisioning later joiners against a bearer whose TX side no longer exists. - With the entry pinned to the first sender, a node that takes over the group afterwards never got remembered at all -- and a group served by two senders at once only ever had one of them remembered. Neither is cosmetic, because the RX side of a bearer is keyed by its sender: FlowId::rxDrbKey() builds the DrbKey from sourceId, and BearerManagement::createIncomingConnection() installs the MAC descriptor under MacCid(senderId, lcid). Provisioning a joiner from a stale flow therefore creates a descriptor under the *departed* sender's CID, while the PDUs that actually arrive carry the current sender's -- which lands in exactly the 'connDescIn_.find(cid) != connDescIn_.end()' assert in macPduUnmake() that multicastGroupJoined() was added to prevent. So the map is now keyed by (group id, sender id): createConnection() remembers one flow per sender, multicastGroupJoined() gives the joiner an RX leg for each remembered sender of the group, and the node-unregistered listener drops the entries of a departing sender. Full fingerprint suite 182/182 PASS, CSVs unchanged: in the static scenarios each group has one sender that never leaves, so the keying change is inert and the purge never runs.
1 parent 15a0b50 commit 59b8305

2 files changed

Lines changed: 30 additions & 8 deletions

File tree

src/simu5g/corenetwork/bearerConfigurator/BearerConfigurator.cc

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -921,6 +921,19 @@ void BearerConfigurator::receiveSignal(cComponent *source, simsignal_t signalID,
921921
else
922922
++it;
923923
}
924+
925+
// The remembered multicast flows are keyed by group but owned by their sender: drop the
926+
// ones this node established, or multicastGroupJoined() would keep handing later joiners
927+
// an RX leg keyed to a sender that no longer transmits -- and, since the RX descriptor's
928+
// MacCid carries that sender's id, the PDUs of whichever node took over the group would
929+
// then arrive on a connection the joiner has no descriptor for. A replacement sender's
930+
// createConnection() stores a fresh flow, so the group keeps working.
931+
for (auto it = multicastFlows_.begin(); it != multicastFlows_.end(); ) {
932+
if (it->first.second == id)
933+
it = multicastFlows_.erase(it);
934+
else
935+
++it;
936+
}
924937
}
925938

926939
void BearerConfigurator::createConnection(const FlowId& flow, const BearerRequest& req, bool withPdcp)
@@ -960,8 +973,9 @@ void BearerConfigurator::createConnection(const FlowId& flow, const BearerReques
960973
else {
961974
// Remember the flow so that nodes joining this group later still get an RX leg; the
962975
// loop below can only reach the members that already exist. See multicastGroupJoined().
963-
if (multicastFlows_.find(groupId) == multicastFlows_.end())
964-
multicastFlows_[groupId] = { flow, req, withPdcp };
976+
auto flowKey = std::make_pair(groupId, sourceId);
977+
if (multicastFlows_.find(flowKey) == multicastFlows_.end())
978+
multicastFlows_[flowKey] = { flow, req, withPdcp };
965979

966980
// Multicast bearers stay unidirectional: TX at the sender, RX at the members
967981
for (auto& [nodeId,_] : binder_->getNodeInfoMap()) //TODO use lte ones if LTE in DC setup, and NR ones if NR in DC setup
@@ -975,10 +989,13 @@ void BearerConfigurator::multicastGroupJoined(MacNodeId nodeId, MacNodeId groupI
975989
{
976990
Enter_Method("multicastGroupJoined(%hu, %hu)", (unsigned short)nodeId, (unsigned short)groupId);
977991

978-
auto it = multicastFlows_.find(groupId);
979-
if (it != multicastFlows_.end() && nodeId != it->second.flow.sourceId)
980-
createIncomingConnectionOnNode(nodeId, it->second.flow, it->second.req,
981-
getNodeTypeById(nodeId) == UE || it->second.withPdcp);
992+
for (auto& [key, mf] : multicastFlows_) {
993+
auto& [flowGroupId, senderId] = key;
994+
if (flowGroupId != groupId || senderId == nodeId)
995+
continue;
996+
createIncomingConnectionOnNode(nodeId, mf.flow, mf.req,
997+
getNodeTypeById(nodeId) == UE || mf.withPdcp);
998+
}
982999
}
9831000

9841001
void BearerConfigurator::createIncomingConnectionOnNode(MacNodeId nodeId, const FlowId& flow, const BearerRequest& req, bool withPdcp)

src/simu5g/corenetwork/bearerConfigurator/BearerConfigurator.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,19 @@ class BearerConfigurator : public cSimpleModule, public cListener
7575
* provisions the members that exist when the sender starts, which is all of them only if
7676
* the node population is static; with nodes created during the simulation the joiner
7777
* would otherwise receive PDUs for a connection its stack knows nothing about.
78-
* Keyed by multicast group id; the first sender to establish the bearer wins.
78+
*
79+
* Keyed by (multicast group id, sender id): the RX side of a bearer is keyed by its
80+
* sender (see FlowId::rxDrbKey, and MacCid(senderId, lcid) in
81+
* BearerManagement::createIncomingConnection), so a group served by several senders --
82+
* at once, or one after another as vehicles come and go -- needs one remembered flow per
83+
* sender. Each entry is dropped when its sender leaves, see receiveSignal().
7984
*/
8085
struct MulticastFlow {
8186
FlowId flow;
8287
BearerRequest req;
8388
bool withPdcp = false;
8489
};
85-
std::map<MacNodeId, MulticastFlow> multicastFlows_;
90+
std::map<std::pair<MacNodeId, MacNodeId>, MulticastFlow> multicastFlows_;
8691

8792

8893
protected:

0 commit comments

Comments
 (0)