OpenDDS::RTPS::GuidGenerator Class Reference

#include <GuidGenerator.h>

Collaboration diagram for OpenDDS::RTPS::GuidGenerator:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 GuidGenerator ()
int interfaceName (const char *interface)
void populate (DCPS::GUID_t &container)

Private Types

enum  { NODE_ID_SIZE = 6 }
typedef unsigned char Node_ID [NODE_ID_SIZE]

Private Member Functions

ACE_UINT16 getCount ()

Private Attributes

Node_ID node_id_
pid_t pid_
ACE_Thread_Mutex counter_lock_
ACE_UINT16 counter_
OPENDDS_STRING interface_name_

Detailed Description

Generate GuidPrefix_t values for use with RTPS Also see GuidConverter.h in dds/DCPS 0 GUID_t.guidPrefix[ 0] == VendorId_t == 0x01 for OCI (used for OpenDDS) 1 GUID_t.guidPrefix[ 1] == VendorId_t == 0x03 for OCI (used for OpenDDS) 2 GUID_t.guidPrefix[ 2] == MAC Address 3 GUID_t.guidPrefix[ 3] == MAC Address 4 GUID_t.guidPrefix[ 4] == MAC Address 5 GUID_t.guidPrefix[ 5] == MAC Address 6 GUID_t.guidPrefix[ 6] == MAC Address 7 GUID_t.guidPrefix[ 7] == MAC Address 8 GUID_t.guidPrefix[ 8] == Process ID (MS byte) 9 GUID_t.guidPrefix[ 9] == Process ID (LS byte) 10 GUID_t.guidPrefix[10] == Counter (MS byte) 11 GUID_t.guidPrefix[11] == Counter (LS byte)

Definition at line 37 of file GuidGenerator.h.


Member Typedef Documentation

typedef unsigned char OpenDDS::RTPS::GuidGenerator::Node_ID[NODE_ID_SIZE] [private]

Borrowed from ACE::UUID_Node, definition of the MAC address holder type

Definition at line 55 of file GuidGenerator.h.


Member Enumeration Documentation

anonymous enum [private]
Enumerator:
NODE_ID_SIZE 

Definition at line 51 of file GuidGenerator.h.

00051 {NODE_ID_SIZE = 6};


Constructor & Destructor Documentation

OpenDDS::RTPS::GuidGenerator::GuidGenerator (  ) 

Definition at line 49 of file GuidGenerator.cpp.

References ACE_OS::getmacaddress(), getpid(), ACE_OS::gettimeofday(), ACE_OS::memcpy(), ACE_OS::macaddr_node_t::node, node_id_, NODE_ID_SIZE, pid_, ACE_OS::rand(), ACE_OS::rand_r(), and ACE_Time_Value::usec().

00050   : pid_(ACE_OS::getpid()),
00051     counter_(0)
00052 {
00053 
00054   if (pid_ == -1) {
00055     unsigned seed = static_cast<unsigned>(ACE_OS::gettimeofday().usec());
00056     pid_ = static_cast<pid_t>(ACE_OS::rand_r(&seed));
00057   }
00058 
00059   ACE_OS::macaddr_node_t macaddress;
00060   const int result = ACE_OS::getmacaddress(&macaddress);
00061 
00062   if (-1 != result) {
00063     ACE_OS::memcpy(node_id_, macaddress.node, NODE_ID_SIZE);
00064   } else {
00065     for (int i = 0; i < NODE_ID_SIZE; ++i) {
00066       node_id_[i] = static_cast<unsigned char>(ACE_OS::rand());
00067     }
00068   }
00069 }

Here is the call graph for this function:


Member Function Documentation

ACE_UINT16 OpenDDS::RTPS::GuidGenerator::getCount (  )  [private]

Definition at line 72 of file GuidGenerator.cpp.

References counter_, and counter_lock_.

Referenced by populate().

00073 {
00074   ACE_Guard<ACE_SYNCH_MUTEX> guard(counter_lock_);
00075   return counter_++;
00076 }

Here is the caller graph for this function:

int OpenDDS::RTPS::GuidGenerator::interfaceName ( const char *  interface  ) 

override the MAC address to use a specific network interface instead of just the first (non-loopback) interface

Definition at line 79 of file GuidGenerator.cpp.

