]> git.llucax.com Git - software/posixx.git/blob - src/linux/tipc.hpp
Add Boost License
[software/posixx.git] / src / linux / tipc.hpp
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)
5
6
7 #ifndef POSIXX_LINUX_TIPC_HPP_
8 #define POSIXX_LINUX_TIPC_HPP_
9
10 #include "../socket/basic_socket.hpp" // posixx::socket
11
12 #include <linux/tipc.h> // all tipc stuff
13 #include <cstring> // memcpy
14
15 /// @file
16
17 namespace posixx {
18
19 /// Linux specific functionality
20 namespace linux {
21
22 /// TIPC socket domain.
23 namespace tipc {
24
25 enum
26 {
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
37 };
38
39 /// TIPC Address
40 struct addr
41 {
42
43         /// 32-bit address.
44         __u32 address;
45
46         /// Constructor
47         addr() throw ();
48
49         /**
50          * Constructor from a raw 32-bit address.
51          *
52          * @param addr Raw 32-bit address.
53          */
54         explicit addr(__u32 addr) throw ();
55
56         /**
57          * Constructor from a zone, cluster and node information.
58          *
59          * @param zone Zone.
60          * @param cluster Cluster.
61          * @param node Node.
62          */
63         addr(unsigned int zone, unsigned int cluster, unsigned int node)
64                 throw ();
65
66         /// Set zone.
67         void zone(unsigned int zone) throw ();
68
69         /// Get zone.
70         unsigned int zone() const throw ();
71
72         /// Set cluster.
73         void cluster(unsigned int cluster) throw ();
74
75         /// Get cluster.
76         unsigned int cluster() const throw ();
77
78         /// Set node.
79         void node(unsigned int node) throw ();
80
81         /// Get node.
82         unsigned int node() const throw ();
83
84         /// Cast to a raw 32-bit address.
85         operator __u32 () const throw ();
86
87 };
88
89 /**
90  * Port Identificator.
91  *
92  * @see tipc_portid struct from linux/tipc.h.
93  */
94 struct portid: tipc_portid
95 {
96
97         /**
98          * Constructor.
99          *
100          * @param ref Unique ID fo the port in the address.
101          * @param node Node address.
102          */
103         portid(__u32 ref, addr node) throw ();
104
105         /// Access to the node addr.
106         addr& node_addr() throw ();
107
108         /// Access to the node addr.
109         const addr& node_addr() const throw ();
110
111         /// Compares 2 port ids.
112         bool operator == (const portid& other) const throw ();
113
114 };
115
116 /**
117  * Named port.
118  *
119  * @see tipc_name struct from linux/tipc.h.
120  */
121 struct name: tipc_name
122 {
123
124         /**
125          * Constructor.
126          *
127          * @param type Type of the named port.
128          * @param instance Instance of the named port.
129          */
130         name(__u32 type, __u32 instance) throw ();
131
132         /// Compares 2 port names.
133         bool operator == (const name& other) const throw ();
134
135 };
136
137 /**
138  * Port sequence.
139  *
140  * @see tipc_name_seq struct from linux/tipc.h.
141  */
142 struct nameseq: tipc_name_seq
143 {
144
145         /**
146          * Constructor.
147          *
148          * @param type Type of the sequence.
149          * @param lower Lower bound.
150          * @param upper Upper bound.
151          */
152
153         nameseq(__u32 type, __u32 lower, __u32 upper) throw ();
154         /**
155          * Constructor.
156          *
157          * @param type Type of the sequence.
158          * @param instance Lower and upper bound.
159          */
160         nameseq(__u32 type, __u32 instance) throw ();
161
162         /// Compares 2 port name sequences.
163         bool operator == (const nameseq& other) const throw ();
164
165 };
166
167 /**
168  * Reasons for returned messages when recvmsg() is used.
169  *
170  * @see recvmsg(2) of TIPC documentation
171  */
172 enum reason_t
173 {
174         /// Not a returned message.
175         OK = TIPC_OK,
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
186 };
187
188 /**
189  * Subscription filter type.
190  *
191  * @see TIPC documentation: 1.4.3 Name Subscriptions
192  */
193 enum subscr_t
194 {
195
196         /**
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.
201          *
202          * Allows the topology service to inform the application if there
203          * are @b any ports of interest.
204          */
205         SUB_PORTS = TIPC_SUB_PORTS,
206
207         /**
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.
211          *
212          * Allows the topology service to inform the application about
213          * @b all ports of interest.
214          */
215         SUB_SERVICE = TIPC_SUB_SERVICE,
216
217         /**
218          * Instruct the topology service to cancel a previously requested
219          * subscription.
220          *
221          * The application simply resends the original subscription request
222          * with SUB_CANCEL logically OR'd into the event filter.
223          *
224          * @note This is implemented in TIPC 1.7+ only (according to TIPC
225          *       documentation).
226          */
227         SUB_CANCEL = TIPC_SUB_CANCEL
228
229 };
230
231 /**
232  * Subscription request message.
233  *
234  * @see TIPC documentation: 1.4.3 Name Subscriptions
235  */
236 struct subscr: tipc_subscr
237 {
238
239         /**
240          * Constructor.
241          *
242          * @param seq The port name sequence of interest to the application.
243          * @param timeout A subscription timeout value, in ms
244          *                (or WAIT_FOREVER).
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).
249          */
250         subscr(nameseq seq, __u32 timeout, __u32 filter,
251                         const char* usr_handle = "") throw ();
252
253         /**
254          * Constructor.
255          *
256          * @param seq The port name sequence of interest to the application.
257          * @param timeout A subscription timeout value, in ms
258          *                (or WAIT_FOREVER).
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
264          *                    most 8)
265          */
266         subscr(nameseq seq, __u32 timeout, __u32 filter,
267                         const char* usr_handle, size_t handle_size)
268                         throw ();
269
270         /// Access to the subscribed name sequence.
271         nameseq& name_seq() throw ();
272
273         /// Access to the subscribed name sequence.
274         const nameseq& name_seq() const throw ();
275
276         /// Set the user handle as a string.
277         void handle(const char* usr_handle) throw ();
278
279         /// Set the user handle as binary data.
280         void handle(const char* usr_handle, size_t handle_size) throw ();
281
282         /// Compares 2 subscription request messages.
283         bool operator == (const subscr& other) const throw ();
284
285 };
286
287 /// Type of events.
288 enum event_t
289 {
290
291         /// The port has been published.
292         PUBLISHED = TIPC_PUBLISHED,
293
294         /// The port has been withdrawn.
295         WITHDRAWN = TIPC_WITHDRAWN,
296
297         /// The event has timed out.
298         TIMEOUT = TIPC_SUBSCR_TIMEOUT
299
300 };
301
302 /**
303  * Event message.
304  *
305  * @see TIPC documentation: 1.4.3 Name Subscriptions
306  */
307 struct subscr_event: tipc_event
308 {
309
310         /// Access to the subscribed name sequence.
311         portid& port_id() throw ();
312
313         /// Access to the subscribed name sequence.
314         const portid& port_id() const throw ();
315
316         /// Access to the subscribed name sequence.
317         subscr& subscription() throw ();
318
319         /// Access to the subscribed name sequence.
320         const subscr& subscription() const throw ();
321
322 };
323
324 /// Type of TIPC address
325 enum type_t
326 {
327         ID = TIPC_ADDR_ID,           ///< Port ID
328         NAME = TIPC_ADDR_NAME,       ///< Port name
329         NAMESEQ = TIPC_ADDR_NAMESEQ  ///< Name sequence or multicast
330 };
331
332 /**
333  * Bind scope.
334  *
335  * @see TIPC documentation: 2.1.2 bind
336  */
337 enum scope_t
338 {
339         ZONE = TIPC_ZONE_SCOPE,       ///< Zone scope.
340         CLUSTER = TIPC_CLUSTER_SCOPE, ///< Cluster scope.
341         NODE = TIPC_NODE_SCOPE        ///< Node scope.
342 };
343
344 /**
345  * TIPC socket address (name).
346  *
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()
354  */
355 struct sockaddr: sockaddr_tipc
356 {
357
358         /// Constructor.
359         sockaddr() throw ();
360
361         /**
362          * Constructor using a port ID.
363          *
364          * @param port Port ID.
365          * @param scope Bind scope.
366          */
367         sockaddr(portid port, scope_t scope = ZONE) throw ();
368
369         /**
370          * Constructor using a port name.
371          *
372          * @param name Port name.
373          * @param scope Bind scope.
374          * @param domain Domain lookup.
375          *
376          * @see Documentación de TIPC: 1.4.1 Address Resolution
377          */
378         sockaddr(name name, scope_t scope = ZONE,
379                         tipc::addr domain = tipc::addr(0u))
380                 throw ();
381
382         /**
383          * Constructor using a port name sequence.
384          *
385          * @param nameseq Port name sequence.
386          * @param scope Bind scope.
387          */
388         sockaddr(nameseq nameseq, scope_t scope = ZONE) throw ();
389
390         /// Type of TIPC address
391         type_t type() const throw ();
392
393         /// Length of this unix socket address
394         socklen_t length() const throw ();
395
396         /// Compare two TIPC socket addresses
397         bool operator == (const sockaddr& other) const throw ();
398
399         /// Access to the port ID (only valid if addrtype == ID)
400         portid& port_id() throw ();
401
402         /// Access to the port ID (only valid if addrtype == ID)
403         const portid& port_id() const throw ();
404
405         /// Access to the port name (only valid if addrtype == NAME)
406         name& port_name() throw ();
407
408         /// Access to the port name (only valid if addrtype == NAME)
409         const name& port_name() const throw ();
410
411         /// Access to the port name domain (only valid if addrtype == NAME)
412         tipc::addr& name_domain() throw ();
413
414         /// Access to the port name domain (only valid if addrtype == NAME)
415         const tipc::addr& name_domain() const throw ();
416
417         /// Access to the port name sequence (only valid if addrtype == NAMESEQ)
418         nameseq& name_seq() throw ();
419
420         /// Access to the port name sequence (only valid if addrtype == NAMESEQ)
421         const nameseq& name_seq() const throw ();
422
423 };
424
425 /// TIPC socket traits.
426 struct traits
427 {
428
429         /// Socket address type.
430         typedef tipc::sockaddr sockaddr;
431
432         /// Protocol family.
433         enum { PF = PF_TIPC };
434
435 };
436
437 /// TIPC socket
438 typedef posixx::socket::basic_socket< traits > socket;
439
440 } } } // namespace posixx::linux::tipc
441
442
443 inline
444 posixx::linux::tipc::addr::addr() throw (): address(0u)
445 {
446 }
447
448 inline
449 posixx::linux::tipc::addr::addr(__u32 address) throw (): address(address)
450 {
451 }
452
453 inline
454 posixx::linux::tipc::addr::addr(unsigned int zone, unsigned int cluster,
455                 unsigned int node) throw ():
456         address(tipc_addr(zone, cluster, node))
457 {
458 }
459
460 inline
461 void posixx::linux::tipc::addr::zone(unsigned int zone) throw ()
462 {
463         address = tipc_addr(zone, cluster(), node());
464 }
465
466 inline
467 unsigned int posixx::linux::tipc::addr::zone() const throw ()
468 {
469         return tipc_zone(address);
470 }
471
472 inline
473 void posixx::linux::tipc::addr::cluster(unsigned int cluster) throw ()
474 {
475         address = tipc_addr(zone(), cluster, node());
476 }
477
478 inline
479 unsigned int posixx::linux::tipc::addr::cluster() const throw ()
480 {
481         return tipc_cluster(address);
482 }
483
484 inline
485 void posixx::linux::tipc::addr::node(unsigned int node) throw ()
486 {
487         address = tipc_addr(zone(), cluster(), node);
488 }
489
490 inline
491 unsigned int posixx::linux::tipc::addr::node() const throw ()
492 {
493         return tipc_node(address);
494 }
495
496 inline
497 posixx::linux::tipc::addr::operator __u32 () const throw ()
498 {
499         return address;
500 }
501
502 inline
503 posixx::linux::tipc::portid::portid(__u32 r, addr n) throw ()
504 {
505         ref = r;
506         node = n;
507 }
508
509 inline
510 posixx::linux::tipc::addr& posixx::linux::tipc::portid::node_addr() throw ()
511 {
512         return *reinterpret_cast<addr*>(&node);
513 }
514
515 inline
516 const posixx::linux::tipc::addr& posixx::linux::tipc::portid::node_addr() const
517                 throw ()
518 {
519         return *reinterpret_cast<const addr*>(&node);
520 }
521
522 inline
523 bool posixx::linux::tipc::portid::operator == (
524                 const posixx::linux::tipc::portid& other) const throw ()
525 {
526         return memcmp(this, &other, sizeof(*this)) == 0;
527 }
528
529 inline
530 posixx::linux::tipc::name::name(__u32 t, __u32 i) throw ()
531 {
532         type = t;
533         instance = i;
534 }
535
536 inline
537 bool posixx::linux::tipc::name::operator == (
538                 const posixx::linux::tipc::name& other) const throw ()
539 {
540         return memcmp(this, &other, sizeof(*this)) == 0;
541 }
542
543 inline
544 posixx::linux::tipc::nameseq::nameseq(__u32 t, __u32 low, __u32 up) throw ()
545 {
546         type = t;
547         lower = low;
548         upper = up;
549 }
550
551 inline
552 posixx::linux::tipc::nameseq::nameseq(__u32 t, __u32 instance) throw ()
553 {
554         type = t;
555         lower = instance;
556         upper = instance;
557 }
558
559 inline
560 bool posixx::linux::tipc::nameseq::operator == (
561                 const posixx::linux::tipc::nameseq& other) const throw ()
562 {
563         return memcmp(this, &other, sizeof(*this)) == 0;
564 }
565
566 inline
567 posixx::linux::tipc::subscr::subscr(nameseq s, __u32 t, __u32 f,
568                 const char* uh) throw ()
569 {
570         seq = s;
571         timeout = t;
572         filter = f;
573         handle(uh);
574 }
575
576 inline
577 posixx::linux::tipc::subscr::subscr(nameseq s, __u32 t, __u32 f,
578                 const char* uh, size_t uh_size) throw ()
579 {
580         seq = s;
581         timeout = t;
582         filter = f;
583         handle(uh, uh_size);
584 }
585
586 inline
587 posixx::linux::tipc::nameseq& posixx::linux::tipc::subscr::name_seq() throw ()
588 {
589         return *reinterpret_cast<nameseq*>(&seq);
590 }
591
592 inline
593 const posixx::linux::tipc::nameseq&
594 posixx::linux::tipc::subscr::name_seq() const throw ()
595 {
596         return *reinterpret_cast<const nameseq*>(&seq);
597 }
598
599 inline
600 void posixx::linux::tipc::subscr::handle(const char* uh) throw ()
601 {
602         std::strncpy(usr_handle, uh, sizeof(usr_handle));
603 }
604
605 inline
606 void posixx::linux::tipc::subscr::handle(const char* uh, size_t uh_size)
607                 throw ()
608 {
609         std::memcpy(usr_handle, uh, uh_size);
610 }
611
612 inline
613 bool posixx::linux::tipc::subscr::operator == (const subscr& other) const
614                 throw ()
615 {
616         return memcmp(this, &other, sizeof(*this)) == 0;
617 }
618
619 inline
620 posixx::linux::tipc::portid& posixx::linux::tipc::subscr_event::port_id()
621                 throw ()
622 {
623         return *reinterpret_cast<portid*>(&port);
624 }
625
626 inline
627 const posixx::linux::tipc::portid& posixx::linux::tipc::subscr_event::port_id()
628                 const throw ()
629 {
630         return *reinterpret_cast<const portid*>(&port);
631 }
632
633 inline
634 posixx::linux::tipc::subscr& posixx::linux::tipc::subscr_event::subscription()
635                 throw ()
636 {
637         return *reinterpret_cast<subscr*>(&s);
638 }
639
640 inline
641 const posixx::linux::tipc::subscr&
642 posixx::linux::tipc::subscr_event::subscription() const throw ()
643 {
644         return *reinterpret_cast<const subscr*>(&s);
645 }
646
647 inline
648 posixx::linux::tipc::sockaddr::sockaddr() throw ()
649 {
650         memset(this, 0, sizeof(*this));
651         family = AF_TIPC;
652 }
653
654 inline
655 posixx::linux::tipc::sockaddr::sockaddr(portid port, scope_t s) throw ()
656 {
657         family = AF_TIPC;
658         addrtype = ID;
659         scope = s;
660         addr.id = port;
661 }
662
663 inline
664 posixx::linux::tipc::sockaddr::sockaddr(name name, scope_t s, tipc::addr d)
665                 throw ()
666 {
667         family = AF_TIPC;
668         addrtype = NAME;
669         scope = s;
670         addr.name.name = name;
671         addr.name.domain = d;
672 }
673
674 inline
675 posixx::linux::tipc::sockaddr::sockaddr(nameseq nameseq, scope_t s) throw ()
676 {
677         family = AF_TIPC;
678         addrtype = NAMESEQ;
679         scope = s;
680         addr.nameseq = nameseq;
681 }
682
683 inline
684 posixx::linux::tipc::type_t posixx::linux::tipc::sockaddr::type()
685                 const throw ()
686 {
687         return static_cast< type_t >(addrtype);
688 }
689
690 inline
691 socklen_t posixx::linux::tipc::sockaddr::length() const throw ()
692 {
693         return sizeof(sockaddr_tipc);
694 }
695
696 inline
697 bool posixx::linux::tipc::sockaddr::operator == (const sockaddr& other) const
698                 throw ()
699 {
700         if (family != other.family)
701                 return false;
702         if (addrtype != other.addrtype)
703                 return false;
704         if (scope != other.scope)
705                 return false;
706         if (addrtype == ID)
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;
714 }
715
716 inline
717 posixx::linux::tipc::portid& posixx::linux::tipc::sockaddr::port_id() throw ()
718 {
719         return *reinterpret_cast<portid*>(&addr.id);
720 }
721
722 inline
723 const posixx::linux::tipc::portid& posixx::linux::tipc::sockaddr::port_id()
724                 const throw ()
725 {
726         return *reinterpret_cast<const portid*>(&addr.id);
727 }
728
729 inline
730 posixx::linux::tipc::name& posixx::linux::tipc::sockaddr::port_name() throw ()
731 {
732         return *reinterpret_cast<name*>(&addr.name.name);
733 }
734
735 inline
736 const posixx::linux::tipc::name& posixx::linux::tipc::sockaddr::port_name()
737                 const throw ()
738 {
739         return *reinterpret_cast<const name*>(&addr.name.name);
740 }
741
742 inline
743 posixx::linux::tipc::addr& posixx::linux::tipc::sockaddr::name_domain()
744                 throw ()
745 {
746         return *reinterpret_cast<tipc::addr*>(&addr.name.domain);
747 }
748
749 inline
750 const posixx::linux::tipc::addr& posixx::linux::tipc::sockaddr::name_domain()
751                 const throw ()
752 {
753         return *reinterpret_cast<const tipc::addr*>(&addr.name.domain);
754 }
755
756 inline
757 posixx::linux::tipc::nameseq& posixx::linux::tipc::sockaddr::name_seq()
758                 throw ()
759 {
760         return *reinterpret_cast<nameseq*>(&addr.nameseq);
761 }
762
763 inline
764 const posixx::linux::tipc::nameseq& posixx::linux::tipc::sockaddr::name_seq()
765                 const throw ()
766 {
767         return *reinterpret_cast<const nameseq*>(&addr.nameseq);
768 }
769
770 #endif // POSIXX_LINUX_TIPC_HPP_