2 This file is part of GNUnet
3 Copyright (C) 2008--2013, 2016 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU 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.
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.
17 * @file testbed-logger/testbed_logger_api.c
18 * @brief Client-side routines for communicating with the tesbted logger service
19 * @author Sree Harsha Totakura <sreeharsha@totakura.in>
20 * @author Christian Grothoff
24 #include "gnunet_util_lib.h"
25 #include "gnunet_testbed_logger_service.h"
28 * Generic logging shorthand
30 #define LOG(kind, ...) \
31 GNUNET_log_from (kind, "testbed-logger-api", __VA_ARGS__)
35 * The size of the buffer we fill before sending out the message
37 #define BUFFER_SIZE (GNUNET_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_MessageHeader))
40 * Connection handle for the logger service
42 struct GNUNET_TESTBED_LOGGER_Handle
47 struct GNUNET_MQ_Handle *mq;
50 * Flush completion callback
52 GNUNET_TESTBED_LOGGER_FlushCompletion cb;
60 * Local buffer for data to be transmitted
62 char buf[BUFFER_SIZE];
65 * How many bytes in @a buf are in use?
70 * Number of bytes wrote since last flush
75 * How long after should we retry sending a message to the service?
77 struct GNUNET_TIME_Relative retry_backoff;
80 * Task to call the flush completion callback
82 struct GNUNET_SCHEDULER_Task *flush_completion_task;
85 * Number of entries in the MQ.
92 * Task to call the flush completion notification
94 * @param cls the logger handle
97 call_flush_completion (void *cls)
99 struct GNUNET_TESTBED_LOGGER_Handle *h = cls;
100 GNUNET_TESTBED_LOGGER_FlushCompletion cb;
104 h->flush_completion_task = NULL;
117 * Schedule the flush completion notification task
119 * @param h logger handle
122 trigger_flush_notification (struct GNUNET_TESTBED_LOGGER_Handle *h)
124 if (NULL != h->flush_completion_task)
125 GNUNET_SCHEDULER_cancel (h->flush_completion_task);
126 h->flush_completion_task
127 = GNUNET_SCHEDULER_add_now (&call_flush_completion,
133 * Send the buffered data to the service
135 * @param h the logger handle
138 dispatch_buffer (struct GNUNET_TESTBED_LOGGER_Handle *h);
142 * MQ successfully sent a message.
144 * @param cls our handle
147 notify_sent (void *cls)
149 struct GNUNET_TESTBED_LOGGER_Handle *h = cls;
152 if ( (0 == h->mq_len) &&
156 trigger_flush_notification (h);
164 * Send the buffered data to the service
166 * @param h the logger handle
169 dispatch_buffer (struct GNUNET_TESTBED_LOGGER_Handle *h)
171 struct GNUNET_MessageHeader *msg;
172 struct GNUNET_MQ_Envelope *env;
174 env = GNUNET_MQ_msg_extra (msg,
176 GNUNET_MESSAGE_TYPE_TESTBED_LOGGER_MSG);
177 GNUNET_memcpy (&msg[1],
180 h->bwrote += h->buse;
183 GNUNET_MQ_notify_sent (env,
186 GNUNET_MQ_send (h->mq,
192 * We got disconnected from the logger. Stop logging.
194 * @param cls the `struct GNUNET_TESTBED_LOGGER_Handle`
195 * @param error error code
198 mq_error_handler (void *cls,
199 enum GNUNET_MQ_Error error)
201 struct GNUNET_TESTBED_LOGGER_Handle *h = cls;
204 GNUNET_MQ_destroy (h->mq);
210 * Connect to the testbed logger service
212 * @param cfg configuration to use
213 * @return the handle which can be used for sending data to the service; NULL
216 struct GNUNET_TESTBED_LOGGER_Handle *
217 GNUNET_TESTBED_LOGGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
219 struct GNUNET_TESTBED_LOGGER_Handle *h;
221 h = GNUNET_new (struct GNUNET_TESTBED_LOGGER_Handle);
222 h->mq = GNUNET_CLIENT_connect (cfg,
237 * Disconnect from the logger service.
239 * @param h the logger handle
242 GNUNET_TESTBED_LOGGER_disconnect (struct GNUNET_TESTBED_LOGGER_Handle *h)
244 if (NULL != h->flush_completion_task)
246 GNUNET_SCHEDULER_cancel (h->flush_completion_task);
247 h->flush_completion_task = NULL;
250 LOG (GNUNET_ERROR_TYPE_WARNING,
251 "Disconnect lost %u logger message[s]\n",
255 GNUNET_MQ_destroy (h->mq);
263 * Send data to be logged to the logger service. The data will be buffered and
264 * will be sent upon an explicit call to GNUNET_TESTBED_LOGGER_flush() or upon
265 * exceeding a threshold size.
267 * @param h the logger handle
268 * @param data the data to send;
269 * @param size how many bytes of @a data to send
272 GNUNET_TESTBED_LOGGER_write (struct GNUNET_TESTBED_LOGGER_Handle *h,
280 size_t fit_size = GNUNET_MIN (size,
281 BUFFER_SIZE - h->buse);
282 GNUNET_memcpy (&h->buf[h->buse],
295 * Flush the buffered data to the logger service
297 * @param h the logger handle
298 * @param cb the callback to call after the data is flushed
299 * @param cb_cls the closure for the above callback
302 GNUNET_TESTBED_LOGGER_flush (struct GNUNET_TESTBED_LOGGER_Handle *h,
303 GNUNET_TESTBED_LOGGER_FlushCompletion cb,
306 GNUNET_assert (NULL == h->cb);
309 if ( (NULL == h->mq) ||
312 trigger_flush_notification (h);
320 * Cancel notification upon flush. Should only be used when the flush
321 * completion callback given to GNUNET_TESTBED_LOGGER_flush() is not already
324 * @param h the logger handle
327 GNUNET_TESTBED_LOGGER_flush_cancel (struct GNUNET_TESTBED_LOGGER_Handle *h)
329 if (NULL != h->flush_completion_task)
331 GNUNET_SCHEDULER_cancel (h->flush_completion_task);
332 h->flush_completion_task = NULL;
338 /* End of testbed_logger_api.c */