towards factoring out HELLO handling from transport_api.c
[oweals/gnunet.git] / src / transport / transport_api_get_hello.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2009-2013, 2016 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  * @file transport/transport_api.c
23  * @brief library to obtain our HELLO from our transport service
24  * @author Christian Grothoff
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_constants.h"
29 #include "gnunet_arm_service.h"
30 #include "gnunet_hello_lib.h"
31 #include "gnunet_protocols.h"
32 #include "gnunet_transport_service.h"
33 #include "transport.h"
34
35
36 /**
37  * Linked list of functions to call whenever our HELLO is updated.
38  */
39 struct GNUNET_TRANSPORT_GetHelloHandle
40 {
41
42   /**
43    * This is a doubly linked list.
44    */
45   struct GNUNET_TRANSPORT_GetHelloHandle *next;
46
47   /**
48    * This is a doubly linked list.
49    */
50   struct GNUNET_TRANSPORT_GetHelloHandle *prev;
51
52   /**
53    * Transport handle.
54    */
55   struct GNUNET_TRANSPORT_Handle *handle;
56
57   /**
58    * Callback to call once we got our HELLO.
59    */
60   GNUNET_TRANSPORT_HelloUpdateCallback rec;
61
62   /**
63    * Task for calling the HelloUpdateCallback when we already have a HELLO
64    */
65   struct GNUNET_SCHEDULER_Task *notify_task;
66
67   /**
68    * Closure for @e rec.
69    */
70   void *rec_cls;
71
72 };
73
74
75
76 /**
77  * Task to call the HelloUpdateCallback of the GetHelloHandle
78  *
79  * @param cls the `struct GNUNET_TRANSPORT_GetHelloHandle`
80  */
81 static void
82 call_hello_update_cb_async (void *cls)
83 {
84   struct GNUNET_TRANSPORT_GetHelloHandle *ghh = cls;
85
86   GNUNET_assert (NULL != ghh->handle->my_hello);
87   GNUNET_assert (NULL != ghh->notify_task);
88   ghh->notify_task = NULL;
89   ghh->rec (ghh->rec_cls,
90             ghh->handle->my_hello);
91 }
92
93
94 /**
95  * Obtain the HELLO message for this peer.  The callback given in this function
96  * is never called synchronously.
97  *
98  * @param handle connection to transport service
99  * @param rec function to call with the HELLO, sender will be our peer
100  *            identity; message and sender will be NULL on timeout
101  *            (handshake with transport service pending/failed).
102  *             cost estimate will be 0.
103  * @param rec_cls closure for @a rec
104  * @return handle to cancel the operation
105  */
106 struct GNUNET_TRANSPORT_GetHelloHandle *
107 GNUNET_TRANSPORT_get_hello (struct GNUNET_TRANSPORT_Handle *handle,
108                             GNUNET_TRANSPORT_HelloUpdateCallback rec,
109                             void *rec_cls)
110 {
111   struct GNUNET_TRANSPORT_GetHelloHandle *hwl;
112
113   hwl = GNUNET_new (struct GNUNET_TRANSPORT_GetHelloHandle);
114   hwl->rec = rec;
115   hwl->rec_cls = rec_cls;
116   hwl->handle = handle;
117   GNUNET_CONTAINER_DLL_insert (handle->hwl_head,
118                                handle->hwl_tail,
119                                hwl);
120   if (NULL != handle->my_hello)
121     hwl->notify_task = GNUNET_SCHEDULER_add_now (&call_hello_update_cb_async,
122                                                  hwl);
123   return hwl;
124 }
125
126
127 /**
128  * Stop receiving updates about changes to our HELLO message.
129  *
130  * @param ghh handle to cancel
131  */
132 void
133 GNUNET_TRANSPORT_get_hello_cancel (struct GNUNET_TRANSPORT_GetHelloHandle *ghh)
134 {
135   struct GNUNET_TRANSPORT_Handle *handle = ghh->handle;
136
137   if (NULL != ghh->notify_task)
138     GNUNET_SCHEDULER_cancel (ghh->notify_task);
139   GNUNET_CONTAINER_DLL_remove (handle->hwl_head,
140                                handle->hwl_tail,
141                                ghh);
142   GNUNET_free (ghh);
143 }
144
145
146 /* end of transport_api_hello.c */