From d986f2c7460120ffc3f199b29a06126d0b97b75b Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 30 Aug 2009 20:48:51 +0000 Subject: [PATCH] adding convenience API --- src/include/gnunet_client_lib.h | 24 +++++++ src/util/client.c | 112 ++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) diff --git a/src/include/gnunet_client_lib.h b/src/include/gnunet_client_lib.h index 8651b273c..d391aed2b 100644 --- a/src/include/gnunet_client_lib.h +++ b/src/include/gnunet_client_lib.h @@ -119,6 +119,30 @@ struct GNUNET_CONNECTION_TransmitHandle notify, void *notify_cls); + +/** + * Convenience API that combines sending a request + * to the service and waiting for a response. + * If either operation times out, the callback + * will be called with a "NULL" response (in which + * case the connection should probably be destroyed). + * + * @param sock connection to use + * @param hdr message to transmit + * @param timeout when to give up (for both transmission + * and for waiting for a response) + * @param rn function to call with the response + * @param rn_cls closure for rn + */ +void +GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *sock, + const struct GNUNET_MessageHeader *hdr, + struct GNUNET_TIME_Relative timeout, + GNUNET_CLIENT_MessageHandler rn, + void *rn_cls); + + + /** * Request that the service should shutdown. * Afterwards, the connection should be disconnected. diff --git a/src/util/client.c b/src/util/client.c index 0c639c905..8b356ce45 100644 --- a/src/util/client.c +++ b/src/util/client.c @@ -521,4 +521,116 @@ GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock, } +/** + * Context for processing + * "GNUNET_CLIENT_transmit_and_get_response" requests. + */ +struct TARCtx +{ + /** + * Client handle. + */ + struct GNUNET_CLIENT_Connection *sock; + + /** + * Message to transmit; do not free, allocated + * right after this struct. + */ + const struct GNUNET_MessageHeader *hdr; + + /** + * Timeout to use. + */ + struct GNUNET_TIME_Absolute timeout; + + /** + * Function to call when done. + */ + GNUNET_CLIENT_MessageHandler rn; + + /** + * Closure for "rn". + */ + void *rn_cls; +}; + + +/** + * Function called to notify a client about the socket + * begin ready to queue the message. "buf" will be + * NULL and "size" zero if the socket was closed for + * writing in the meantime. + * + * @param cls closure of type "struct TARCtx*" + * @param size number of bytes available in buf + * @param buf where the callee should write the message + * @return number of bytes written to buf + */ +static size_t +transmit_for_response (void *cls, + size_t size, + void *buf) +{ + struct TARCtx *tc = cls; + uint16_t msize; + + msize = ntohs(tc->hdr->size); + if (NULL == buf) + { + tc->rn (tc->rn_cls, NULL); + GNUNET_free (tc); + return 0; + } + GNUNET_assert (size >= msize); + memcpy (buf, tc->hdr, msize); + GNUNET_CLIENT_receive (tc->sock, + tc->rn, + tc->rn_cls, + GNUNET_TIME_absolute_get_remaining (tc->timeout)); + GNUNET_free (tc); + return msize; +} + + +/** + * Convenience API that combines sending a request + * to the service and waiting for a response. + * If either operation times out, the callback + * will be called with a "NULL" response (in which + * case the connection should probably be destroyed). + * + * @param sock connection to use + * @param hdr message to transmit + * @param timeout when to give up (for both transmission + * and for waiting for a response) + * @param rn function to call with the response + * @param rn_cls closure for rn + */ +void +GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *sock, + const struct GNUNET_MessageHeader *hdr, + struct GNUNET_TIME_Relative timeout, + GNUNET_CLIENT_MessageHandler rn, + void *rn_cls) +{ + struct TARCtx *tc; + uint16_t msize; + + msize = ntohs(hdr->size); + tc = GNUNET_malloc(sizeof (struct TARCtx) + msize); + tc->sock = sock; + tc->hdr = (const struct GNUNET_MessageHeader*) &tc[1]; + memcpy (&tc[1], hdr, msize); + tc->timeout = GNUNET_TIME_relative_to_absolute (timeout); + tc->rn = rn; + tc->rn_cls = rn_cls; + GNUNET_CLIENT_notify_transmit_ready (sock, + msize, + timeout, + &transmit_for_response, + tc); +} + + + /* end of client.c */ -- 2.25.1