1 // Copyright Leandro Lucarella 2008 - 2010.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file COPYING or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
7 #ifndef POSIXX_LINUX_TIPC_HPP_
8 #define POSIXX_LINUX_TIPC_HPP_
10 #include "../socket/basic_socket.hpp" // posixx::socket
12 #include <linux/tipc.h> // all tipc stuff
13 #include <cstring> // memcpy
19 /// Linux specific functionality
22 /// TIPC socket domain.
27 /// Configuration port name.
28 CFG_SRV = TIPC_CFG_SRV,
29 /// Topology discovery port name.
30 TOP_SRV = TIPC_TOP_SRV,
31 /// Name of the last reserved port.
32 RESERVED_TYPES = TIPC_RESERVED_TYPES,
33 /// Maximum message size.
34 MAX_USER_MSG_SIZE = TIPC_MAX_USER_MSG_SIZE,
35 /// Wait forever (for subscriptions).
36 WAIT_FOREVER = TIPC_WAIT_FOREVER
50 * Constructor from a raw 32-bit address.
52 * @param addr Raw 32-bit address.
54 explicit addr(__u32 addr) throw ();
57 * Constructor from a zone, cluster and node information.
60 * @param cluster Cluster.
63 addr(unsigned int zone, unsigned int cluster, unsigned int node)
67 void zone(unsigned int zone) throw ();
70 unsigned int zone() const throw ();
73 void cluster(unsigned int cluster) throw ();
76 unsigned int cluster() const throw ();
79 void node(unsigned int node) throw ();
82 unsigned int node() const throw ();
84 /// Cast to a raw 32-bit address.
85 operator __u32 () const throw ();
92 * @see tipc_portid struct from linux/tipc.h.
94 struct portid: tipc_portid
100 * @param ref Unique ID fo the port in the address.
101 * @param node Node address.
103 portid(__u32 ref, addr node) throw ();
105 /// Access to the node addr.
106 addr& node_addr() throw ();
108 /// Access to the node addr.
109 const addr& node_addr() const throw ();
111 /// Compares 2 port ids.
112 bool operator == (const portid& other) const throw ();
119 * @see tipc_name struct from linux/tipc.h.
121 struct name: tipc_name
127 * @param type Type of the named port.
128 * @param instance Instance of the named port.
130 name(__u32 type, __u32 instance) throw ();
132 /// Compares 2 port names.
133 bool operator == (const name& other) const throw ();
140 * @see tipc_name_seq struct from linux/tipc.h.
142 struct nameseq: tipc_name_seq
148 * @param type Type of the sequence.
149 * @param lower Lower bound.
150 * @param upper Upper bound.
153 nameseq(__u32 type, __u32 lower, __u32 upper) throw ();
157 * @param type Type of the sequence.
158 * @param instance Lower and upper bound.
160 nameseq(__u32 type, __u32 instance) throw ();
162 /// Compares 2 port name sequences.
163 bool operator == (const nameseq& other) const throw ();
168 * Reasons for returned messages when recvmsg() is used.
170 * @see recvmsg(2) of TIPC documentation
174 /// Not a returned message.
176 /// Port name doesn't exist.
177 ERR_NO_NAME = TIPC_ERR_NO_NAME,
178 /// Port ID doesn't exist.
179 ERR_NO_PORT = TIPC_ERR_NO_PORT,
180 /// Node doesn't exist.
181 ERR_NO_NODE = TIPC_ERR_NO_NODE,
182 /// Reception queue is full.
183 ERR_OVERLOAD = TIPC_ERR_OVERLOAD,
184 /// Connection shutted down.
185 CONN_SHUTDOWN = TIPC_CONN_SHUTDOWN
189 * Subscription filter type.
191 * @see TIPC documentation: 1.4.3 Name Subscriptions
197 * Causes the topology service to generate a PUBLISHED event
198 * for each port name or port name sequence it finds that overlaps
199 * the specified port name sequence; a WITHDRAWN event is issued
200 * each time a previously reported name becomes unavailable.
202 * Allows the topology service to inform the application if there
203 * are @b any ports of interest.
205 SUB_PORTS = TIPC_SUB_PORTS,
208 * Causes the topology service to generate a single publish event for
209 * the first port it finds with an overlapping name and a single
210 * withdraw event when the last such port becomes unavailable.
212 * Allows the topology service to inform the application about
213 * @b all ports of interest.
215 SUB_SERVICE = TIPC_SUB_SERVICE,
218 * Instruct the topology service to cancel a previously requested
221 * The application simply resends the original subscription request
222 * with SUB_CANCEL logically OR'd into the event filter.
224 * @note This is implemented in TIPC 1.7+ only (according to TIPC
227 SUB_CANCEL = TIPC_SUB_CANCEL
232 * Subscription request message.
234 * @see TIPC documentation: 1.4.3 Name Subscriptions
236 struct subscr: tipc_subscr
242 * @param seq The port name sequence of interest to the application.
243 * @param timeout A subscription timeout value, in ms
245 * @param filter An event filter specifying which events are of
246 * interest to the application (see subscr_t).
247 * @param usr_handle An 8 byte user handle that is application-defined,
248 * (treated as a string).
250 subscr(nameseq seq, __u32 timeout, __u32 filter,
251 const char* usr_handle = "") throw ();
256 * @param seq The port name sequence of interest to the application.
257 * @param timeout A subscription timeout value, in ms
259 * @param filter An event filter specifying which events are of
260 * interest to the application (see subscr_t).
261 * @param usr_handle An 8 byte user handle that is application-defined.
262 * (treated as binary data).
263 * @param handle_size Size of the usr_handle buffer (it should be at
266 subscr(nameseq seq, __u32 timeout, __u32 filter,
267 const char* usr_handle, size_t handle_size)
270 /// Access to the subscribed name sequence.
271 nameseq& name_seq() throw ();
273 /// Access to the subscribed name sequence.
274 const nameseq& name_seq() const throw ();
276 /// Set the user handle as a string.
277 void handle(const char* usr_handle) throw ();
279 /// Set the user handle as binary data.
280 void handle(const char* usr_handle, size_t handle_size) throw ();
282 /// Compares 2 subscription request messages.
283 bool operator == (const subscr& other) const throw ();
291 /// The port has been published.
292 PUBLISHED = TIPC_PUBLISHED,
294 /// The port has been withdrawn.
295 WITHDRAWN = TIPC_WITHDRAWN,
297 /// The event has timed out.
298 TIMEOUT = TIPC_SUBSCR_TIMEOUT
305 * @see TIPC documentation: 1.4.3 Name Subscriptions
307 struct subscr_event: tipc_event
310 /// Access to the subscribed name sequence.
311 portid& port_id() throw ();
313 /// Access to the subscribed name sequence.
314 const portid& port_id() const throw ();
316 /// Access to the subscribed name sequence.
317 subscr& subscription() throw ();
319 /// Access to the subscribed name sequence.
320 const subscr& subscription() const throw ();
324 /// Type of TIPC address
327 ID = TIPC_ADDR_ID, ///< Port ID
328 NAME = TIPC_ADDR_NAME, ///< Port name
329 NAMESEQ = TIPC_ADDR_NAMESEQ ///< Name sequence or multicast
335 * @see TIPC documentation: 2.1.2 bind
339 ZONE = TIPC_ZONE_SCOPE, ///< Zone scope.
340 CLUSTER = TIPC_CLUSTER_SCOPE, ///< Cluster scope.
341 NODE = TIPC_NODE_SCOPE ///< Node scope.
345 * TIPC socket address (name).
347 * @see bind(2), Socket::bind()
348 * @see connect(2), Socket::connect()
349 * @see getsockaddr(2), Socket::getsockaddr()
350 * @see setsockaddr(2), Socket::setsockaddr()
351 * @see accept(2), Socket::accept()
352 * @see sendto(2), Socket::send()
353 * @see recvfrom(2), Socket::recv()
355 struct sockaddr: sockaddr_tipc
362 * Constructor using a port ID.
364 * @param port Port ID.
365 * @param scope Bind scope.
367 sockaddr(portid port, scope_t scope = ZONE) throw ();
370 * Constructor using a port name.
372 * @param name Port name.
373 * @param scope Bind scope.
374 * @param domain Domain lookup.
376 * @see Documentación de TIPC: 1.4.1 Address Resolution
378 sockaddr(name name, scope_t scope = ZONE,
379 tipc::addr domain = tipc::addr(0u))
383 * Constructor using a port name sequence.
385 * @param nameseq Port name sequence.
386 * @param scope Bind scope.
388 sockaddr(nameseq nameseq, scope_t scope = ZONE) throw ();
390 /// Type of TIPC address
391 type_t type() const throw ();
393 /// Length of this unix socket address
394 socklen_t length() const throw ();
396 /// Compare two TIPC socket addresses
397 bool operator == (const sockaddr& other) const throw ();
399 /// Access to the port ID (only valid if addrtype == ID)
400 portid& port_id() throw ();
402 /// Access to the port ID (only valid if addrtype == ID)
403 const portid& port_id() const throw ();
405 /// Access to the port name (only valid if addrtype == NAME)
406 name& port_name() throw ();
408 /// Access to the port name (only valid if addrtype == NAME)
409 const name& port_name() const throw ();
411 /// Access to the port name domain (only valid if addrtype == NAME)
412 tipc::addr& name_domain() throw ();
414 /// Access to the port name domain (only valid if addrtype == NAME)
415 const tipc::addr& name_domain() const throw ();
417 /// Access to the port name sequence (only valid if addrtype == NAMESEQ)
418 nameseq& name_seq() throw ();
420 /// Access to the port name sequence (only valid if addrtype == NAMESEQ)
421 const nameseq& name_seq() const throw ();
425 /// TIPC socket traits.
429 /// Socket address type.
430 typedef tipc::sockaddr sockaddr;
433 enum { PF = PF_TIPC };
438 typedef posixx::socket::basic_socket< traits > socket;
440 } } } // namespace posixx::linux::tipc
444 posixx::linux::tipc::addr::addr() throw (): address(0u)
449 posixx::linux::tipc::addr::addr(__u32 address) throw (): address(address)
454 posixx::linux::tipc::addr::addr(unsigned int zone, unsigned int cluster,
455 unsigned int node) throw ():
456 address(tipc_addr(zone, cluster, node))
461 void posixx::linux::tipc::addr::zone(unsigned int zone) throw ()
463 address = tipc_addr(zone, cluster(), node());
467 unsigned int posixx::linux::tipc::addr::zone() const throw ()
469 return tipc_zone(address);
473 void posixx::linux::tipc::addr::cluster(unsigned int cluster) throw ()
475 address = tipc_addr(zone(), cluster, node());
479 unsigned int posixx::linux::tipc::addr::cluster() const throw ()
481 return tipc_cluster(address);
485 void posixx::linux::tipc::addr::node(unsigned int node) throw ()
487 address = tipc_addr(zone(), cluster(), node);
491 unsigned int posixx::linux::tipc::addr::node() const throw ()
493 return tipc_node(address);
497 posixx::linux::tipc::addr::operator __u32 () const throw ()
503 posixx::linux::tipc::portid::portid(__u32 r, addr n) throw ()
510 posixx::linux::tipc::addr& posixx::linux::tipc::portid::node_addr() throw ()
512 return *reinterpret_cast<addr*>(&node);
516 const posixx::linux::tipc::addr& posixx::linux::tipc::portid::node_addr() const
519 return *reinterpret_cast<const addr*>(&node);
523 bool posixx::linux::tipc::portid::operator == (
524 const posixx::linux::tipc::portid& other) const throw ()
526 return memcmp(this, &other, sizeof(*this)) == 0;
530 posixx::linux::tipc::name::name(__u32 t, __u32 i) throw ()
537 bool posixx::linux::tipc::name::operator == (
538 const posixx::linux::tipc::name& other) const throw ()
540 return memcmp(this, &other, sizeof(*this)) == 0;
544 posixx::linux::tipc::nameseq::nameseq(__u32 t, __u32 low, __u32 up) throw ()
552 posixx::linux::tipc::nameseq::nameseq(__u32 t, __u32 instance) throw ()
560 bool posixx::linux::tipc::nameseq::operator == (
561 const posixx::linux::tipc::nameseq& other) const throw ()
563 return memcmp(this, &other, sizeof(*this)) == 0;
567 posixx::linux::tipc::subscr::subscr(nameseq s, __u32 t, __u32 f,
568 const char* uh) throw ()
577 posixx::linux::tipc::subscr::subscr(nameseq s, __u32 t, __u32 f,
578 const char* uh, size_t uh_size) throw ()
587 posixx::linux::tipc::nameseq& posixx::linux::tipc::subscr::name_seq() throw ()
589 return *reinterpret_cast<nameseq*>(&seq);
593 const posixx::linux::tipc::nameseq&
594 posixx::linux::tipc::subscr::name_seq() const throw ()
596 return *reinterpret_cast<const nameseq*>(&seq);
600 void posixx::linux::tipc::subscr::handle(const char* uh) throw ()
602 std::strncpy(usr_handle, uh, sizeof(usr_handle));
606 void posixx::linux::tipc::subscr::handle(const char* uh, size_t uh_size)
609 std::memcpy(usr_handle, uh, uh_size);
613 bool posixx::linux::tipc::subscr::operator == (const subscr& other) const
616 return memcmp(this, &other, sizeof(*this)) == 0;
620 posixx::linux::tipc::portid& posixx::linux::tipc::subscr_event::port_id()
623 return *reinterpret_cast<portid*>(&port);
627 const posixx::linux::tipc::portid& posixx::linux::tipc::subscr_event::port_id()
630 return *reinterpret_cast<const portid*>(&port);
634 posixx::linux::tipc::subscr& posixx::linux::tipc::subscr_event::subscription()
637 return *reinterpret_cast<subscr*>(&s);
641 const posixx::linux::tipc::subscr&
642 posixx::linux::tipc::subscr_event::subscription() const throw ()
644 return *reinterpret_cast<const subscr*>(&s);
648 posixx::linux::tipc::sockaddr::sockaddr() throw ()
650 memset(this, 0, sizeof(*this));
655 posixx::linux::tipc::sockaddr::sockaddr(portid port, scope_t s) throw ()
664 posixx::linux::tipc::sockaddr::sockaddr(name name, scope_t s, tipc::addr d)
670 addr.name.name = name;
671 addr.name.domain = d;
675 posixx::linux::tipc::sockaddr::sockaddr(nameseq nameseq, scope_t s) throw ()
680 addr.nameseq = nameseq;
684 posixx::linux::tipc::type_t posixx::linux::tipc::sockaddr::type()
687 return static_cast< type_t >(addrtype);
691 socklen_t posixx::linux::tipc::sockaddr::length() const throw ()
693 return sizeof(sockaddr_tipc);
697 bool posixx::linux::tipc::sockaddr::operator == (const sockaddr& other) const
700 if (family != other.family)
702 if (addrtype != other.addrtype)
704 if (scope != other.scope)
707 return port_id() == other.port_id();
708 if (addrtype == NAME)
709 return name_domain() == other.name_domain()
710 && port_name() == other.port_name();
711 if (addrtype == NAMESEQ)
712 return name_seq() == other.name_seq();
713 return memcmp(this, &other, sizeof(*this)) == 0;
717 posixx::linux::tipc::portid& posixx::linux::tipc::sockaddr::port_id() throw ()
719 return *reinterpret_cast<portid*>(&addr.id);
723 const posixx::linux::tipc::portid& posixx::linux::tipc::sockaddr::port_id()
726 return *reinterpret_cast<const portid*>(&addr.id);
730 posixx::linux::tipc::name& posixx::linux::tipc::sockaddr::port_name() throw ()
732 return *reinterpret_cast<name*>(&addr.name.name);
736 const posixx::linux::tipc::name& posixx::linux::tipc::sockaddr::port_name()
739 return *reinterpret_cast<const name*>(&addr.name.name);
743 posixx::linux::tipc::addr& posixx::linux::tipc::sockaddr::name_domain()
746 return *reinterpret_cast<tipc::addr*>(&addr.name.domain);
750 const posixx::linux::tipc::addr& posixx::linux::tipc::sockaddr::name_domain()
753 return *reinterpret_cast<const tipc::addr*>(&addr.name.domain);
757 posixx::linux::tipc::nameseq& posixx::linux::tipc::sockaddr::name_seq()
760 return *reinterpret_cast<nameseq*>(&addr.nameseq);
764 const posixx::linux::tipc::nameseq& posixx::linux::tipc::sockaddr::name_seq()
767 return *reinterpret_cast<const nameseq*>(&addr.nameseq);
770 #endif // POSIXX_LINUX_TIPC_HPP_