peerstore helper file
[oweals/gnunet.git] / src / peerstore / peerstore_api.c
1 /*
2      This file is part of GNUnet.
3      (C) 
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., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file peerstore/peerstore_api.c
23  * @brief API for peerstore
24  * @author Omar Tarabai
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "peerstore.h"
29 #include "peerstore_common.h"
30
31 #define LOG(kind,...) GNUNET_log_from (kind, "peerstore-api",__VA_ARGS__)
32
33 /******************************************************************************/
34 /************************      DATA STRUCTURES     ****************************/
35 /******************************************************************************/
36
37 /**
38  * Handle to the PEERSTORE service.
39  */
40 struct GNUNET_PEERSTORE_Handle
41 {
42
43   /**
44    * Our configuration.
45    */
46   const struct GNUNET_CONFIGURATION_Handle *cfg;
47
48   /**
49    * Connection to the service.
50    */
51   struct GNUNET_CLIENT_Connection *client;
52
53 };
54
55 /**
56  * Context for a store request
57  */
58 struct GNUNET_PEERSTORE_StoreContext
59 {
60
61   /**
62    * Handle to the PEERSTORE service.
63    */
64   struct GNUNET_PEERSTORE_Handle *h;
65
66   /**
67    * Continuation called with service response
68    */
69   GNUNET_PEERSTORE_Continuation cont;
70
71   /**
72    * Closure for 'cont'
73    */
74   void *cont_cls;
75
76 };
77
78 /******************************************************************************/
79 /*******************         CONNECTION FUNCTIONS         *********************/
80 /******************************************************************************/
81
82 /**
83  * Close the existing connection to PEERSTORE and reconnect.
84  *
85  * @param h handle to the service
86  */
87 static void
88 reconnect (struct GNUNET_PEERSTORE_Handle *h)
89 {
90
91   LOG(GNUNET_ERROR_TYPE_DEBUG, "Reconnecting...\n");
92   if (NULL != h->client)
93   {
94     GNUNET_CLIENT_disconnect (h->client);
95     h->client = NULL;
96   }
97   h->client = GNUNET_CLIENT_connect ("peerstore", h->cfg);
98
99 }
100
101 /**
102  * Connect to the PEERSTORE service.
103  *
104  * @return NULL on error
105  */
106 struct GNUNET_PEERSTORE_Handle *
107 GNUNET_PEERSTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
108 {
109   struct GNUNET_CLIENT_Connection *client;
110   struct GNUNET_PEERSTORE_Handle *h;
111
112   client = GNUNET_CLIENT_connect ("peerstore", cfg);
113   if(NULL == client)
114     return NULL;
115   h = GNUNET_new (struct GNUNET_PEERSTORE_Handle);
116   h->client = client;
117   h->cfg = cfg;
118   LOG(GNUNET_ERROR_TYPE_DEBUG, "New connection created\n");
119   return h;
120 }
121
122 /**
123  * Disconnect from the PEERSTORE service
124  * Do not call in case of pending requests
125  *
126  * @param h handle to disconnect
127  */
128 void
129 GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h)
130 {
131   if (NULL != h->client)
132   {
133     GNUNET_CLIENT_disconnect (h->client);
134     h->client = NULL;
135   }
136   GNUNET_free(h);
137   LOG(GNUNET_ERROR_TYPE_DEBUG, "Disconnected, BYE!\n");
138 }
139
140
141 /******************************************************************************/
142 /*******************             ADD FUNCTIONS            *********************/
143 /******************************************************************************/
144
145 /**
146  * When a response for store request is received
147  *
148  * @param cls a 'struct GNUNET_PEERSTORE_StoreContext *'
149  * @param msg message received, NULL on timeout or fatal error
150  */
151 void store_response_receiver (void *cls, const struct GNUNET_MessageHeader *msg)
152 {
153   struct GNUNET_PEERSTORE_StoreContext *sc = cls;
154   uint16_t msg_type;
155
156   if(NULL == sc->cont)
157     return;
158   if(NULL == msg)
159   {
160     sc->cont(sc->cont_cls, GNUNET_SYSERR);
161     reconnect(sc->h);
162     return;
163   }
164   msg_type = ntohs(msg->type);
165   if(GNUNET_MESSAGE_TYPE_PEERSTORE_STORE_RESULT_OK == msg_type)
166     sc->cont(sc->cont_cls, GNUNET_OK);
167   else if(GNUNET_MESSAGE_TYPE_PEERSTORE_STORE_RESULT_FAIL == msg_type)
168     sc->cont(sc->cont_cls, GNUNET_SYSERR);
169   else
170   {
171     LOG(GNUNET_ERROR_TYPE_ERROR, "Invalid response from `PEERSTORE' service.\n");
172     sc->cont(sc->cont_cls, GNUNET_SYSERR);
173   }
174
175 }
176
177 /**
178  * Cancel a store request
179  *
180  * @param sc Store request context
181  */
182 void
183 GNUNET_PEERSTORE_store_cancel (struct GNUNET_PEERSTORE_StoreContext *sc)
184 {
185   sc->cont = NULL;
186 }
187
188 /**
189  * Store a new entry in the PEERSTORE
190  *
191  * @param h Handle to the PEERSTORE service
192  * @param sub_system name of the sub system
193  * @param peer Peer Identity
194  * @param key entry key
195  * @param value entry value BLOB
196  * @param size size of 'value'
197  * @param lifetime relative time after which the entry is (possibly) deleted
198  * @param cont Continuation function after the store request is processed
199  * @param cont_cls Closure for 'cont'
200  */
201 struct GNUNET_PEERSTORE_StoreContext *
202 GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h,
203     const char *sub_system,
204     const struct GNUNET_PeerIdentity *peer,
205     const char *key,
206     const void *value,
207     size_t size,
208     struct GNUNET_TIME_Relative lifetime,
209     GNUNET_PEERSTORE_Continuation cont,
210     void *cont_cls)
211 {
212   struct GNUNET_PEERSTORE_StoreContext *sc;
213   struct StoreRecordMessage *srm;
214
215   LOG (GNUNET_ERROR_TYPE_DEBUG,
216       "Storing value (size: %lu) for subsytem `%s', peer `%s', key `%s'\n",
217       size, sub_system, GNUNET_i2s (peer), key);
218   sc = GNUNET_new(struct GNUNET_PEERSTORE_StoreContext);
219   sc->cont = cont;
220   sc->cont_cls = cont_cls;
221   sc->h = h;
222   srm = PEERSTORE_create_record_message(sub_system,
223       peer,
224       key,
225       value,
226       size,
227       lifetime);
228   GNUNET_CLIENT_transmit_and_get_response(h->client,
229       (const struct GNUNET_MessageHeader *)srm,
230       GNUNET_TIME_UNIT_FOREVER_REL,
231       GNUNET_YES,
232       &store_response_receiver,
233       sc);
234   return sc;
235
236 }
237
238
239 /* end of peerstore_api.c */