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