1 #ifndef POSIXX_LINUX_TIPC_HPP_
2 #define POSIXX_LINUX_TIPC_HPP_
4 #include "../socket/basic_socket.hpp" // posixx::socket
6 #include <linux/tipc.h> // all tipc stuff
7 #include <cstring> // memcpy
13 /// Linux specific functionality
16 /// TIPC socket domain.
21 /// Configuration port name.
22 CFG_SRV = TIPC_CFG_SRV,
23 /// Topology discovery port name.
24 TOP_SRV = TIPC_TOP_SRV,
25 /// Name of the last reserved port.
26 RESERVED_TYPES = TIPC_RESERVED_TYPES,
27 /// Maximum message size.
28 MAX_USER_MSG_SIZE = TIPC_MAX_USER_MSG_SIZE,
29 /// Wait forever (for subscriptions).
30 WAIT_FOREVER = TIPC_WAIT_FOREVER
44 * Constructor from a raw 32-bit address.
46 * @param addr Raw 32-bit address.
48 explicit addr(__u32 addr) throw ();
51 * Constructor from a zone, cluster and node information.
54 * @param cluster Cluster.
57 addr(unsigned int zone, unsigned int cluster, unsigned int node)
61 void zone(unsigned int zone) throw ();
64 unsigned int zone() const throw ();
67 void cluster(unsigned int cluster) throw ();
70 unsigned int cluster() const throw ();
73 void node(unsigned int node) throw ();
76 unsigned int node() const throw ();
78 /// Cast to a raw 32-bit address.
79 operator __u32 () const throw ();
86 * @see tipc_portid struct from linux/tipc.h.
88 struct portid: tipc_portid
94 * @param ref Unique ID fo the port in the address.
95 * @param node Node address.
97 portid(__u32 ref, addr node) throw ();
99 /// Access to the node addr.
100 addr& node_addr() throw ();
102 /// Access to the node addr.
103 const addr& node_addr() const throw ();
105 /// Compares 2 port ids.
106 bool operator == (const portid& other) const throw ();
113 * @see tipc_name struct from linux/tipc.h.
115 struct name: tipc_name
121 * @param type Type of the named port.
122 * @param instance Instance of the named port.
124 name(__u32 type, __u32 instance) throw ();
126 /// Compares 2 port names.
127 bool operator == (const name& other) const throw ();
134 * @see tipc_name_seq struct from linux/tipc.h.
136 struct nameseq: tipc_name_seq
142 * @param type Type of the sequence.
143 * @param lower Lower bound.
144 * @param upper Upper bound.
147 nameseq(__u32 type, __u32 lower, __u32 upper) throw ();
151 * @param type Type of the sequence.
152 * @param instance Lower and upper bound.
154 nameseq(__u32 type, __u32 instance) throw ();
156 /// Compares 2 port name sequences.
157 bool operator == (const nameseq& other) const throw ();
162 * Reasons for returned messages when recvmsg() is used.
164 * @see recvmsg(2) of TIPC documentation
168 /// Not a returned message.
170 /// Port name doesn't exist.
171 ERR_NO_NAME = TIPC_ERR_NO_NAME,
172 /// Port ID doesn't exist.
173 ERR_NO_PORT = TIPC_ERR_NO_PORT,
174 /// Node doesn't exist.
175 ERR_NO_NODE = TIPC_ERR_NO_NODE,
176 /// Reception queue is full.
177 ERR_OVERLOAD = TIPC_ERR_OVERLOAD,
178 /// Connection shutted down.
179 CONN_SHUTDOWN = TIPC_CONN_SHUTDOWN
183 * Subscription filter type.
185 * @see TIPC documentation: 1.4.3 Name Subscriptions
191 * Causes the topology service to generate a PUBLISHED event
192 * for each port name or port name sequence it finds that overlaps
193 * the specified port name sequence; a WITHDRAWN event is issued
194 * each time a previously reported name becomes unavailable.
196 * Allows the topology service to inform the application if there
197 * are @b any ports of interest.
199 SUB_PORTS = TIPC_SUB_PORTS,
202 * Causes the topology service to generate a single publish event for
203 * the first port it finds with an overlapping name and a single
204 * withdraw event when the last such port becomes unavailable.
206 * Allows the topology service to inform the application about
207 * @b all ports of interest.
209 SUB_SERVICE = TIPC_SUB_SERVICE,
212 * Instruct the topology service to cancel a previously requested
215 * The application simply resends the original subscription request
216 * with SUB_CANCEL logically OR'd into the event filter.
218 * @note This is implemented in TIPC 1.7+ only (according to TIPC
221 SUB_CANCEL = TIPC_SUB_CANCEL
226 * Subscription request message.
228 * @see TIPC documentation: 1.4.3 Name Subscriptions
230 struct subscr: tipc_subscr
236 * @param seq The port name sequence of interest to the application.
237 * @param timeout A subscription timeout value, in ms
239 * @param filter An event filter specifying which events are of
240 * interest to the application (see subscr_t).
241 * @param usr_handle An 8 byte user handle that is application-defined,
242 * (treated as a string).
244 subscr(nameseq seq, __u32 timeout, __u32 filter,
245 const char* usr_handle = "") throw ();
250 * @param seq The port name sequence of interest to the application.
251 * @param timeout A subscription timeout value, in ms
253 * @param filter An event filter specifying which events are of
254 * interest to the application (see subscr_t).
255 * @param usr_handle An 8 byte user handle that is application-defined.
256 * (treated as binary data).
257 * @param handle_size Size of the usr_handle buffer (it should be at
260 subscr(nameseq seq, __u32 timeout, __u32 filter,
261 const char* usr_handle, size_t handle_size)
264 /// Access to the subscribed name sequence.
265 nameseq& name_seq() throw ();
267 /// Access to the subscribed name sequence.
268 const nameseq& name_seq() const throw ();
270 /// Set the user handle as a string.
271 void handle(const char* usr_handle) throw ();
273 /// Set the user handle as binary data.
274 void handle(const char* usr_handle, size_t handle_size) throw ();
276 /// Compares 2 subscription request messages.
277 bool operator == (const subscr& other) const throw ();
285 /// The port has been published.
286 PUBLISHED = TIPC_PUBLISHED,
288 /// The port has been withdrawn.
289 WITHDRAWN = TIPC_WITHDRAWN,
291 /// The event has timed out.
292 TIMEOUT = TIPC_SUBSCR_TIMEOUT
299 * @see TIPC documentation: 1.4.3 Name Subscriptions
301 struct subscr_event: tipc_event
304 /// Access to the subscribed name sequence.
305 portid& port_id() throw ();
307 /// Access to the subscribed name sequence.
308 const portid& port_id() const throw ();
310 /// Access to the subscribed name sequence.
311 subscr& subscription() throw ();
313 /// Access to the subscribed name sequence.
314 const subscr& subscription() const throw ();
319 * TIPC socket address (name).
321 * @see bind(2), Socket::bind()
322 * @see connect(2), Socket::connect()
323 * @see getsockaddr(2), Socket::getsockaddr()
324 * @see setsockaddr(2), Socket::setsockaddr()
325 * @see accept(2), Socket::accept()
326 * @see sendto(2), Socket::send()
327 * @see recvfrom(2), Socket::recv()
329 struct sockaddr: sockaddr_tipc
332 /// Type of TIPC address
335 ID = TIPC_ADDR_ID, ///< Port ID
336 NAME = TIPC_ADDR_NAME, ///< Port name
337 NAMESEQ = TIPC_ADDR_NAMESEQ ///< Name sequence or multicast
343 * @see TIPC documentation: 2.1.2 bind
347 ZONE = TIPC_ZONE_SCOPE, ///< Zone scope.
348 CLUSTER = TIPC_CLUSTER_SCOPE, ///< Cluster scope.
349 NODE = TIPC_NODE_SCOPE ///< Node scope.
356 * Constructor using a port ID.
358 * @param port Port ID.
359 * @param scope Bind scope.
361 sockaddr(portid port, scope_t scope = ZONE) throw ();
364 * Constructor using a port name.
366 * @param name Port name.
367 * @param scope Bind scope.
368 * @param domain Domain lookup.
370 * @see Documentación de TIPC: 1.4.1 Address Resolution
372 sockaddr(name name, scope_t scope = ZONE,
373 tipc::addr domain = tipc::addr(0u))
377 * Constructor using a port name sequence.
379 * @param nameseq Port name sequence.
380 * @param scope Bind scope.
382 sockaddr(nameseq nameseq, scope_t scope = ZONE) throw ();
384 /// Type of TIPC address
385 type_t type() const throw ();
387 /// Length of this unix socket address
388 socklen_t length() const throw ();
390 /// Compare two TIPC socket addresses
391 bool operator == (const sockaddr& other) const throw ();
393 /// Access to the port ID (only valid if addrtype == ID)
394 portid& port_id() throw ();
396 /// Access to the port ID (only valid if addrtype == ID)
397 const portid& port_id() const throw ();
399 /// Access to the port name (only valid if addrtype == NAME)
400 name& port_name() throw ();
402 /// Access to the port name (only valid if addrtype == NAME)
403 const name& port_name() const throw ();
405 /// Access to the port name domain (only valid if addrtype == NAME)
406 tipc::addr& name_domain() throw ();
408 /// Access to the port name domain (only valid if addrtype == NAME)
409 const tipc::addr& name_domain() const throw ();
411 /// Access to the port name sequence (only valid if addrtype == NAMESEQ)
412 nameseq& name_seq() throw ();
414 /// Access to the port name sequence (only valid if addrtype == NAMESEQ)
415 const nameseq& name_seq() const throw ();
419 /// TIPC socket traits.
423 /// Socket address type.
424 typedef tipc::sockaddr sockaddr;
427 enum { PF = PF_TIPC };
432 typedef posixx::socket::basic_socket< traits > socket;
434 } } } // namespace posixx::linux::tipc
438 posixx::linux::tipc::addr::addr() throw (): address(0u)
443 posixx::linux::tipc::addr::addr(__u32 address) throw (): address(address)
448 posixx::linux::tipc::addr::addr(unsigned int zone, unsigned int cluster,
449 unsigned int node) throw ():
450 address(tipc_addr(zone, cluster, node))
455 void posixx::linux::tipc::addr::zone(unsigned int zone) throw ()
457 address = tipc_addr(zone, cluster(), node());
461 unsigned int posixx::linux::tipc::addr::zone() const throw ()
463 return tipc_zone(address);
467 void posixx::linux::tipc::addr::cluster(unsigned int cluster) throw ()
469 address = tipc_addr(zone(), cluster, node());
473 unsigned int posixx::linux::tipc::addr::cluster() const throw ()
475 return tipc_cluster(address);
479 void posixx::linux::tipc::addr::node(unsigned int node) throw ()
481 address = tipc_addr(zone(), cluster(), node);
485 unsigned int posixx::linux::tipc::addr::node() const throw ()
487 return tipc_node(address);
491 posixx::linux::tipc::addr::operator __u32 () const throw ()
497 posixx::linux::tipc::portid::portid(__u32 r, addr n) throw ()
504 posixx::linux::tipc::addr& posixx::linux::tipc::portid::node_addr() throw ()
506 return *reinterpret_cast<addr*>(&node);
510 const posixx::linux::tipc::addr& posixx::linux::tipc::portid::node_addr() const
513 return *reinterpret_cast<const addr*>(&node);
517 bool posixx::linux::tipc::portid::operator == (
518 const posixx::linux::tipc::portid& other) const throw ()
520 return memcmp(this, &other, sizeof(*this)) == 0;
524 posixx::linux::tipc::name::name(__u32 t, __u32 i) throw ()
531 bool posixx::linux::tipc::name::operator == (
532 const posixx::linux::tipc::name& other) const throw ()
534 return memcmp(this, &other, sizeof(*this)) == 0;
538 posixx::linux::tipc::nameseq::nameseq(__u32 t, __u32 low, __u32 up) throw ()
546 posixx::linux::tipc::nameseq::nameseq(__u32 t, __u32 instance) throw ()
554 bool posixx::linux::tipc::nameseq::operator == (
555 const posixx::linux::tipc::nameseq& other) const throw ()
557 return memcmp(this, &other, sizeof(*this)) == 0;
561 posixx::linux::tipc::subscr::subscr(nameseq s, __u32 t, __u32 f,
562 const char* uh) throw ()
571 posixx::linux::tipc::subscr::subscr(nameseq s, __u32 t, __u32 f,
572 const char* uh, size_t uh_size) throw ()
581 posixx::linux::tipc::nameseq& posixx::linux::tipc::subscr::name_seq() throw ()
583 return *reinterpret_cast<nameseq*>(&seq);
587 const posixx::linux::tipc::nameseq&
588 posixx::linux::tipc::subscr::name_seq() const throw ()
590 return *reinterpret_cast<const nameseq*>(&seq);
594 void posixx::linux::tipc::subscr::handle(const char* uh) throw ()
596 std::strncpy(usr_handle, uh, sizeof(usr_handle));
600 void posixx::linux::tipc::subscr::handle(const char* uh, size_t uh_size)
603 std::memcpy(usr_handle, uh, uh_size);
607 bool posixx::linux::tipc::subscr::operator == (const subscr& other) const
610 return memcmp(this, &other, sizeof(*this)) == 0;
614 posixx::linux::tipc::portid& posixx::linux::tipc::subscr_event::port_id()
617 return *reinterpret_cast<portid*>(&port);
621 const posixx::linux::tipc::portid& posixx::linux::tipc::subscr_event::port_id()
624 return *reinterpret_cast<const portid*>(&port);
628 posixx::linux::tipc::subscr& posixx::linux::tipc::subscr_event::subscription()
631 return *reinterpret_cast<subscr*>(&s);
635 const posixx::linux::tipc::subscr&
636 posixx::linux::tipc::subscr_event::subscription() const throw ()
638 return *reinterpret_cast<const subscr*>(&s);
642 posixx::linux::tipc::sockaddr::sockaddr() throw ()
644 memset(this, 0, sizeof(*this));
649 posixx::linux::tipc::sockaddr::sockaddr(portid port, scope_t s) throw ()
658 posixx::linux::tipc::sockaddr::sockaddr(name name, scope_t s, tipc::addr d)
664 addr.name.name = name;
665 addr.name.domain = d;
669 posixx::linux::tipc::sockaddr::sockaddr(nameseq nameseq, scope_t s) throw ()
674 addr.nameseq = nameseq;
678 posixx::linux::tipc::sockaddr::type_t posixx::linux::tipc::sockaddr::type()
681 return static_cast< type_t >(addrtype);
685 socklen_t posixx::linux::tipc::sockaddr::length() const throw ()
687 return sizeof(sockaddr_tipc);
691 bool posixx::linux::tipc::sockaddr::operator == (const sockaddr& other) const
694 if (family != other.family)
696 if (addrtype != other.addrtype)
698 if (scope != other.scope)
701 return port_id() == other.port_id();
702 if (addrtype == NAME)
703 return name_domain() == other.name_domain()
704 && port_name() == other.port_name();
705 if (addrtype == NAMESEQ)
706 return name_seq() == other.name_seq();
707 return memcmp(this, &other, sizeof(*this)) == 0;
711 posixx::linux::tipc::portid& posixx::linux::tipc::sockaddr::port_id() throw ()
713 return *reinterpret_cast<portid*>(&addr.id);
717 const posixx::linux::tipc::portid& posixx::linux::tipc::sockaddr::port_id()
720 return *reinterpret_cast<const portid*>(&addr.id);
724 posixx::linux::tipc::name& posixx::linux::tipc::sockaddr::port_name() throw ()
726 return *reinterpret_cast<name*>(&addr.name.name);
730 const posixx::linux::tipc::name& posixx::linux::tipc::sockaddr::port_name()
733 return *reinterpret_cast<const name*>(&addr.name.name);
737 posixx::linux::tipc::addr& posixx::linux::tipc::sockaddr::name_domain()
740 return *reinterpret_cast<tipc::addr*>(&addr.name.domain);
744 const posixx::linux::tipc::addr& posixx::linux::tipc::sockaddr::name_domain()
747 return *reinterpret_cast<const tipc::addr*>(&addr.name.domain);
751 posixx::linux::tipc::nameseq& posixx::linux::tipc::sockaddr::name_seq()
754 return *reinterpret_cast<nameseq*>(&addr.nameseq);
758 const posixx::linux::tipc::nameseq& posixx::linux::tipc::sockaddr::name_seq()
761 return *reinterpret_cast<const nameseq*>(&addr.nameseq);
764 #endif // POSIXX_LINUX_TIPC_HPP_