References ACE_TEXT(), ACE_OS::close(), ACE_Allocator::free(), h, ifconf::ifc_len, ifreq::ifr_name, OpenDDS::DCPS::SafetyProfilePool::instance(), interface_name_, ACE_OS::ioctl(), LM_ERROR, ACE_Allocator::malloc(), node_id_, size, and ACE_OS::socket().

Referenced by OpenDDS::RTPS::RtpsDiscovery::add_domain_participant(), and OpenDDS::RTPS::RtpsDiscovery::generate_participant_guid().

00080 {
00081   if (interface_name_ == iface) {
00082     return 0;
00083   }
00084   interface_name_ = iface;
00085   // See ace/OS_NS_netdb.cpp ACE_OS::getmacaddress()
00086 #if defined ACE_WIN32 && !defined ACE_HAS_WINCE
00087   ULONG size;
00088   if (::GetAdaptersAddresses(AF_UNSPEC, 0, 0, 0, &size)
00089       != ERROR_BUFFER_OVERFLOW) {
00090     return -1;
00091   }
00092   ACE_Allocator* const alloc = DCPS::SafetyProfilePool::instance();
00093   IP_ADAPTER_ADDRESSES* const addrs =
00094     static_cast<IP_ADAPTER_ADDRESSES*>(alloc->malloc(size));
00095   if (!addrs) {
00096     return -1;
00097   }
00098   if (::GetAdaptersAddresses(AF_UNSPEC, 0, 0, addrs, &size) != NO_ERROR) {
00099     alloc->free(addrs);
00100     return -1;
00101   }
00102 
00103   bool found = false;
00104   for (IP_ADAPTER_ADDRESSES* iter = addrs; iter && !found; iter = iter->Next) {
00105     if (ACE_Wide_To_Ascii(iter->FriendlyName).char_rep() == interface_name_) {
00106       std::memcpy(node_id_, iter->PhysicalAddress,
00107                   std::min(static_cast<size_t>(iter->PhysicalAddressLength),
00108                            sizeof node_id_));
00109       found = true;
00110     }
00111   }
00112 
00113   alloc->free(addrs);
00114   return found ? 0 : -1;
00115 #elif defined ACE_LINUX || defined __ANDROID_API__
00116   ifreq ifr;
00117   // Guarantee that iface will fit in ifr.ifr_name and still be null terminated
00118   // ifr.ifr_name is sized to IFNAMSIZ
00119   if (std::strlen(iface) >= sizeof(ifr.ifr_name)) {
00120     ACE_ERROR((LM_ERROR,
00121       ACE_TEXT("Interface name %C exceeds max allowable length, must be < %d."),
00122       iface, IFNAMSIZ));
00123     return -1;
00124   }
00125   std::strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
00126   const ACE_HANDLE h = ACE_OS::socket(PF_INET, SOCK_DGRAM, 0);
00127   if (h == ACE_INVALID_HANDLE) {
00128     return -1;
00129   }
00130   if (ACE_OS::ioctl(h, SIOCGIFHWADDR, &ifr) < 0) {
00131     ACE_OS::close(h);
00132     return -1;
00133   }
00134   ACE_OS::close(h);
00135   std::memcpy(node_id_, ifr.ifr_addr.sa_data, sizeof node_id_);
00136   return 0;
00137 #elif defined ACE_HAS_SIOCGIFCONF || defined ACE_HAS_MAC_OSX
00138   const ACE_HANDLE h = ACE_OS::socket(AF_INET, SOCK_DGRAM, 0);
00139   if (h == ACE_INVALID_HANDLE) {
00140     return -1;
00141   }
00142 
00143   const int BUFFERSIZE = 4000;
00144   char buffer[BUFFERSIZE];
00145   ifconf ifc;
00146   ifc.ifc_len = BUFFERSIZE;
00147   ifc.ifc_buf = buffer;
00148 
00149   if (ACE_OS::ioctl(h, SIOCGIFCONF, &ifc) < 0) {
00150     ACE_OS::close(h);
00151     return -1;
00152   }
00153 
00154   bool found = false;
00155   for (const char* ptr = buffer; !found && ptr < buffer + ifc.ifc_len;) {
00156     const ifreq* ifr = reinterpret_cast<const ifreq*>(ptr);
00157     if (ifr->ifr_addr.sa_family == AF_LINK && ifr->ifr_name == interface_name_) {
00158       const sockaddr_dl* sdl =
00159         reinterpret_cast<const sockaddr_dl*>(&ifr->ifr_addr);
00160       std::memcpy(node_id_, LLADDR(sdl), sizeof node_id_);
00161       found = true;
00162     }
00163 
00164     ptr += sizeof ifr->ifr_name + std::max(sizeof ifr->ifr_addr,
00165       static_cast<size_t>(ifr->ifr_addr.sa_len));
00166   }
00167 
00168   ACE_OS::close(h);
00169   return found ? 0 : -1;
00170 #elif defined ACE_VXWORKS
00171   int name[] = {CTL_NET, AF_ROUTE, 0, 0, NET_RT_IFLIST, 0};
00172   static const size_t name_elts = sizeof name / sizeof name[0];
00173 
00174   size_t result_sz = 0u;
00175   if (sysctl(name, name_elts, 0, &result_sz, 0, 0u) != 0) {
00176     return -1;
00177   }
00178 
00179   ACE_Allocator* const alloc = DCPS::SafetyProfilePool::instance();
00180   char* const result = static_cast<char*>(alloc->malloc(result_sz));
00181 
00182   if (sysctl(name, name_elts, result, &result_sz, 0, 0u) != 0) {
00183     alloc->free(result);
00184     return -1;
00185   }
00186 
00187   for (size_t pos = 0, n; pos + sizeof(if_msghdr) < result_sz; pos += n) {
00188     if_msghdr* const hdr = reinterpret_cast<if_msghdr*>(result + pos);
00189     n = hdr->ifm_msglen;
00190     sockaddr_dl* const addr =
00191       reinterpret_cast<sockaddr_dl*>(result + pos + sizeof(if_msghdr));
00192 
00193     if (hdr->ifm_type == RTM_IFINFO && (hdr->ifm_addrs & RTA_IFP)
00194         && std::memcmp(addr->sdl_data, iface, addr->sdl_nlen) == 0
00195         && addr->sdl_alen >= sizeof node_id_) {
00196       std::memcpy(node_id_, LLADDR(addr), sizeof node_id_);
00197       alloc->free(result);
00198       return 0;
00199     }
00200 
00201     while (pos + n < result_sz) {
00202       if_msghdr* const nxt = reinterpret_cast<if_msghdr*>(result + pos + n);
00203       if (nxt->ifm_type != RTM_NEWADDR) {
00204         break;
00205       }
00206       n += nxt->ifm_msglen;
00207     }
00208   }
00209 
00210   alloc->free(result);
00211   return -1;
00212 #else
00213   return -1;
00214 #endif
00215 }

