curl: reschedule uses GNUNET_CURL_perform2.
[oweals/gnunet.git] / src / include / gnunet_psyc_service.h
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2012, 2013 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14     
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 /**
20  * @author Gabor X Toth
21  * @author Christian Grothoff
22  *
23  * @file
24  * PSYC service
25  *
26  * @defgroup psyc  PSYC service
27  * Send/receive messages in PSYC channels and access the PSYC Store.
28  *
29  * Note that clients of this API are NOT expected to understand the PSYC message
30  * format, only the semantics!  Parsing (and serializing) the PSYC stream format
31  * is done within the implementation of the libgnunetpsyc library, and this API
32  * deliberately exposes as little as possible of the actual data stream format
33  * to the application!
34  *
35  * NOTE:
36  * - this API does not know about PSYC's "root" and "places";
37  *   there is no 'root' in GNUnet-PSYC as we're decentralized;
38  *   'places' and 'persons' are combined within the same
39  *   abstraction, that of a "channel".  Channels are identified
40  *   and accessed in this API using a public/private key.
41  *   Higher-level applications should use NAMES within GNS
42  *   to obtain public keys, and the distinction between
43  *   'places' and 'persons' can then be made with the help
44  *   of the naming system (and/or conventions).
45  *   Channels are (as in PSYC) organized into a hierarchy; each
46  *   channel master (the one with the private key) is then
47  *   the operator of the multicast group (its Origin in
48  *   the terminology of the multicast API).
49  * - The API supports passing large amounts of data using
50  *   'streaming' for the argument passed to a method.  State
51  *   and variables must fit into memory and cannot be streamed
52  *   (thus, no passing of 4 GB of data in a variable;
53  *   once we implement this, we might want to create a
54  *   @c \#define for the maximum size of a variable).
55  * - PSYC defines standard variables, methods, etc.  This
56  *   library deliberately abstracts over all of these; a
57  *   higher-level API should combine the naming system (GNS)
58  *   and standard methods (_converse, _notice, _request,
59  *   _warning, _error etc) and variables (_action, _color,
60  *   _time, etc).  However, this API does take over the
61  *   routing variables, specifically '_context' (channel),
62  *   and '_source'.  We only kind-of support '_target', as
63  *   the target is either everyone in the group or the
64  *   origin, and never just a single member of the group;
65  *   for such individual messages, an application needs to
66  *   construct an 'inbox' channel where the master (only)
67  *   receives messages (but never forwards; private responses
68  *   would be transmitted by joining the senders 'inbox'
69  *   channel -- or a inbox#bob subchannel).  The
70  *   goal for all of this is to keep the abstractions in this
71  *   API minimal: interaction with multicast, try \& slice,
72  *   state/variable/channel management.  Higher-level
73  *   operations belong elsewhere (so maybe this API should
74  *   be called 'PSYC-low', whereas a higher-level API
75  *   implementing defaults for standard methods and
76  *   variables might be called 'PSYC-std' or 'PSYC-high'.
77  *
78  *   In PSYC terminology this is simply called the "PSYC
79  *   routing layer" and the abstractions, for instance in
80  *   psyced, are quite similar. The higher one is called
81  *   "PSYC entity layer." In the text rendering of the
82  *   protocol the two are separated by an empty line. See
83  *   http://about.psyc.eu/Spec:Packet and related.  --lynX
84  *
85  * @{
86  */
87
88 #ifndef GNUNET_PSYC_SERVICE_H
89 #define GNUNET_PSYC_SERVICE_H
90
91 #ifdef __cplusplus
92 extern "C"
93 {
94 #if 0                           /* keep Emacsens' auto-indent happy */
95 }
96 #endif
97 #endif
98
99 #include "gnunet_util_lib.h"
100 #include "gnunet_multicast_service.h"
101 //Mingw work around
102 #ifdef MINGW
103     # ifndef  UINT64_MAX
104     # define  UINT64_MAX 0xffffffffffffffffULL
105     # endif
106 #endif
107
108 /**
109  * Version number of GNUnet-PSYC API.
110  */
111 #define GNUNET_PSYC_VERSION 0x00000000
112
113
114 /**
115  * Policy flags for a channel.
116  */
117 enum GNUNET_PSYC_ChannelFlags
118 {
119   /**
120    * Admission must be confirmed by the master.
121    */
122   GNUNET_PSYC_CHANNEL_ADMISSION_CONTROL = 1 << 0,
123
124   /**
125    * Past messages are only available to slaves who were admitted at the time
126    * they were sent to the channel.
127    */
128   GNUNET_PSYC_CHANNEL_RESTRICTED_HISTORY = 1 << 1
129 };
130
131
132 /**
133  * PSYC channel policies.
134  */
135 enum GNUNET_PSYC_Policy
136 {
137   /**
138    * Anyone can join the channel, without announcing their presence;
139    * all messages are always public and can be distributed freely.
140    * Joins may be announced, but this is not required.
141    */
142   GNUNET_PSYC_CHANNEL_ANONYMOUS = 0,
143
144   /**
145    * The master must approve membership to the channel, messages must only be
146    * distributed to current channel slaves.  This includes the channel
147    * state as well as transient messages.
148    */
149   GNUNET_PSYC_CHANNEL_PRIVATE
150     = GNUNET_PSYC_CHANNEL_ADMISSION_CONTROL
151     | GNUNET_PSYC_CHANNEL_RESTRICTED_HISTORY
152
153 #if IDEAS_FOR_FUTURE
154   /**
155    * Anyone can freely join the channel (no approval required);
156    * however, messages must only be distributed to current channel
157    * slaves, so the master must still acknowledge that the slave
158    * joined before transient messages are delivered.  As approval is
159    * guaranteed, the presistent channel state can be synchronized freely
160    * immediately, prior to master confirmation.
161    */
162   GNUNET_PSYC_CHANNEL_OPEN
163     = GNUNET_PSYC_CHANNEL_RESTRICTED_HISTORY,
164
165   /**
166    * The master must approve joins to the channel, but past messages can be
167    * freely distributed to slaves.
168    */
169   GNUNET_PSYC_CHANNEL_CLOSED
170     = GNUNET_PSYC_CHANNEL_ADMISSION_CONTROL,
171 #endif
172 };
173
174
175 enum GNUNET_PSYC_MessageFlags
176 {
177   /**
178    * Default / no flags.
179    */
180   GNUNET_PSYC_MESSAGE_DEFAULT = 0,
181
182   /**
183    * Historic message, retrieved from PSYCstore.
184    */
185   GNUNET_PSYC_MESSAGE_HISTORIC = 1 << 0,
186
187   /**
188    * Request from slave to master.
189    */
190   GNUNET_PSYC_MESSAGE_REQUEST = 1 << 1,
191
192   /**
193    * Message can be delivered out of order.
194    */
195   GNUNET_PSYC_MESSAGE_ORDER_ANY = 1 << 2
196 };
197
198
199 /**
200  * Values for the @a state_delta field of GNUNET_PSYC_MessageHeader.
201  */
202 enum GNUNET_PSYC_StateDeltaValues
203 {
204   GNUNET_PSYC_STATE_RESET = 0,
205
206   GNUNET_PSYC_STATE_NOT_MODIFIED = UINT64_MAX
207 };
208
209
210 GNUNET_NETWORK_STRUCT_BEGIN
211
212 /**
213  * A PSYC message.
214  *
215  * Used for single-fragment messages e.g. in a join request or response.
216  */
217 struct GNUNET_PSYC_Message
218 {
219   /**
220    * Message header with size and type information.
221    */
222   struct GNUNET_MessageHeader header;
223
224   /* Followed by concatenated PSYC message parts:
225    * messages with GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_* types
226    */
227 };
228
229
230 /**
231  * Header of a PSYC message.
232  *
233  * The PSYC service adds this when delivering the message to local clients,
234  * not present on the multicast layer.
235  */
236 struct GNUNET_PSYC_MessageHeader
237 {
238   /**
239    * Generic message header with size and type information.
240    */
241   struct GNUNET_MessageHeader header;
242
243   /**
244    * Flags for this message fragment.
245    *
246    * @see enum GNUNET_PSYC_MessageFlags
247    */
248   uint32_t flags GNUNET_PACKED;
249
250   /**
251    * Number of the message this message part belongs to.
252    * Monotonically increasing from 1.
253    */
254   uint64_t message_id GNUNET_PACKED;
255
256   /**
257    * Byte offset of this @e fragment of the @e message.
258    */
259   uint64_t fragment_offset GNUNET_PACKED;
260
261   /**
262    * Sending slave's public key.
263    * Not set if the message is from the master.
264    */
265   struct GNUNET_CRYPTO_EcdsaPublicKey slave_pub_key;
266
267   /* Followed by concatenated PSYC message parts:
268    * messages with GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_* types
269    */
270 };
271
272
273 /**
274  * The method of a message.
275  */
276 struct GNUNET_PSYC_MessageMethod
277 {
278   /**
279    * Type: GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD
280    */
281   struct GNUNET_MessageHeader header;
282
283   /**
284    * OR'ed GNUNET_PSYC_MasterTransmitFlags
285    */
286   uint32_t flags GNUNET_PACKED;
287
288   /**
289    * Number of message IDs since the last message that contained state
290    * operations. @see enum GNUNET_PSYC_StateDeltaValues
291    */
292   uint64_t state_delta GNUNET_PACKED;
293
294   /* Followed by NUL-terminated method name. */
295 };
296
297
298 /**
299  * A modifier of a message.
300  */
301 struct GNUNET_PSYC_MessageModifier
302 {
303   /**
304    * Type: GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER
305    */
306   struct GNUNET_MessageHeader header;
307
308   /**
309    * Size of value.
310    */
311   uint32_t value_size GNUNET_PACKED;
312
313   /**
314    * Size of name, including NUL terminator.
315    */
316   uint16_t name_size GNUNET_PACKED;
317
318   /**
319    * enum GNUNET_PSYC_Operator
320    */
321   uint8_t oper;
322
323   /* Followed by NUL-terminated name, then the value. */
324 };
325
326
327 struct GNUNET_PSYC_CountersResultMessage
328 {
329   /**
330    * Type: GNUNET_MESSAGE_TYPE_PSYC_RESULT_COUNTERS
331    */
332   struct GNUNET_MessageHeader header;
333
334   /**
335    * Status code for the operation.
336    */
337   uint32_t result_code GNUNET_PACKED;
338
339   /**
340    * Last message ID sent to the channel.
341    */
342   uint64_t max_message_id GNUNET_PACKED;
343 };
344
345
346 /**
347  * Join request sent to a PSYC master.
348  */
349 struct GNUNET_PSYC_JoinRequestMessage
350 {
351   /**
352    * Type: GNUNET_MESSAGE_TYPE_PSYC_MASTER_JOIN_REQUEST
353    */
354   struct GNUNET_MessageHeader header;
355   /**
356    * Public key of the joining slave.
357    */
358   struct GNUNET_CRYPTO_EcdsaPublicKey slave_pub_key;
359
360   /* Followed by struct GNUNET_MessageHeader join_request */
361 };
362
363
364 /**
365  * Join decision sent in reply to a join request.
366  */
367 struct GNUNET_PSYC_JoinDecisionMessage
368 {
369   /**
370    * Type: GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION
371    */
372   struct GNUNET_MessageHeader header;
373
374   /**
375    * #GNUNET_YES if the slave was admitted.
376    */
377   int32_t is_admitted;
378
379   /**
380    * Public key of the joining slave.
381    * Only set when the master is sending the decision,
382    * not set when a slave is receiving it.
383    */
384   struct GNUNET_CRYPTO_EcdsaPublicKey slave_pub_key;
385
386   /* Followed by struct GNUNET_MessageHeader join_response */
387 };
388
389
390 enum GNUNET_PSYC_HistoryReplayFlags
391 {
392   /**
393    * Replay locally available messages.
394    */
395   GNUNET_PSYC_HISTORY_REPLAY_LOCAL  = 0,
396
397   /**
398    * Replay messages from remote peers if not found locally.
399    */
400   GNUNET_PSYC_HISTORY_REPLAY_REMOTE = 1,
401 };
402
403
404 struct GNUNET_PSYC_HistoryRequestMessage
405 {
406   /**
407    * Type: GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_HISTORY_REPLAY
408    */
409   struct GNUNET_MessageHeader header;
410
411   /**
412    * @see enum GNUNET_PSYC_HistoryReplayFlags
413    */
414   uint32_t flags GNUNET_PACKED;
415
416   /**
417    * ID for this operation.
418    */
419   uint64_t op_id GNUNET_PACKED;
420
421   uint64_t start_message_id GNUNET_PACKED;
422
423   uint64_t end_message_id GNUNET_PACKED;
424
425   uint64_t message_limit GNUNET_PACKED;
426
427   /* Followed by NUL-terminated method name prefix. */
428 };
429
430
431 struct GNUNET_PSYC_StateRequestMessage
432 {
433   /**
434    * Types:
435    * - GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_STATE_GET
436    * - GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_STATE_GET_PREFIX
437    */
438   struct GNUNET_MessageHeader header;
439
440   uint32_t reserved GNUNET_PACKED;
441
442   /**
443    * ID for this operation.
444    */
445   uint64_t op_id GNUNET_PACKED;
446
447   /* Followed by NUL-terminated name. */
448 };
449
450
451 /**** service -> library ****/
452
453
454 /**
455  * Answer from service to client about last operation.
456  */
457 struct GNUNET_PSYC_OperationResultMessage
458 {
459   /**
460    * Types:
461    * - GNUNET_MESSAGE_TYPE_PSYC_RESULT_CODE
462    * - GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_STATE_RESULT
463    */
464   struct GNUNET_MessageHeader header;
465
466   uint32_t reserved GNUNET_PACKED;
467
468   /**
469    * Operation ID.
470    */
471   uint64_t op_id GNUNET_PACKED;
472
473   /**
474    * Status code for the operation.
475    */
476   uint64_t result_code GNUNET_PACKED;
477
478   /* Followed by:
479    * - on error: NUL-terminated error message
480    * - on success: one of the following message types
481    *
482    *   For a STATE_RESULT, one of:
483    *   - GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER
484    *   - GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MOD_CONT
485    *   - GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END
486    */
487 };
488
489 GNUNET_NETWORK_STRUCT_END
490
491
492 #define GNUNET_PSYC_MODIFIER_MAX_PAYLOAD        \
493   GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD         \
494   - sizeof (struct GNUNET_PSYC_MessageModifier)
495
496 #define GNUNET_PSYC_MOD_CONT_MAX_PAYLOAD        \
497   GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD         \
498   - sizeof (struct GNUNET_MessageHeader)
499
500 #define GNUNET_PSYC_DATA_MAX_PAYLOAD            \
501   GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD         \
502   - sizeof (struct GNUNET_MessageHeader)
503
504
505 /**
506  * PSYC message part processing states.
507  */
508 enum GNUNET_PSYC_MessageState
509 {
510   GNUNET_PSYC_MESSAGE_STATE_START    = 0,
511   GNUNET_PSYC_MESSAGE_STATE_HEADER   = 1,
512   GNUNET_PSYC_MESSAGE_STATE_METHOD   = 2,
513   GNUNET_PSYC_MESSAGE_STATE_MODIFIER = 3,
514   GNUNET_PSYC_MESSAGE_STATE_MOD_CONT = 4,
515   GNUNET_PSYC_MESSAGE_STATE_DATA     = 5,
516   GNUNET_PSYC_MESSAGE_STATE_END      = 6,
517   GNUNET_PSYC_MESSAGE_STATE_CANCEL   = 7,
518   GNUNET_PSYC_MESSAGE_STATE_ERROR    = 8,
519 };
520
521
522 /**
523  * Handle that identifies a join request.
524  *
525  * Used to match calls to #GNUNET_PSYC_JoinCallback to the
526  * corresponding calls to GNUNET_PSYC_join_decision().
527  */
528 struct GNUNET_PSYC_JoinHandle;
529
530
531 /**
532  * Method called from PSYC upon receiving a message.
533  *
534  * @param cls  Closure.
535  * @param message_id  Sequence number of the message.
536  * @param flags  OR'ed GNUNET_PSYC_MessageFlags
537  * @param msg  Message part, one of the following types:
538  */
539 typedef void
540 (*GNUNET_PSYC_MessageCallback) (void *cls,
541                                 const struct GNUNET_PSYC_MessageHeader *msg);
542
543
544 /**
545  * Method called from PSYC upon receiving part of a message.
546  *
547  * @param cls
548  *        Closure.
549  * @param slave_pub_key
550  *        Public key of the slave sending the message.
551  *        Only set for channel master.
552  * @param message_id
553  *        Sequence number of the message.
554  * @param flags
555  *        OR'ed GNUNET_PSYC_MessageFlags
556  * @param fragment_offset
557  *        Multicast message fragment offset.
558  * @param msg  Message part, one of the following types:
559  * - #GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_HEADER
560  * - #GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD
561  * - #GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER
562  * - #GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MOD_CONT
563  * - #GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_DATA
564  * or NULL if an error occurred while receiving a message.
565  */
566 typedef void
567 (*GNUNET_PSYC_MessagePartCallback) (void *cls,
568                                     const struct GNUNET_PSYC_MessageHeader *msg,
569                                     const struct GNUNET_MessageHeader *pmsg);
570
571
572 /**
573  * Method called from PSYC upon receiving a join request.
574  *
575  * @param cls
576  *        Closure.
577  * @param slave_pub_key
578  *        Public key of the slave requesting join.
579  * @param join_msg
580  *        Join message sent along with the request.
581  * @param jh
582  *        Join handle to use with GNUNET_PSYC_join_decision()
583  */
584 typedef void
585 (*GNUNET_PSYC_JoinRequestCallback) (void *cls,
586                                     const struct GNUNET_PSYC_JoinRequestMessage *req,
587                                     const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_pub_key,
588                                     const struct GNUNET_PSYC_Message *join_msg,
589                                     struct GNUNET_PSYC_JoinHandle *jh);
590
591
592 /**
593  * Function to call with the decision made for a join request.
594  *
595  * Must be called once and only once in response to an invocation of the
596  * #GNUNET_PSYC_JoinCallback.
597  *
598  * @param jh  Join request handle.
599  * @param is_admitted
600  *   #GNUNET_YES    if the join is approved,
601  *   #GNUNET_NO     if it is disapproved,
602  *   #GNUNET_SYSERR if we cannot answer the request.
603  * @param relay_count  Number of relays given.
604  * @param relays  Array of suggested peers that might be useful relays to use
605  *        when joining the multicast group (essentially a list of peers that
606  *        are already part of the multicast group and might thus be willing
607  *        to help with routing).  If empty, only this local peer (which must
608  *        be the multicast origin) is a good candidate for building the
609  *        multicast tree.  Note that it is unnecessary to specify our own
610  *        peer identity in this array.
611  * @param join_resp  Application-dependent join response message to send along
612  *        with the decision.
613  *
614  * @return #GNUNET_OK on success,
615  *         #GNUNET_SYSERR if @a join_resp is too large.
616  */
617 int
618 GNUNET_PSYC_join_decision (struct GNUNET_PSYC_JoinHandle *jh,
619                            int is_admitted,
620                            uint32_t relay_count,
621                            const struct GNUNET_PeerIdentity *relays,
622                            const struct GNUNET_PSYC_Message *join_resp);
623
624
625 /**
626  * Handle for the master of a PSYC channel.
627  */
628 struct GNUNET_PSYC_Master;
629
630
631 /**
632  * Function called once we are connected to the PSYC service
633  * and the channel master is started.
634  *
635  * Also called when we reconnected to the service
636  * after the connection closed unexpectedly.
637  *
638  * @param cls
639  *        Closure.
640  * @param result
641  *        #GNUNET_YES if there were already messages sent to the channel,
642  *        #GNUNET_NO  if the message history is empty,
643  *        #GNUNET_SYSERR on error.
644  * @param max_message_id
645  *        Last message ID sent to the channel.
646  */
647 typedef void
648 (*GNUNET_PSYC_MasterStartCallback) (void *cls, int result,
649                                     uint64_t max_message_id);
650
651
652 /**
653  * Start a PSYC master channel.
654  *
655  * Will start a multicast group identified by the given ECC key.  Messages
656  * received from group members will be given to the respective handler methods.
657  * If a new member wants to join a group, the "join" method handler will be
658  * invoked; the join handler must then generate a "join" message to approve the
659  * joining of the new member.  The channel can also change group membership
660  * without explicit requests.  Note that PSYC doesn't itself "understand" join
661  * or part messages, the respective methods must call other PSYC functions to
662  * inform PSYC about the meaning of the respective events.
663  *
664  * @param cfg  Configuration to use (to connect to PSYC service).
665  * @param channel_key  ECC key that will be used to sign messages for this
666  *        PSYC session. The public key is used to identify the PSYC channel.
667  *        Note that end-users will usually not use the private key directly, but
668  *        rather look it up in GNS for places managed by other users, or select
669  *        a file with the private key(s) when setting up their own channels
670  *        FIXME: we'll likely want to use NOT the p521 curve here, but a cheaper
671  *        one in the future.
672  * @param policy  Channel policy specifying join and history restrictions.
673  *        Used to automate join decisions.
674  * @param master_start_cb  Function to invoke after the channel master started.
675  * @param join_request_cb  Function to invoke when a slave wants to join.
676  * @param message_cb  Function to invoke on message parts sent to the channel
677  *        and received from slaves
678  * @param cls  Closure for @a method and @a join_cb.
679  *
680  * @return Handle for the channel master, NULL on error.
681  */
682 struct GNUNET_PSYC_Master *
683 GNUNET_PSYC_master_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
684                           const struct GNUNET_CRYPTO_EddsaPrivateKey *channel_key,
685                           enum GNUNET_PSYC_Policy policy,
686                           GNUNET_PSYC_MasterStartCallback master_start_cb,
687                           GNUNET_PSYC_JoinRequestCallback join_request_cb,
688                           GNUNET_PSYC_MessageCallback message_cb,
689                           GNUNET_PSYC_MessagePartCallback message_part_cb,
690                           void *cls);
691
692
693 /**
694  * Function called to provide data for a transmission via PSYC.
695  *
696  * Note that returning #GNUNET_YES or #GNUNET_SYSERR (but not #GNUNET_NO)
697  * invalidates the respective transmission handle.
698  *
699  * @param cls Closure.
700  * @param[in,out] data_size Initially set to the number of bytes available in
701  *        @a data, should be set to the number of bytes written to data.
702  * @param[out] data Where to write the body of the message to give to the
703  *         method. The function must copy at most @a data_size bytes to @a data.
704  * @return #GNUNET_SYSERR on error (fatal, aborts transmission)
705  *         #GNUNET_NO on success, if more data is to be transmitted later.
706  *         Should be used if @a data_size was not big enough to take all the
707  *         data.  If 0 is returned in @a data_size the transmission is paused,
708  *         and can be resumed with GNUNET_PSYC_master_transmit_resume().
709  *         #GNUNET_YES if this completes the transmission (all data supplied)
710  */
711 typedef int
712 (*GNUNET_PSYC_TransmitNotifyData) (void *cls,
713                                    uint16_t *data_size,
714                                    void *data);
715
716 /**
717  * Function called to provide a modifier for a transmission via PSYC.
718  *
719  * Note that returning #GNUNET_YES or #GNUNET_SYSERR (but not #GNUNET_NO)
720  * invalidates the respective transmission handle.
721  *
722  * @param cls Closure.
723  * @param[in,out] data_size  Initially set to the number of bytes available in
724  *         @a data, should be set to the number of bytes written to data.
725  * @param[out] data  Where to write the modifier's name and value.
726  *         The function must copy at most @a data_size bytes to @a data.
727  *         When this callback is first called for a modifier, @a data should
728  *         contain: "name\0value".  If the whole value does not fit, subsequent
729  *         calls to this function should write continuations of the value to
730  *         @a data.
731  * @param[out] oper  Where to write the operator of the modifier.
732  *         Only needed during the first call to this callback at the beginning
733  *         of the modifier.  In case of subsequent calls asking for value
734  *         continuations @a oper is set to #NULL.
735  * @param[out] full_value_size  Where to write the full size of the value.
736  *         Only needed during the first call to this callback at the beginning
737  *         of the modifier.  In case of subsequent calls asking for value
738  *         continuations @a value_size is set to #NULL.
739  * @return #GNUNET_SYSERR on error (fatal, aborts transmission)
740  *         #GNUNET_NO on success, if more data is to be transmitted later.
741  *         Should be used if @a data_size was not big enough to take all the
742  *         data for the modifier's value (the name must be always returned
743  *         during the first call to this callback).
744  *         If 0 is returned in @a data_size the transmission is paused,
745  *         and can be resumed with GNUNET_PSYC_master_transmit_resume().
746  *         #GNUNET_YES if this completes the modifier (the whole value is supplied).
747  */
748 typedef int
749 (*GNUNET_PSYC_TransmitNotifyModifier) (void *cls,
750                                        uint16_t *data_size,
751                                        void *data,
752                                        uint8_t *oper,
753                                        uint32_t *full_value_size);
754
755 /**
756  * Flags for transmitting messages to a channel by the master.
757  */
758 enum GNUNET_PSYC_MasterTransmitFlags
759 {
760   GNUNET_PSYC_MASTER_TRANSMIT_NONE = 0,
761
762   /**
763    * Whether this message should reset the channel state,
764    * i.e. remove all previously stored state variables.
765    */
766
767   GNUNET_PSYC_MASTER_TRANSMIT_STATE_RESET = 1 << 0,
768
769   /**
770    * Whether this message contains any state modifiers.
771    */
772   GNUNET_PSYC_MASTER_TRANSMIT_STATE_MODIFY = 1 << 1,
773
774   /**
775    * Add PSYC header variable with the hash of the current channel state.
776    */
777   GNUNET_PSYC_MASTER_TRANSMIT_STATE_HASH = 1 << 2,
778
779   /**
780    * Whether we need to increment the group generation counter after
781    * transmitting this message.
782    */
783   GNUNET_PSYC_MASTER_TRANSMIT_INC_GROUP_GEN = 1 << 3
784 };
785
786
787 /**
788  * Handle for a pending PSYC transmission operation.
789  */
790 struct GNUNET_PSYC_MasterTransmitHandle;
791
792
793 /**
794  * Send a message to call a method to all members in the PSYC channel.
795  *
796  * @param master Handle to the PSYC channel.
797  * @param method_name Which method should be invoked.
798  * @param notify_mod Function to call to obtain modifiers.
799  * @param notify_data Function to call to obtain fragments of the data.
800  * @param notify_cls Closure for @a notify_mod and @a notify_data.
801  * @param flags Flags for the message being transmitted.
802  * @return Transmission handle, NULL on error (i.e. more than one request queued).
803  */
804 struct GNUNET_PSYC_MasterTransmitHandle *
805 GNUNET_PSYC_master_transmit (struct GNUNET_PSYC_Master *master,
806                              const char *method_name,
807                              GNUNET_PSYC_TransmitNotifyModifier notify_mod,
808                              GNUNET_PSYC_TransmitNotifyData notify_data,
809                              void *notify_cls,
810                              enum GNUNET_PSYC_MasterTransmitFlags flags);
811
812
813 /**
814  * Resume transmission to the channel.
815  *
816  * @param th Handle of the request that is being resumed.
817  */
818 void
819 GNUNET_PSYC_master_transmit_resume (struct GNUNET_PSYC_MasterTransmitHandle *th);
820
821
822 /**
823  * Abort transmission request to channel.
824  *
825  * @param th Handle of the request that is being aborted.
826  */
827 void
828 GNUNET_PSYC_master_transmit_cancel (struct GNUNET_PSYC_MasterTransmitHandle *th);
829
830
831 /**
832  * Relay a message
833  *
834  * @param master Handle to the PSYC channel.
835  * @param method_name Which method should be invoked.
836  * @param notify_mod Function to call to obtain modifiers.
837  * @param notify_data Function to call to obtain fragments of the data.
838  * @param notify_cls Closure for @a notify_mod and @a notify_data.
839  * @param flags Flags for the message being transmitted.
840  * @return Transmission handle, NULL on error (i.e. more than one request queued).
841  */
842 struct GNUNET_PSYC_MasterTransmitHandle *
843 GNUNET_PSYC_master_relay (struct GNUNET_PSYC_Master *master,
844                           uint64_t message_id);
845
846
847 /**
848  * Stop a PSYC master channel.
849  *
850  * @param master
851  *        PSYC channel master to stop.
852  * @param keep_active
853  *        Keep place active after last application disconnected.
854  * @param stop_cb
855  *        Function called after the master stopped
856  *        and disconnected from the psyc service.
857  * @param stop_cls
858  *        Closure for @a part_cb.
859  */
860 void
861 GNUNET_PSYC_master_stop (struct GNUNET_PSYC_Master *master,
862                          int keep_active,
863                          GNUNET_ContinuationCallback stop_cb,
864                          void *stop_cls);
865
866
867 /**
868  * Handle for a PSYC channel slave.
869  */
870 struct GNUNET_PSYC_Slave;
871
872
873 /**
874  * Function called after the slave connected to the PSYC service.
875  *
876  * Also called when reconnected to the service
877  * after the connection closed unexpectedly.
878  *
879  * @param cls
880  *        Closure.
881  * @param result
882  *        #GNUNET_YES if there were already messages sent to the channel,
883  *        #GNUNET_NO  if the message history is empty,
884  *        #GNUNET_SYSERR on error.
885  * @param max_message_id
886  *        Last message ID sent to the channel.
887  */
888 typedef void
889 (*GNUNET_PSYC_SlaveConnectCallback) (void *cls, int result,
890                                      uint64_t max_message_id);
891
892
893 /**
894  * Method called to inform about the decision in response to a join request.
895  *
896  * If @a is_admitted is not #GNUNET_YES, then sending messages to the channel is
897  * not possible, but earlier history can be still queried.
898  *
899  * @param cls  Closure.
900  * @param is_admitted  #GNUNET_YES or #GNUNET_NO or #GNUNET_SYSERR
901  * @param join_msg  Application-dependent join message from the origin.
902  */
903 typedef void
904 (*GNUNET_PSYC_JoinDecisionCallback) (void *cls,
905                                      const struct GNUNET_PSYC_JoinDecisionMessage *dcsn,
906                                      int is_admitted,
907                                      const struct GNUNET_PSYC_Message *join_msg);
908
909 /**
910  * Flags for GNUNET_PSYC_slave_join()
911  */
912 enum GNUNET_PSYC_SlaveJoinFlags
913 {
914   GNUNET_PSYC_SLAVE_JOIN_NONE   = 0,
915
916   /**
917    * Local join for history access, no network connection is established.
918    */
919   GNUNET_PSYC_SLAVE_JOIN_LOCAL  = 1,
920 };
921
922
923 /**
924  * Join a PSYC channel.
925  *
926  * The entity joining is always the local peer.  The user must immediately use
927  * the GNUNET_PSYC_slave_transmit() functions to transmit a @e join_msg to the
928  * channel; if the join request succeeds, the channel state (and @e recent
929  * method calls) will be replayed to the joining member.  There is no explicit
930  * notification on failure (as the channel may simply take days to approve,
931  * and disapproval is simply being ignored).
932  *
933  * @param cfg
934  *        Configuration to use.
935  * @param channel_pub_key
936  *        ECC public key that identifies the channel we wish to join.
937  * @param slave_pub_key
938  *        ECC private-public key pair that identifies the slave, and
939  *        used by multicast to sign the join request and subsequent unicast
940  *        requests sent to the master.
941  * @param flags
942  *        Join flags.
943  * @param origin
944  *        Peer identity of the origin.
945  * @param relay_count
946  *        Number of peers in the @a relays array.
947  * @param relays
948  *        Peer identities of members of the multicast group, which serve
949  *        as relays and used to join the group at.
950  * @param message_cb
951  *        Function to invoke on message fragments received from the channel.
952  * @param message_part_cb
953  *        Function to invoke on message parts received from the channel.
954  * @param slave_connect_cb
955  *        Function invoked once we have connected to the PSYC service.
956  * @param join_decision_cb
957  *        Function invoked once we have received a join decision.
958  * @param cls
959  *        Closure for @a message_cb and @a slave_joined_cb.
960  * @param join_msg
961  *        Join message.
962  *
963  * @return Handle for the slave, NULL on error.
964  */
965 struct GNUNET_PSYC_Slave *
966 GNUNET_PSYC_slave_join (const struct GNUNET_CONFIGURATION_Handle *cfg,
967                         const struct GNUNET_CRYPTO_EddsaPublicKey *channel_pub_key,
968                         const struct GNUNET_CRYPTO_EcdsaPrivateKey *slave_pub_key,
969                         enum GNUNET_PSYC_SlaveJoinFlags flags,
970                         const struct GNUNET_PeerIdentity *origin,
971                         uint32_t relay_count,
972                         const struct GNUNET_PeerIdentity *relays,
973                         GNUNET_PSYC_MessageCallback message_cb,
974                         GNUNET_PSYC_MessagePartCallback message_part_cb,
975                         GNUNET_PSYC_SlaveConnectCallback slave_connect_cb,
976                         GNUNET_PSYC_JoinDecisionCallback join_decision_cb,
977                         void *cls,
978                         const struct GNUNET_PSYC_Message *join_msg);
979
980
981 /**
982  * Part a PSYC channel.
983  *
984  * Will terminate the connection to the PSYC service.  Polite clients should
985  * first explicitly send a part request (via GNUNET_PSYC_slave_transmit()).
986  *
987  * @param slave
988  *        Slave handle.
989  * @param keep_active
990  *        Keep place active after last application disconnected.
991  * @param part_cb
992  *        Function called after the slave parted the channel
993  *        and disconnected from the psyc service.
994  * @param part_cls
995  *        Closure for @a part_cb.
996  */
997 void
998 GNUNET_PSYC_slave_part (struct GNUNET_PSYC_Slave *slave,
999                         int keep_active,
1000                         GNUNET_ContinuationCallback part_cb,
1001                         void *part_cls);
1002
1003
1004 /**
1005  * Flags for transmitting messages to the channel master by a slave.
1006  */
1007 enum GNUNET_PSYC_SlaveTransmitFlags
1008 {
1009   GNUNET_PSYC_SLAVE_TRANSMIT_NONE = 0
1010 };
1011
1012
1013 /**
1014  * Handle for a pending PSYC transmission operation.
1015  */
1016 struct GNUNET_PSYC_SlaveTransmitHandle;
1017
1018
1019 /**
1020  * Request a message to be sent to the channel master.
1021  *
1022  * @param slave Slave handle.
1023  * @param method_name Which (PSYC) method should be invoked (on host).
1024  * @param notify_mod Function to call to obtain modifiers.
1025  * @param notify_data Function to call to obtain fragments of the data.
1026  * @param notify_cls Closure for @a notify.
1027  * @param flags Flags for the message being transmitted.
1028  * @return Transmission handle, NULL on error (i.e. more than one request queued).
1029  */
1030 struct GNUNET_PSYC_SlaveTransmitHandle *
1031 GNUNET_PSYC_slave_transmit (struct GNUNET_PSYC_Slave *slave,
1032                             const char *method_name,
1033                             GNUNET_PSYC_TransmitNotifyModifier notify_mod,
1034                             GNUNET_PSYC_TransmitNotifyData notify_data,
1035                             void *notify_cls,
1036                             enum GNUNET_PSYC_SlaveTransmitFlags flags);
1037
1038
1039 /**
1040  * Resume transmission to the master.
1041  *
1042  * @param th Handle of the request that is being resumed.
1043  */
1044 void
1045 GNUNET_PSYC_slave_transmit_resume (struct GNUNET_PSYC_SlaveTransmitHandle *th);
1046
1047
1048 /**
1049  * Abort transmission request to master.
1050  *
1051  * @param th Handle of the request that is being aborted.
1052  */
1053 void
1054 GNUNET_PSYC_slave_transmit_cancel (struct GNUNET_PSYC_SlaveTransmitHandle *th);
1055
1056
1057 /**
1058  * Handle to access PSYC channel operations for both the master and slaves.
1059  */
1060 struct GNUNET_PSYC_Channel;
1061
1062
1063 /**
1064  * Convert a channel @a master to a @e channel handle to access the @e channel
1065  * APIs.
1066  *
1067  * @param master Channel master handle.
1068  * @return Channel handle, valid for as long as @a master is valid.
1069  */
1070 struct GNUNET_PSYC_Channel *
1071 GNUNET_PSYC_master_get_channel (struct GNUNET_PSYC_Master *master);
1072
1073
1074 /**
1075  * Convert @a slave to a @e channel handle to access the @e channel APIs.
1076  *
1077  * @param slave Slave handle.
1078  * @return Channel handle, valid for as long as @a slave is valid.
1079  */
1080 struct GNUNET_PSYC_Channel *
1081 GNUNET_PSYC_slave_get_channel (struct GNUNET_PSYC_Slave *slave);
1082
1083
1084 /**
1085  * Add a slave to the channel's membership list.
1086  *
1087  * Note that this will NOT generate any PSYC traffic, it will merely update the
1088  * local database to modify how we react to <em>membership test</em> queries.
1089  * The channel master still needs to explicitly transmit a @e join message to
1090  * notify other channel members and they then also must still call this function
1091  * in their respective methods handling the @e join message.  This way, how @e
1092  * join and @e part operations are exactly implemented is still up to the
1093  * application; for example, there might be a @e part_all method to kick out
1094  * everyone.
1095  *
1096  * Note that channel slaves are explicitly trusted to execute such methods
1097  * correctly; not doing so correctly will result in either denying other slaves
1098  * access or offering access to channel data to non-members.
1099  *
1100  * @param channel
1101  *        Channel handle.
1102  * @param slave_pub_key
1103  *        Identity of channel slave to add.
1104  * @param announced_at
1105  *        ID of the message that announced the membership change.
1106  * @param effective_since
1107  *        Addition of slave is in effect since this message ID.
1108  * @param result_cb
1109  *        Function to call with the result of the operation.
1110  *        The @e result_code argument is #GNUNET_OK on success, or
1111  *        #GNUNET_SYSERR on error.  In case of an error, the @e data argument
1112  *        can contain an optional error message.
1113  * @param cls
1114  *        Closure for @a result_cb.
1115  */
1116 void
1117 GNUNET_PSYC_channel_slave_add (struct GNUNET_PSYC_Channel *channel,
1118                                const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_pub_key,
1119                                uint64_t announced_at,
1120                                uint64_t effective_since,
1121                                GNUNET_ResultCallback result_cb,
1122                                void *cls);
1123
1124
1125 /**
1126  * Remove a slave from the channel's membership list.
1127  *
1128  * Note that this will NOT generate any PSYC traffic, it will merely update the
1129  * local database to modify how we react to <em>membership test</em> queries.
1130  * The channel master still needs to explicitly transmit a @e part message to
1131  * notify other channel members and they then also must still call this function
1132  * in their respective methods handling the @e part message.  This way, how
1133  * @e join and @e part operations are exactly implemented is still up to the
1134  * application; for example, there might be a @e part_all message to kick out
1135  * everyone.
1136  *
1137  * Note that channel members are explicitly trusted to perform these
1138  * operations correctly; not doing so correctly will result in either
1139  * denying members access or offering access to channel data to
1140  * non-members.
1141  *
1142  * @param channel
1143  *        Channel handle.
1144  * @param slave_pub_key
1145  *        Identity of channel slave to remove.
1146  * @param announced_at
1147  *        ID of the message that announced the membership change.
1148  * @param result_cb
1149  *        Function to call with the result of the operation.
1150  *        The @e result_code argument is #GNUNET_OK on success, or
1151  *        #GNUNET_SYSERR on error.  In case of an error, the @e data argument
1152  *        can contain an optional error message.
1153  * @param cls
1154  *        Closure for @a result_cb.
1155  */
1156 void
1157 GNUNET_PSYC_channel_slave_remove (struct GNUNET_PSYC_Channel *channel,
1158                                   const struct GNUNET_CRYPTO_EcdsaPublicKey
1159                                   *slave_pub_key,
1160                                   uint64_t announced_at,
1161                                   GNUNET_ResultCallback result_cb,
1162                                   void *cls);
1163
1164
1165 /**
1166  * History request handle.
1167  */
1168 struct GNUNET_PSYC_HistoryRequest;
1169
1170
1171 /**
1172  * Request to replay a part of the message history of the channel.
1173  *
1174  * Historic messages (but NOT the state at the time) will be replayed (given to
1175  * the normal method handlers) if available and if access is permitted.
1176  *
1177  * @param channel
1178  *        Which channel should be replayed?
1179  * @param start_message_id
1180  *        Earliest interesting point in history.
1181  * @param end_message_id
1182  *        Last (inclusive) interesting point in history.
1183  * @param method_prefix
1184  *        Retrieve only messages with a matching method prefix.
1185  * @param flags
1186  *        OR'ed enum GNUNET_PSYC_HistoryReplayFlags
1187  * @param result_cb
1188  *        Function to call when the requested history has been fully replayed.
1189  *        Once this function has been called, the client must not call
1190  *        GNUNET_PSYC_channel_history_replay_cancel() anymore.
1191  * @param cls
1192  *        Closure for the callbacks.
1193  *
1194  * @return Handle to cancel history replay operation.
1195  */
1196 struct GNUNET_PSYC_HistoryRequest *
1197 GNUNET_PSYC_channel_history_replay (struct GNUNET_PSYC_Channel *channel,
1198                                     uint64_t start_message_id,
1199                                     uint64_t end_message_id,
1200                                     const char *method_prefix,
1201                                     uint32_t flags,
1202                                     GNUNET_PSYC_MessageCallback message_cb,
1203                                     GNUNET_PSYC_MessagePartCallback message_part_cb,
1204                                     GNUNET_ResultCallback result_cb,
1205                                     void *cls);
1206
1207
1208 /**
1209  * Request to replay the latest messages from the message history of the channel.
1210  *
1211  * Historic messages (but NOT the state at the time) will be replayed (given to
1212  * the normal method handlers) if available and if access is permitted.
1213  *
1214  * @param channel
1215  *        Which channel should be replayed?
1216  * @param message_limit
1217  *        Maximum number of messages to replay.
1218  * @param flags
1219  *        OR'ed enum GNUNET_PSYC_HistoryReplayFlags
1220  * @param finish_cb
1221  *        Function to call when the requested history has been fully replayed
1222  *        (counting message IDs might not suffice, as some messages might be
1223  *        secret and thus the listener would not know the story is finished
1224  *        without being told explicitly)o once this function has been called, the
1225  *        client must not call GNUNET_PSYC_channel_history_replay_cancel() anymore.
1226  * @param cls
1227  *        Closure for the callbacks.
1228  *
1229  * @return Handle to cancel history replay operation.
1230  */
1231 struct GNUNET_PSYC_HistoryRequest *
1232 GNUNET_PSYC_channel_history_replay_latest (struct GNUNET_PSYC_Channel *channel,
1233                                            uint64_t message_limit,
1234                                            const char *method_prefix,
1235                                            uint32_t flags,
1236                                            GNUNET_PSYC_MessageCallback message_cb,
1237                                            GNUNET_PSYC_MessagePartCallback message_part_cb,
1238                                            GNUNET_ResultCallback result_cb,
1239                                            void *cls);
1240
1241
1242 void
1243 GNUNET_PSYC_channel_history_replay_cancel (struct GNUNET_PSYC_Channel *channel,
1244                                            struct GNUNET_PSYC_HistoryRequest *hr);
1245
1246
1247 /**
1248  * Function called to inform a member about stored state values for a channel.
1249  *
1250  * If @a full_value_size > value_size then this function is called multiple
1251  * times until the whole value arrived.
1252  *
1253  * @param cls
1254  *        Closure.
1255  * @param name
1256  *        Name of the state variable.
1257  *        NULL if there are no more state variables to be returned.
1258  * @param value
1259  *        Value of the state variable.
1260  * @param value_size
1261  *        Number of bytes in @a value.
1262  * @param full_value_size
1263  *        Number of bytes in the full value, including continuations.
1264  *        Only set for the first part of a variable,
1265  *        in case of a continuation it is 0.
1266  */
1267 typedef void
1268 (*GNUNET_PSYC_StateVarCallback) (void *cls,
1269                                  const struct GNUNET_MessageHeader *mod,
1270                                  const char *name,
1271                                  const void *value,
1272                                  uint32_t value_size,
1273                                  uint32_t full_value_size);
1274
1275
1276 /**
1277  * State request handle.
1278  */
1279 struct GNUNET_PSYC_StateRequest;
1280
1281
1282 /**
1283  * Retrieve the best matching channel state variable.
1284  *
1285  * If the requested variable name is not present in the state, the nearest
1286  * less-specific name is matched; for example, requesting "_a_b" will match "_a"
1287  * if "_a_b" does not exist.
1288  *
1289  * @param channel
1290  *        Channel handle.
1291  * @param full_name
1292  *        Full name of the requested variable.
1293  *        The actual variable returned might have a shorter name.
1294  * @param var_cb
1295  *        Function called once when a matching state variable is found.
1296  *        Not called if there's no matching state variable.
1297  * @param result_cb
1298  *        Function called after the operation finished.
1299  *        (i.e. all state variables have been returned via @a state_cb)
1300  * @param cls
1301  *        Closure for the callbacks.
1302  */
1303 struct GNUNET_PSYC_StateRequest *
1304 GNUNET_PSYC_channel_state_get (struct GNUNET_PSYC_Channel *channel,
1305                                const char *full_name,
1306                                GNUNET_PSYC_StateVarCallback var_cb,
1307                                GNUNET_ResultCallback result_cb,
1308                                void *cls);
1309
1310
1311 /**
1312  * Return all channel state variables whose name matches a given prefix.
1313  *
1314  * A name matches if it starts with the given @a name_prefix, thus requesting
1315  * the empty prefix ("") will match all values; requesting "_a_b" will also
1316  * return values stored under "_a_b_c".
1317  *
1318  * The @a state_cb is invoked on all matching state variables asynchronously, as
1319  * the state is stored in and retrieved from the PSYCstore,
1320  *
1321  * @param channel
1322  *        Channel handle.
1323  * @param name_prefix
1324  *        Prefix of the state variable name to match.
1325  * @param var_cb
1326  *        Function called once when a matching state variable is found.
1327  *        Not called if there's no matching state variable.
1328  * @param result_cb
1329  *        Function called after the operation finished.
1330  *        (i.e. all state variables have been returned via @a state_cb)
1331  * @param cls
1332  *        Closure for the callbacks.
1333  */
1334 struct GNUNET_PSYC_StateRequest *
1335 GNUNET_PSYC_channel_state_get_prefix (struct GNUNET_PSYC_Channel *channel,
1336                                       const char *name_prefix,
1337                                       GNUNET_PSYC_StateVarCallback var_cb,
1338                                       GNUNET_ResultCallback result_cb,
1339                                       void *cls);
1340
1341 /**
1342  * Cancel a state request operation.
1343  *
1344  * @param sr
1345  *        Handle for the operation to cancel.
1346  */
1347 void
1348 GNUNET_PSYC_channel_state_get_cancel (struct GNUNET_PSYC_StateRequest *sr);
1349
1350
1351
1352 #if 0                           /* keep Emacsens' auto-indent happy */
1353 {
1354 #endif
1355 #ifdef __cplusplus
1356 }
1357 #endif
1358
1359 /* ifndef GNUNET_PSYC_SERVICE_H */
1360 #endif
1361
1362 /** @} */  /* end of group */