|
|
| 164 |
{ |
164 |
{ |
| 165 |
//PM STATE Machine |
165 |
//PM STATE Machine |
| 166 |
//Check that a given beacon is not from our interface |
166 |
//Check that a given beacon is not from our interface |
| 167 |
Simulator::Schedule (beaconInterval - TuToTime (m_maxBeaconShift + 1), &PeerManagementProtocol::DoShiftBeacon, this, interface); |
|
|
| 168 |
for (PeerManagementProtocolMacMap::const_iterator i = m_plugins.begin (); i != m_plugins.end (); i++) |
167 |
for (PeerManagementProtocolMacMap::const_iterator i = m_plugins.begin (); i != m_plugins.end (); i++) |
| 169 |
{ |
168 |
{ |
| 170 |
if (i->second->GetAddress () == peerAddress) |
169 |
if (i->second->GetAddress () == peerAddress) |
|
|
| 180 |
peerLink = InitiateLink (interface, peerAddress, Mac48Address::GetBroadcast ()); |
179 |
peerLink = InitiateLink (interface, peerAddress, Mac48Address::GetBroadcast ()); |
| 181 |
peerLink->MLMEActivePeerLinkOpen (); |
180 |
peerLink->MLMEActivePeerLinkOpen (); |
| 182 |
} |
181 |
} |
|
|
182 |
else |
| 183 |
{ |
| 184 |
//PMP has cancelled new link and should not open it. |
| 185 |
return; |
| 186 |
} |
| 183 |
} |
187 |
} |
| 184 |
peerLink->SetBeaconInformation (Simulator::Now (), beaconInterval); |
188 |
peerLink->SetBeaconInformation (Simulator::Now (), beaconInterval); |
| 185 |
if (GetBeaconCollisionAvoidance ()) |
189 |
if (GetBeaconCollisionAvoidance ()) |
|
|
| 383 |
UniformVariable beaconShift (-m_maxBeaconShift, m_maxBeaconShift); |
387 |
UniformVariable beaconShift (-m_maxBeaconShift, m_maxBeaconShift); |
| 384 |
PeerLinksMap::iterator iface = m_peerLinks.find (interface); |
388 |
PeerLinksMap::iterator iface = m_peerLinks.find (interface); |
| 385 |
NS_ASSERT (iface != m_peerLinks.end ()); |
389 |
NS_ASSERT (iface != m_peerLinks.end ()); |
| 386 |
PeerManagementProtocolMacMap::const_iterator plugin = m_plugins.find (interface); |
|
|
| 387 |
NS_ASSERT (plugin != m_plugins.end ()); |
| 388 |
std::map<uint32_t, Time>::const_iterator lastBeacon = m_lastBeacon.find (interface); |
390 |
std::map<uint32_t, Time>::const_iterator lastBeacon = m_lastBeacon.find (interface); |
| 389 |
std::map<uint32_t, Time>::const_iterator beaconInterval = m_beaconInterval.find (interface); |
391 |
std::map<uint32_t, Time>::const_iterator beaconInterval = m_beaconInterval.find (interface); |
| 390 |
if ((lastBeacon == m_lastBeacon.end ()) || (beaconInterval == m_beaconInterval.end ())) |
392 |
if ((lastBeacon == m_lastBeacon.end ()) || (beaconInterval == m_beaconInterval.end ())) |
| 391 |
{ |
393 |
{ |
| 392 |
return; |
394 |
return; |
| 393 |
} |
395 |
} |
|
|
396 |
//my last beacon in 256 us units |
| 397 |
uint16_t lastBeaconInTimeElement = (uint16_t) ((lastBeacon->second.GetMicroSeconds () >> 8) & 0xffff); |
| 394 |
if (TuToTime (m_maxBeaconShift) > m_beaconInterval[interface]) |
398 |
if (TuToTime (m_maxBeaconShift) > m_beaconInterval[interface]) |
| 395 |
{ |
399 |
{ |
| 396 |
NS_FATAL_ERROR ("Wrong beacon shift parameters"); |
400 |
NS_FATAL_ERROR ("Wrong beacon shift parameters"); |
| 397 |
return; |
401 |
return; |
| 398 |
} |
402 |
} |
|
|
403 |
//check whether we need to shift our beacon |
| 404 |
bool shiftIsNeeded = false; |
| 405 |
|
| 406 |
if (iface->second.size () == 0) |
| 407 |
{ |
| 408 |
//I have no peers - may be our beacons are in collision |
| 409 |
shiftIsNeeded = true; |
| 410 |
} |
| 411 |
//check whether all my peers receive my beacon and I'am not in collision with other beacons |
| 399 |
for (PeerLinksOnInterface::iterator i = iface->second.begin (); i != iface->second.end (); i++) |
412 |
for (PeerLinksOnInterface::iterator i = iface->second.begin (); i != iface->second.end (); i++) |
| 400 |
{ |
413 |
{ |
|
|
414 |
bool isMyBeaconRec = false; |
| 415 |
bool isCollision = false; |
| 401 |
IeBeaconTiming::NeighboursTimingUnitsList neighbours; |
416 |
IeBeaconTiming::NeighboursTimingUnitsList neighbours; |
| 402 |
neighbours = (*i)->GetBeaconTimingElement ().GetNeighboursTimingElementsList (); |
417 |
neighbours = (*i)->GetBeaconTimingElement ().GetNeighboursTimingElementsList (); |
| 403 |
//Going through all my timing elements and detecting future beacon collisions |
418 |
for (IeBeaconTiming::NeighboursTimingUnitsList::const_iterator j = neighbours.begin (); j != neighbours.end (); j++) |
| 404 |
for (IeBeaconTiming::NeighboursTimingUnitsList::const_iterator j = neighbours.begin (); j |
|
|
| 405 |
!= neighbours.end (); j++) |
| 406 |
{ |
419 |
{ |
| 407 |
if ((*i)->GetPeerAid () == (*j)->GetAid ()) |
420 |
if ((*i)->GetPeerAid () == (*j)->GetAid ()) |
| 408 |
{ |
421 |
{ |
| 409 |
// I am present at neighbour's list of neighbors |
422 |
// I am presented at neighbour's list of neighbors |
|
|
423 |
isMyBeaconRec = true; |
| 410 |
continue; |
424 |
continue; |
| 411 |
} |
425 |
} |
| 412 |
//Beacon interval is stored in TU's |
426 |
if ( |
| 413 |
if (((*j)->GetBeaconInterval ()) != TimeToTu (beaconInterval->second)) |
427 |
((int16_t) ((*j)->GetLastBeacon () - lastBeaconInTimeElement) >= 0) |
|
|
428 |
&& |
| 429 |
(((*j)->GetLastBeacon () - lastBeaconInTimeElement) % (4 * TimeToTu (beaconInterval->second))== 0) |
| 430 |
) |
| 414 |
{ |
431 |
{ |
| 415 |
continue; |
432 |
isCollision=true; |
| 416 |
} |
433 |
} |
| 417 |
//Timing element keeps beacon receiving times in 256us units, TU=1024us |
|
|
| 418 |
if ((int) ((int)(*j)->GetLastBeacon () / 4 - (int)TimeToTu (lastBeacon->second)) % TimeToTu ( |
| 419 |
beaconInterval->second) |
| 420 |
!= 0) |
| 421 |
{ |
| 422 |
continue; |
| 423 |
} |
| 424 |
int shift = 0; |
| 425 |
do |
| 426 |
{ |
| 427 |
shift = (int) beaconShift.GetValue (); |
| 428 |
} |
| 429 |
while (shift == 0); |
| 430 |
PeerManagementProtocolMacMap::iterator plugin = m_plugins.find (interface); |
| 431 |
NS_ASSERT (plugin != m_plugins.end ()); |
| 432 |
plugin->second->SetBeaconShift (TuToTime (shift)); |
| 433 |
return; |
| 434 |
} |
434 |
} |
|
|
435 |
// If I am not present in neighbor's beacon timing element, this may be caused vy collisions with |
| 436 |
// other beacons, and no peering link was established. |
| 437 |
if ((!isMyBeaconRec)||(isCollision)) |
| 438 |
{ |
| 439 |
shiftIsNeeded=true; |
| 440 |
break; |
| 441 |
} |
| 442 |
} |
| 443 |
// Now, shift beacon. The value is chosen randomly: |
| 444 |
if (!shiftIsNeeded) |
| 445 |
{ |
| 446 |
return; |
| 435 |
} |
447 |
} |
|
|
448 |
int shift = 0; |
| 449 |
do |
| 450 |
{ |
| 451 |
shift = (int) beaconShift.GetValue (); |
| 452 |
} |
| 453 |
while (shift == 0); |
| 454 |
// Apply beacon shift parameters: |
| 455 |
PeerManagementProtocolMacMap::iterator plugin = m_plugins.find (interface); |
| 456 |
NS_ASSERT (plugin != m_plugins.end ()); |
| 457 |
plugin->second->SetBeaconShift (TuToTime (shift)); |
| 458 |
return; |
| 436 |
} |
459 |
} |
|
|
460 |
|
| 437 |
Time |
461 |
Time |
| 438 |
PeerManagementProtocol::TuToTime (uint32_t x) |
462 |
PeerManagementProtocol::TuToTime (int x) |
| 439 |
{ |
463 |
{ |
| 440 |
return MicroSeconds (x * 1024); |
464 |
return MicroSeconds (x * 1024); |
| 441 |
} |
465 |
} |
| 442 |
uint32_t |
466 |
|
|
|
467 |
int |
| 443 |
PeerManagementProtocol::TimeToTu (Time x) |
468 |
PeerManagementProtocol::TimeToTu (Time x) |
| 444 |
{ |
469 |
{ |
| 445 |
return (uint32_t) (x.GetMicroSeconds () / 1024); |
470 |
return (uint32_t) (x.GetMicroSeconds () / 1024); |
|
|
| 519 |
PeerManagementProtocol::NotifyBeaconSent (uint32_t interface, Time beaconInterval) |
544 |
PeerManagementProtocol::NotifyBeaconSent (uint32_t interface, Time beaconInterval) |
| 520 |
{ |
545 |
{ |
| 521 |
m_lastBeacon[interface] = Simulator::Now (); |
546 |
m_lastBeacon[interface] = Simulator::Now (); |
|
|
547 |
Simulator::Schedule(beaconInterval - TuToTime(m_maxBeaconShift + 1), &PeerManagementProtocol::DoShiftBeacon,this, interface); |
| 522 |
m_beaconInterval[interface] = beaconInterval; |
548 |
m_beaconInterval[interface] = beaconInterval; |
| 523 |
} |
549 |
} |
| 524 |
PeerManagementProtocol::Statistics::Statistics (uint16_t t) : |
550 |
PeerManagementProtocol::Statistics::Statistics (uint16_t t) : |