summaryrefslogtreecommitdiff
path: root/pjlib/include/pj/activesock.h
diff options
context:
space:
mode:
authorDavid M. Lee <dlee@digium.com>2013-01-07 14:24:28 -0600
committerDavid M. Lee <dlee@digium.com>2013-01-07 14:24:28 -0600
commitf3ab456a17af1c89a6e3be4d20c5944853df1cb0 (patch)
treed00e1a332cd038a6d906a1ea0ac91e1a4458e617 /pjlib/include/pj/activesock.h
Import pjproject-2.0.1
Diffstat (limited to 'pjlib/include/pj/activesock.h')
-rw-r--r--pjlib/include/pj/activesock.h560
1 files changed, 560 insertions, 0 deletions
diff --git a/pjlib/include/pj/activesock.h b/pjlib/include/pj/activesock.h
new file mode 100644
index 0000000..0c30c01
--- /dev/null
+++ b/pjlib/include/pj/activesock.h
@@ -0,0 +1,560 @@
+/* $Id: activesock.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJ_ASYNCSOCK_H__
+#define __PJ_ASYNCSOCK_H__
+
+/**
+ * @file activesock.h
+ * @brief Active socket
+ */
+
+#include <pj/ioqueue.h>
+#include <pj/sock.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_ACTIVESOCK Active socket I/O
+ * @brief Active socket performs active operations on socket.
+ * @ingroup PJ_IO
+ * @{
+ *
+ * Active socket is a higher level abstraction to the ioqueue. It provides
+ * automation to socket operations which otherwise would have to be done
+ * manually by the applications. For example with socket recv(), recvfrom(),
+ * and accept() operations, application only needs to invoke these
+ * operation once, and it will be notified whenever data or incoming TCP
+ * connection (in the case of accept()) arrives.
+ */
+
+/**
+ * This opaque structure describes the active socket.
+ */
+typedef struct pj_activesock_t pj_activesock_t;
+
+/**
+ * This structure contains the callbacks to be called by the active socket.
+ */
+typedef struct pj_activesock_cb
+{
+ /**
+ * This callback is called when a data arrives as the result of
+ * pj_activesock_start_read().
+ *
+ * @param asock The active socket.
+ * @param data The buffer containing the new data, if any. If
+ * the status argument is non-PJ_SUCCESS, this
+ * argument may be NULL.
+ * @param size The length of data in the buffer.
+ * @param status The status of the read operation. This may contain
+ * non-PJ_SUCCESS for example when the TCP connection
+ * has been closed. In this case, the buffer may
+ * contain left over data from previous callback which
+ * the application may want to process.
+ * @param remainder If application wishes to leave some data in the
+ * buffer (common for TCP applications), it should
+ * move the remainder data to the front part of the
+ * buffer and set the remainder length here. The value
+ * of this parameter will be ignored for datagram
+ * sockets.
+ *
+ * @return PJ_TRUE if further read is desired, and PJ_FALSE
+ * when application no longer wants to receive data.
+ * Application may destroy the active socket in the
+ * callback and return PJ_FALSE here.
+ */
+ pj_bool_t (*on_data_read)(pj_activesock_t *asock,
+ void *data,
+ pj_size_t size,
+ pj_status_t status,
+ pj_size_t *remainder);
+ /**
+ * This callback is called when a packet arrives as the result of
+ * pj_activesock_start_recvfrom().
+ *
+ * @param asock The active socket.
+ * @param data The buffer containing the packet, if any. If
+ * the status argument is non-PJ_SUCCESS, this
+ * argument will be set to NULL.
+ * @param size The length of packet in the buffer. If
+ * the status argument is non-PJ_SUCCESS, this
+ * argument will be set to zero.
+ * @param src_addr Source address of the packet.
+ * @param addr_len Length of the source address.
+ * @param status This contains
+ *
+ * @return PJ_TRUE if further read is desired, and PJ_FALSE
+ * when application no longer wants to receive data.
+ * Application may destroy the active socket in the
+ * callback and return PJ_FALSE here.
+ */
+ pj_bool_t (*on_data_recvfrom)(pj_activesock_t *asock,
+ void *data,
+ pj_size_t size,
+ const pj_sockaddr_t *src_addr,
+ int addr_len,
+ pj_status_t status);
+
+ /**
+ * This callback is called when data has been sent.
+ *
+ * @param asock The active socket.
+ * @param send_key Key associated with the send operation.
+ * @param sent If value is positive non-zero it indicates the
+ * number of data sent. When the value is negative,
+ * it contains the error code which can be retrieved
+ * by negating the value (i.e. status=-sent).
+ *
+ * @return Application may destroy the active socket in the
+ * callback and return PJ_FALSE here.
+ */
+ pj_bool_t (*on_data_sent)(pj_activesock_t *asock,
+ pj_ioqueue_op_key_t *send_key,
+ pj_ssize_t sent);
+
+ /**
+ * This callback is called when new connection arrives as the result
+ * of pj_activesock_start_accept().
+ *
+ * @param asock The active socket.
+ * @param newsock The new incoming socket.
+ * @param src_addr The source address of the connection.
+ * @param addr_len Length of the source address.
+ *
+ * @return PJ_TRUE if further accept() is desired, and PJ_FALSE
+ * when application no longer wants to accept incoming
+ * connection. Application may destroy the active socket
+ * in the callback and return PJ_FALSE here.
+ */
+ pj_bool_t (*on_accept_complete)(pj_activesock_t *asock,
+ pj_sock_t newsock,
+ const pj_sockaddr_t *src_addr,
+ int src_addr_len);
+
+ /**
+ * This callback is called when pending connect operation has been
+ * completed.
+ *
+ * @param asock The active socket.
+ * @param status The connection result. If connection has been
+ * successfully established, the status will contain
+ * PJ_SUCCESS.
+ *
+ * @return Application may destroy the active socket in the
+ * callback and return PJ_FALSE here.
+ */
+ pj_bool_t (*on_connect_complete)(pj_activesock_t *asock,
+ pj_status_t status);
+
+} pj_activesock_cb;
+
+
+/**
+ * Settings that can be given during active socket creation. Application
+ * must initialize this structure with #pj_activesock_cfg_default().
+ */
+typedef struct pj_activesock_cfg
+{
+ /**
+ * Number of concurrent asynchronous operations that is to be supported
+ * by the active socket. This value only affects socket receive and
+ * accept operations -- the active socket will issue one or more
+ * asynchronous read and accept operations based on the value of this
+ * field. Setting this field to more than one will allow more than one
+ * incoming data or incoming connections to be processed simultaneously
+ * on multiprocessor systems, when the ioqueue is polled by more than
+ * one threads.
+ *
+ * The default value is 1.
+ */
+ unsigned async_cnt;
+
+ /**
+ * The ioqueue concurrency to be forced on the socket when it is
+ * registered to the ioqueue. See #pj_ioqueue_set_concurrency() for more
+ * info about ioqueue concurrency.
+ *
+ * When this value is -1, the concurrency setting will not be forced for
+ * this socket, and the socket will inherit the concurrency setting of
+ * the ioqueue. When this value is zero, the active socket will disable
+ * concurrency for the socket. When this value is +1, the active socket
+ * will enable concurrency for the socket.
+ *
+ * The default value is -1.
+ */
+ int concurrency;
+
+ /**
+ * If this option is specified, the active socket will make sure that
+ * asynchronous send operation with stream oriented socket will only
+ * call the callback after all data has been sent. This means that the
+ * active socket will automatically resend the remaining data until
+ * all data has been sent.
+ *
+ * Please note that when this option is specified, it is possible that
+ * error is reported after partial data has been sent. Also setting
+ * this will disable the ioqueue concurrency for the socket.
+ *
+ * Default value is 1.
+ */
+ pj_bool_t whole_data;
+
+} pj_activesock_cfg;
+
+
+/**
+ * Initialize the active socket configuration with the default values.
+ *
+ * @param cfg The configuration to be initialized.
+ */
+PJ_DECL(void) pj_activesock_cfg_default(pj_activesock_cfg *cfg);
+
+
+/**
+ * Create the active socket for the specified socket. This will register
+ * the socket to the specified ioqueue.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param sock The socket handle.
+ * @param sock_type Specify socket type, either pj_SOCK_DGRAM() or
+ * pj_SOCK_STREAM(). The active socket needs this
+ * information to handle connection closure for
+ * connection oriented sockets.
+ * @param ioqueue The ioqueue to use.
+ * @param opt Optional settings. When this setting is not specifed,
+ * the default values will be used.
+ * @param cb Pointer to structure containing application
+ * callbacks.
+ * @param user_data Arbitrary user data to be associated with this
+ * active socket.
+ * @param p_asock Pointer to receive the active socket instance.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_activesock_create(pj_pool_t *pool,
+ pj_sock_t sock,
+ int sock_type,
+ const pj_activesock_cfg *opt,
+ pj_ioqueue_t *ioqueue,
+ const pj_activesock_cb *cb,
+ void *user_data,
+ pj_activesock_t **p_asock);
+
+/**
+ * Create UDP socket descriptor, bind it to the specified address, and
+ * create the active socket for the socket descriptor.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param addr Specifies the address family of the socket and the
+ * address where the socket should be bound to. If
+ * this argument is NULL, then AF_INET is assumed and
+ * the socket will be bound to any addresses and port.
+ * @param opt Optional settings. When this setting is not specifed,
+ * the default values will be used.
+ * @param cb Pointer to structure containing application
+ * callbacks.
+ * @param user_data Arbitrary user data to be associated with this
+ * active socket.
+ * @param p_asock Pointer to receive the active socket instance.
+ * @param bound_addr If this argument is specified, it will be filled with
+ * the bound address on return.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_activesock_create_udp(pj_pool_t *pool,
+ const pj_sockaddr *addr,
+ const pj_activesock_cfg *opt,
+ pj_ioqueue_t *ioqueue,
+ const pj_activesock_cb *cb,
+ void *user_data,
+ pj_activesock_t **p_asock,
+ pj_sockaddr *bound_addr);
+
+
+/**
+ * Close the active socket. This will unregister the socket from the
+ * ioqueue and ultimately close the socket.
+ *
+ * @param asock The active socket.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_activesock_close(pj_activesock_t *asock);
+
+#if (defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \
+ PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0) || \
+ defined(DOXYGEN)
+/**
+ * Set iPhone OS background mode setting. Setting to 1 will enable TCP
+ * active socket to receive incoming data when application is in the
+ * background. Setting to 0 will disable it. Default value of this
+ * setting is PJ_ACTIVESOCK_TCP_IPHONE_OS_BG.
+ *
+ * This API is only available if PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT
+ * is set to non-zero.
+ *
+ * @param asock The active socket.
+ * @param val The value of background mode setting.
+ *
+ */
+PJ_DECL(void) pj_activesock_set_iphone_os_bg(pj_activesock_t *asock,
+ int val);
+
+/**
+ * Enable/disable support for iPhone OS background mode. This setting
+ * will apply globally and will affect any active sockets created
+ * afterwards, if you want to change the setting for a particular
+ * active socket, use #pj_activesock_set_iphone_os_bg() instead.
+ * By default, this setting is enabled.
+ *
+ * This API is only available if PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT
+ * is set to non-zero.
+ *
+ * @param val The value of global background mode setting.
+ *
+ */
+PJ_DECL(void) pj_activesock_enable_iphone_os_bg(pj_bool_t val);
+#endif
+
+/**
+ * Associate arbitrary data with the active socket. Application may
+ * inspect this data in the callbacks and associate it with higher
+ * level processing.
+ *
+ * @param asock The active socket.
+ * @param user_data The user data to be associated with the active
+ * socket.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_activesock_set_user_data(pj_activesock_t *asock,
+ void *user_data);
+
+/**
+ * Retrieve the user data previously associated with this active
+ * socket.
+ *
+ * @param asock The active socket.
+ *
+ * @return The user data.
+ */
+PJ_DECL(void*) pj_activesock_get_user_data(pj_activesock_t *asock);
+
+
+/**
+ * Starts read operation on this active socket. This function will create
+ * \a async_cnt number of buffers (the \a async_cnt parameter was given
+ * in \a pj_activesock_create() function) where each buffer is \a buff_size
+ * long. The buffers are allocated from the specified \a pool. Once the
+ * buffers are created, it then issues \a async_cnt number of asynchronous
+ * \a recv() operations to the socket and returns back to caller. Incoming
+ * data on the socket will be reported back to application via the
+ * \a on_data_read() callback.
+ *
+ * Application only needs to call this function once to initiate read
+ * operations. Further read operations will be done automatically by the
+ * active socket when \a on_data_read() callback returns non-zero.
+ *
+ * @param asock The active socket.
+ * @param pool Pool used to allocate buffers for incoming data.
+ * @param buff_size The size of each buffer, in bytes.
+ * @param flags Flags to be given to pj_ioqueue_recv().
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_activesock_start_read(pj_activesock_t *asock,
+ pj_pool_t *pool,
+ unsigned buff_size,
+ pj_uint32_t flags);
+
+/**
+ * Same as #pj_activesock_start_read(), except that the application
+ * supplies the buffers for the read operation so that the acive socket
+ * does not have to allocate the buffers.
+ *
+ * @param asock The active socket.
+ * @param pool Pool used to allocate buffers for incoming data.
+ * @param buff_size The size of each buffer, in bytes.
+ * @param readbuf Array of packet buffers, each has buff_size size.
+ * @param flags Flags to be given to pj_ioqueue_recv().
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_activesock_start_read2(pj_activesock_t *asock,
+ pj_pool_t *pool,
+ unsigned buff_size,
+ void *readbuf[],
+ pj_uint32_t flags);
+
+/**
+ * Same as pj_activesock_start_read(), except that this function is used
+ * only for datagram sockets, and it will trigger \a on_data_recvfrom()
+ * callback instead.
+ *
+ * @param asock The active socket.
+ * @param pool Pool used to allocate buffers for incoming data.
+ * @param buff_size The size of each buffer, in bytes.
+ * @param flags Flags to be given to pj_ioqueue_recvfrom().
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_activesock_start_recvfrom(pj_activesock_t *asock,
+ pj_pool_t *pool,
+ unsigned buff_size,
+ pj_uint32_t flags);
+
+/**
+ * Same as #pj_activesock_start_recvfrom() except that the recvfrom()
+ * operation takes the buffer from the argument rather than creating
+ * new ones.
+ *
+ * @param asock The active socket.
+ * @param pool Pool used to allocate buffers for incoming data.
+ * @param buff_size The size of each buffer, in bytes.
+ * @param readbuf Array of packet buffers, each has buff_size size.
+ * @param flags Flags to be given to pj_ioqueue_recvfrom().
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_activesock_start_recvfrom2(pj_activesock_t *asock,
+ pj_pool_t *pool,
+ unsigned buff_size,
+ void *readbuf[],
+ pj_uint32_t flags);
+
+/**
+ * Send data using the socket.
+ *
+ * @param asock The active socket.
+ * @param send_key The operation key to send the data, which is useful
+ * if application wants to submit multiple pending
+ * send operations and want to track which exact data
+ * has been sent in the \a on_data_sent() callback.
+ * @param data The data to be sent. This data must remain valid
+ * until the data has been sent.
+ * @param size The size of the data.
+ * @param flags Flags to be given to pj_ioqueue_send().
+ *
+ *
+ * @return PJ_SUCCESS if data has been sent immediately, or
+ * PJ_EPENDING if data cannot be sent immediately. In
+ * this case the \a on_data_sent() callback will be
+ * called when data is actually sent. Any other return
+ * value indicates error condition.
+ */
+PJ_DECL(pj_status_t) pj_activesock_send(pj_activesock_t *asock,
+ pj_ioqueue_op_key_t *send_key,
+ const void *data,
+ pj_ssize_t *size,
+ unsigned flags);
+
+/**
+ * Send datagram using the socket.
+ *
+ * @param asock The active socket.
+ * @param send_key The operation key to send the data, which is useful
+ * if application wants to submit multiple pending
+ * send operations and want to track which exact data
+ * has been sent in the \a on_data_sent() callback.
+ * @param data The data to be sent. This data must remain valid
+ * until the data has been sent.
+ * @param size The size of the data.
+ * @param flags Flags to be given to pj_ioqueue_send().
+ * @param addr The destination address.
+ * @param addr_len The length of the address.
+ *
+ * @return PJ_SUCCESS if data has been sent immediately, or
+ * PJ_EPENDING if data cannot be sent immediately. In
+ * this case the \a on_data_sent() callback will be
+ * called when data is actually sent. Any other return
+ * value indicates error condition.
+ */
+PJ_DECL(pj_status_t) pj_activesock_sendto(pj_activesock_t *asock,
+ pj_ioqueue_op_key_t *send_key,
+ const void *data,
+ pj_ssize_t *size,
+ unsigned flags,
+ const pj_sockaddr_t *addr,
+ int addr_len);
+
+#if PJ_HAS_TCP
+/**
+ * Starts asynchronous socket accept() operations on this active socket.
+ * Application must bind the socket before calling this function. This
+ * function will issue \a async_cnt number of asynchronous \a accept()
+ * operations to the socket and returns back to caller. Incoming
+ * connection on the socket will be reported back to application via the
+ * \a on_accept_complete() callback.
+ *
+ * Application only needs to call this function once to initiate accept()
+ * operations. Further accept() operations will be done automatically by
+ * the active socket when \a on_accept_complete() callback returns non-zero.
+ *
+ * @param asock The active socket.
+ * @param pool Pool used to allocate some internal data for the
+ * operation.
+ *
+ * @return PJ_SUCCESS if the operation has been successful,
+ * or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t) pj_activesock_start_accept(pj_activesock_t *asock,
+ pj_pool_t *pool);
+
+/**
+ * Starts asynchronous socket connect() operation for this socket. Once
+ * the connection is done (either successfully or not), the
+ * \a on_connect_complete() callback will be called.
+ *
+ * @param asock The active socket.
+ * @param pool The pool to allocate some internal data for the
+ * operation.
+ * @param remaddr Remote address.
+ * @param addr_len Length of the remote address.
+ *
+ * @return PJ_SUCCESS if connection can be established immediately,
+ * or PJ_EPENDING if connection cannot be established
+ * immediately. In this case the \a on_connect_complete()
+ * callback will be called when connection is complete.
+ * Any other return value indicates error condition.
+ */
+PJ_DECL(pj_status_t) pj_activesock_start_connect(pj_activesock_t *asock,
+ pj_pool_t *pool,
+ const pj_sockaddr_t *remaddr,
+ int addr_len);
+
+#endif /* PJ_HAS_TCP */
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJ_ASYNCSOCK_H__ */
+