Here is the call graph for this function:

Here is the caller graph for this function:

void OpenDDS::RTPS::GuidGenerator::populate ( DCPS::GUID_t container  ) 

populate a GUID container with a unique ID. This will increment the counter, and use a lock (if compiled with MT ACE) while doing so.

Definition at line 218 of file GuidGenerator.cpp.

References getCount(), OpenDDS::DCPS::GUID_t::guidPrefix, ACE_OS::memcpy(), node_id_, NODE_ID_SIZE, pid_, and OpenDDS::DCPS::VENDORID_OCI.

Referenced by OpenDDS::RTPS::RtpsDiscovery::add_domain_participant(), and OpenDDS::RTPS::RtpsDiscovery::generate_participant_guid().

00219 {
00220   container.guidPrefix[0] = DCPS::VENDORID_OCI[0];
00221   container.guidPrefix[1] = DCPS::VENDORID_OCI[1];
00222 
00223   const ACE_UINT16 count = getCount();
00224   ACE_OS::memcpy(&container.guidPrefix[2], node_id_, NODE_ID_SIZE);
00225   container.guidPrefix[8] = static_cast<CORBA::Octet>(pid_ >> 8);
00226   container.guidPrefix[9] = static_cast<CORBA::Octet>(pid_ & 0xFF);
00227   container.guidPrefix[10] = static_cast<CORBA::Octet>(count >> 8);
00228   container.guidPrefix[11] = static_cast<CORBA::Octet>(count & 0xFF);
00229 }

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 62 of file GuidGenerator.h.

Referenced by getCount().

Definition at line 61 of file GuidGenerator.h.

Referenced by getCount().

Definition at line 63 of file GuidGenerator.h.

Referenced by interfaceName().

Definition at line 59 of file GuidGenerator.h.

Referenced by GuidGenerator(), interfaceName(), and populate().

Definition at line 60 of file GuidGenerator.h.

Referenced by GuidGenerator(), and populate().


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 10 Aug 2018 for OpenDDS by  doxygen 1.6.1