From f3ab456a17af1c89a6e3be4d20c5944853df1cb0 Mon Sep 17 00:00:00 2001 From: "David M. Lee" Date: Mon, 7 Jan 2013 14:24:28 -0600 Subject: Import pjproject-2.0.1 --- pjlib/include/pj/activesock.h | 560 +++++++++++ pjlib/include/pj/addr_resolv.h | 165 ++++ pjlib/include/pj/array.h | 96 ++ pjlib/include/pj/assert.h | 95 ++ pjlib/include/pj/compat/assert.h | 44 + pjlib/include/pj/compat/cc_armcc.h | 57 ++ pjlib/include/pj/compat/cc_codew.h | 55 ++ pjlib/include/pj/compat/cc_gcc.h | 78 ++ pjlib/include/pj/compat/cc_gcce.h | 54 ++ pjlib/include/pj/compat/cc_msvc.h | 87 ++ pjlib/include/pj/compat/cc_mwcc.h | 55 ++ pjlib/include/pj/compat/ctype.h | 49 + pjlib/include/pj/compat/errno.h | 44 + pjlib/include/pj/compat/high_precision.h | 103 ++ pjlib/include/pj/compat/m_alpha.h | 36 + pjlib/include/pj/compat/m_armv4.h | 39 + pjlib/include/pj/compat/m_auto.h.in | 60 ++ pjlib/include/pj/compat/m_i386.h | 35 + pjlib/include/pj/compat/m_m68k.h | 35 + pjlib/include/pj/compat/m_powerpc.h | 36 + pjlib/include/pj/compat/m_sparc.h | 35 + pjlib/include/pj/compat/m_x86_64.h | 36 + pjlib/include/pj/compat/malloc.h | 34 + pjlib/include/pj/compat/os_auto.h.in | 212 +++++ pjlib/include/pj/compat/os_darwinos.h | 145 +++ pjlib/include/pj/compat/os_linux.h | 129 +++ pjlib/include/pj/compat/os_linux_kernel.h | 149 +++ pjlib/include/pj/compat/os_palmos.h | 119 +++ pjlib/include/pj/compat/os_rtems.h | 139 +++ pjlib/include/pj/compat/os_sunos.h | 132 +++ pjlib/include/pj/compat/os_symbian.h | 167 ++++ pjlib/include/pj/compat/os_win32.h | 139 +++ pjlib/include/pj/compat/os_win32_wince.h | 146 +++ pjlib/include/pj/compat/rand.h | 70 ++ pjlib/include/pj/compat/setjmp.h | 98 ++ pjlib/include/pj/compat/size_t.h | 32 + pjlib/include/pj/compat/socket.h | 239 +++++ pjlib/include/pj/compat/stdarg.h | 32 + pjlib/include/pj/compat/stdfileio.h | 32 + pjlib/include/pj/compat/string.h | 144 +++ pjlib/include/pj/compat/time.h | 42 + pjlib/include/pj/config.h | 1211 +++++++++++++++++++++++ pjlib/include/pj/config_site_sample.h | 407 ++++++++ pjlib/include/pj/ctype.h | 175 ++++ pjlib/include/pj/doxygen.h | 996 +++++++++++++++++++ pjlib/include/pj/errno.h | 577 +++++++++++ pjlib/include/pj/except.h | 421 ++++++++ pjlib/include/pj/fifobuf.h | 44 + pjlib/include/pj/file_access.h | 109 +++ pjlib/include/pj/file_io.h | 183 ++++ pjlib/include/pj/guid.h | 101 ++ pjlib/include/pj/hash.h | 220 +++++ pjlib/include/pj/ioqueue.h | 805 ++++++++++++++++ pjlib/include/pj/ip_helper.h | 97 ++ pjlib/include/pj/list.h | 273 ++++++ pjlib/include/pj/list_i.h | 121 +++ pjlib/include/pj/lock.h | 154 +++ pjlib/include/pj/log.h | 423 +++++++++ pjlib/include/pj/math.h | 197 ++++ pjlib/include/pj/os.h | 1476 +++++++++++++++++++++++++++++ pjlib/include/pj/pool.h | 903 ++++++++++++++++++ pjlib/include/pj/pool_alt.h | 198 ++++ pjlib/include/pj/pool_buf.h | 105 ++ pjlib/include/pj/pool_i.h | 94 ++ pjlib/include/pj/rand.h | 66 ++ pjlib/include/pj/rbtree.h | 210 ++++ pjlib/include/pj/sock.h | 1393 +++++++++++++++++++++++++++ pjlib/include/pj/sock_qos.h | 427 +++++++++ pjlib/include/pj/sock_select.h | 152 +++ pjlib/include/pj/ssl_sock.h | 1051 ++++++++++++++++++++ pjlib/include/pj/string.h | 692 ++++++++++++++ pjlib/include/pj/string_i.h | 371 ++++++++ pjlib/include/pj/timer.h | 297 ++++++ pjlib/include/pj/types.h | 542 +++++++++++ pjlib/include/pj/unicode.h | 141 +++ 75 files changed, 18686 insertions(+) create mode 100644 pjlib/include/pj/activesock.h create mode 100644 pjlib/include/pj/addr_resolv.h create mode 100644 pjlib/include/pj/array.h create mode 100644 pjlib/include/pj/assert.h create mode 100644 pjlib/include/pj/compat/assert.h create mode 100644 pjlib/include/pj/compat/cc_armcc.h create mode 100644 pjlib/include/pj/compat/cc_codew.h create mode 100644 pjlib/include/pj/compat/cc_gcc.h create mode 100644 pjlib/include/pj/compat/cc_gcce.h create mode 100644 pjlib/include/pj/compat/cc_msvc.h create mode 100644 pjlib/include/pj/compat/cc_mwcc.h create mode 100644 pjlib/include/pj/compat/ctype.h create mode 100644 pjlib/include/pj/compat/errno.h create mode 100644 pjlib/include/pj/compat/high_precision.h create mode 100644 pjlib/include/pj/compat/m_alpha.h create mode 100644 pjlib/include/pj/compat/m_armv4.h create mode 100644 pjlib/include/pj/compat/m_auto.h.in create mode 100644 pjlib/include/pj/compat/m_i386.h create mode 100644 pjlib/include/pj/compat/m_m68k.h create mode 100644 pjlib/include/pj/compat/m_powerpc.h create mode 100644 pjlib/include/pj/compat/m_sparc.h create mode 100644 pjlib/include/pj/compat/m_x86_64.h create mode 100644 pjlib/include/pj/compat/malloc.h create mode 100644 pjlib/include/pj/compat/os_auto.h.in create mode 100644 pjlib/include/pj/compat/os_darwinos.h create mode 100644 pjlib/include/pj/compat/os_linux.h create mode 100644 pjlib/include/pj/compat/os_linux_kernel.h create mode 100644 pjlib/include/pj/compat/os_palmos.h create mode 100644 pjlib/include/pj/compat/os_rtems.h create mode 100644 pjlib/include/pj/compat/os_sunos.h create mode 100644 pjlib/include/pj/compat/os_symbian.h create mode 100644 pjlib/include/pj/compat/os_win32.h create mode 100644 pjlib/include/pj/compat/os_win32_wince.h create mode 100644 pjlib/include/pj/compat/rand.h create mode 100644 pjlib/include/pj/compat/setjmp.h create mode 100644 pjlib/include/pj/compat/size_t.h create mode 100644 pjlib/include/pj/compat/socket.h create mode 100644 pjlib/include/pj/compat/stdarg.h create mode 100644 pjlib/include/pj/compat/stdfileio.h create mode 100644 pjlib/include/pj/compat/string.h create mode 100644 pjlib/include/pj/compat/time.h create mode 100644 pjlib/include/pj/config.h create mode 100644 pjlib/include/pj/config_site_sample.h create mode 100644 pjlib/include/pj/ctype.h create mode 100644 pjlib/include/pj/doxygen.h create mode 100644 pjlib/include/pj/errno.h create mode 100644 pjlib/include/pj/except.h create mode 100644 pjlib/include/pj/fifobuf.h create mode 100644 pjlib/include/pj/file_access.h create mode 100644 pjlib/include/pj/file_io.h create mode 100644 pjlib/include/pj/guid.h create mode 100644 pjlib/include/pj/hash.h create mode 100644 pjlib/include/pj/ioqueue.h create mode 100644 pjlib/include/pj/ip_helper.h create mode 100644 pjlib/include/pj/list.h create mode 100644 pjlib/include/pj/list_i.h create mode 100644 pjlib/include/pj/lock.h create mode 100644 pjlib/include/pj/log.h create mode 100644 pjlib/include/pj/math.h create mode 100644 pjlib/include/pj/os.h create mode 100644 pjlib/include/pj/pool.h create mode 100644 pjlib/include/pj/pool_alt.h create mode 100644 pjlib/include/pj/pool_buf.h create mode 100644 pjlib/include/pj/pool_i.h create mode 100644 pjlib/include/pj/rand.h create mode 100644 pjlib/include/pj/rbtree.h create mode 100644 pjlib/include/pj/sock.h create mode 100644 pjlib/include/pj/sock_qos.h create mode 100644 pjlib/include/pj/sock_select.h create mode 100644 pjlib/include/pj/ssl_sock.h create mode 100644 pjlib/include/pj/string.h create mode 100644 pjlib/include/pj/string_i.h create mode 100644 pjlib/include/pj/timer.h create mode 100644 pjlib/include/pj/types.h create mode 100644 pjlib/include/pj/unicode.h (limited to 'pjlib/include/pj') 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 + * + * 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 +#include + + +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__ */ + diff --git a/pjlib/include/pj/addr_resolv.h b/pjlib/include/pj/addr_resolv.h new file mode 100644 index 0000000..ae10337 --- /dev/null +++ b/pjlib/include/pj/addr_resolv.h @@ -0,0 +1,165 @@ +/* $Id: addr_resolv.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 + * + * 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_ADDR_RESOLV_H__ +#define __PJ_ADDR_RESOLV_H__ + +/** + * @file addr_resolv.h + * @brief IP address resolution. + */ + +#include + +PJ_BEGIN_DECL + +/** + * @defgroup pj_addr_resolve Network Address Resolution + * @ingroup PJ_IO + * @{ + * + * This module provides function to resolve Internet address of the + * specified host name. To resolve a particular host name, application + * can just call #pj_gethostbyname(). + * + * Example: + *
+ *   ...
+ *   pj_hostent he;
+ *   pj_status_t rc;
+ *   pj_str_t host = pj_str("host.example.com");
+ *   
+ *   rc = pj_gethostbyname( &host, &he);
+ *   if (rc != PJ_SUCCESS) {
+ *      char errbuf[80];
+ *      pj_strerror( rc, errbuf, sizeof(errbuf));
+ *      PJ_LOG(2,("sample", "Unable to resolve host, error=%s", errbuf));
+ *      return rc;
+ *   }
+ *
+ *   // process address...
+ *   addr.sin_addr.s_addr = *(pj_uint32_t*)he.h_addr;
+ *   ...
+ * 
+ * + * It's pretty simple really... + */ + +/** This structure describes an Internet host address. */ +typedef struct pj_hostent +{ + char *h_name; /**< The official name of the host. */ + char **h_aliases; /**< Aliases list. */ + int h_addrtype; /**< Host address type. */ + int h_length; /**< Length of address. */ + char **h_addr_list; /**< List of addresses. */ +} pj_hostent; + +/** Shortcut to h_addr_list[0] */ +#define h_addr h_addr_list[0] + +/** + * This structure describes address information pj_getaddrinfo(). + */ +typedef struct pj_addrinfo +{ + char ai_canonname[PJ_MAX_HOSTNAME]; /**< Canonical name for host*/ + pj_sockaddr ai_addr; /**< Binary address. */ +} pj_addrinfo; + + +/** + * This function fills the structure of type pj_hostent for a given host name. + * For host resolution function that also works with IPv6, please see + * #pj_getaddrinfo(). + * + * @param name Host name to resolve. Specifying IPv4 address here + * may fail on some platforms (e.g. Windows) + * @param he The pj_hostent structure to be filled. Note that + * the pointers in this structure points to temporary + * variables which value will be reset upon subsequent + * invocation. + * + * @return PJ_SUCCESS, or the appropriate error codes. + */ +PJ_DECL(pj_status_t) pj_gethostbyname(const pj_str_t *name, pj_hostent *he); + + +/** + * Resolve the primary IP address of local host. + * + * @param af The desired address family to query. Valid values + * are pj_AF_INET() or pj_AF_INET6(). + * @param addr On successful resolution, the address family and address + * part of this socket address will be filled up with the host + * IP address, in network byte order. Other parts of the socket + * address are untouched. + * + * @return PJ_SUCCESS on success, or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_gethostip(int af, pj_sockaddr *addr); + + +/** + * Get the IP address of the default interface. Default interface is the + * interface of the default route. + * + * @param af The desired address family to query. Valid values + * are pj_AF_INET() or pj_AF_INET6(). + * @param addr On successful resolution, the address family and address + * part of this socket address will be filled up with the host + * IP address, in network byte order. Other parts of the socket + * address are untouched. + * + * @return PJ_SUCCESS on success, or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_getdefaultipinterface(int af, + pj_sockaddr *addr); + + +/** + * This function translates the name of a service location (for example, + * a host name) and returns a set of addresses and associated information + * to be used in creating a socket with which to address the specified + * service. + * + * @param af The desired address family to query. Valid values + * are pj_AF_INET(), pj_AF_INET6(), or pj_AF_UNSPEC(). + * @param name Descriptive name or an address string, such as host + * name. + * @param count On input, it specifies the number of elements in + * \a ai array. On output, this will be set with the + * number of address informations found for the + * specified name. + * @param ai Array of address info to be filled with the information + * about the host. + * + * @return PJ_SUCCESS on success, or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_getaddrinfo(int af, const pj_str_t *name, + unsigned *count, pj_addrinfo ai[]); + + + +/** @} */ + +PJ_END_DECL + +#endif /* __PJ_ADDR_RESOLV_H__ */ + diff --git a/pjlib/include/pj/array.h b/pjlib/include/pj/array.h new file mode 100644 index 0000000..9b93727 --- /dev/null +++ b/pjlib/include/pj/array.h @@ -0,0 +1,96 @@ +/* $Id: array.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 + * + * 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_ARRAY_H__ +#define __PJ_ARRAY_H__ + +/** + * @file array.h + * @brief PJLIB Array helper. + */ +#include + +PJ_BEGIN_DECL + +/** + * @defgroup PJ_ARRAY Array helper. + * @ingroup PJ_DS + * @{ + * + * This module provides helper to manipulate array of elements of any size. + * It provides most used array operations such as insert, erase, and search. + */ + +/** + * Insert value to the array at the given position, and rearrange the + * remaining nodes after the position. + * + * @param array the array. + * @param elem_size the size of the individual element. + * @param count the CURRENT number of elements in the array. + * @param pos the position where the new element is put. + * @param value the value to copy to the new element. + */ +PJ_DECL(void) pj_array_insert( void *array, + unsigned elem_size, + unsigned count, + unsigned pos, + const void *value); + +/** + * Erase a value from the array at given position, and rearrange the remaining + * elements post the erased element. + * + * @param array the array. + * @param elem_size the size of the individual element. + * @param count the current number of elements in the array. + * @param pos the index/position to delete. + */ +PJ_DECL(void) pj_array_erase( void *array, + unsigned elem_size, + unsigned count, + unsigned pos); + +/** + * Search the first value in the array according to matching function. + * + * @param array the array. + * @param elem_size the individual size of the element. + * @param count the number of elements. + * @param matching the matching function, which MUST return PJ_SUCCESS if + * the specified element match. + * @param result the pointer to the value found. + * + * @return PJ_SUCCESS if value is found, otherwise the error code. + */ +PJ_DECL(pj_status_t) pj_array_find( const void *array, + unsigned elem_size, + unsigned count, + pj_status_t (*matching)(const void *value), + void **result); + +/** + * @} + */ + +PJ_END_DECL + + +#endif /* __PJ_ARRAY_H__ */ + diff --git a/pjlib/include/pj/assert.h b/pjlib/include/pj/assert.h new file mode 100644 index 0000000..41a5d11 --- /dev/null +++ b/pjlib/include/pj/assert.h @@ -0,0 +1,95 @@ +/* $Id: assert.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 + * + * 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_ASSERT_H__ +#define __PJ_ASSERT_H__ + +/** + * @file assert.h + * @brief Assertion macro pj_assert(). + */ + +#include +#include + +/** + * @defgroup pj_assert Assertion Macro + * @ingroup PJ_MISC + * @{ + * + * Assertion and other helper macros for sanity checking. + */ + +/** + * @hideinitializer + * Check during debug build that an expression is true. If the expression + * computes to false during run-time, then the program will stop at the + * offending statements. + * For release build, this macro will not do anything. + * + * @param expr The expression to be evaluated. + */ +#ifndef pj_assert +# define pj_assert(expr) assert(expr) +#endif + + +/** + * @hideinitializer + * If #PJ_ENABLE_EXTRA_CHECK is declared and the value is non-zero, then + * #PJ_ASSERT_RETURN macro will evaluate the expression in @a expr during + * run-time. If the expression yields false, assertion will be triggered + * and the current function will return with the specified return value. + * + * If #PJ_ENABLE_EXTRA_CHECK is not declared or is zero, then no run-time + * checking will be performed. The macro simply evaluates to pj_assert(expr). + */ +#if defined(PJ_ENABLE_EXTRA_CHECK) && PJ_ENABLE_EXTRA_CHECK != 0 +# define PJ_ASSERT_RETURN(expr,retval) \ + do { \ + if (!(expr)) { pj_assert(expr); return retval; } \ + } while (0) +#else +# define PJ_ASSERT_RETURN(expr,retval) pj_assert(expr) +#endif + +/** + * @hideinitializer + * If #PJ_ENABLE_EXTRA_CHECK is declared and non-zero, then + * #PJ_ASSERT_ON_FAIL macro will evaluate the expression in @a expr during + * run-time. If the expression yields false, assertion will be triggered + * and @a exec_on_fail will be executed. + * + * If #PJ_ENABLE_EXTRA_CHECK is not declared or is zero, then no run-time + * checking will be performed. The macro simply evaluates to pj_assert(expr). + */ +#if defined(PJ_ENABLE_EXTRA_CHECK) && PJ_ENABLE_EXTRA_CHECK != 0 +# define PJ_ASSERT_ON_FAIL(expr,exec_on_fail) \ + do { \ + pj_assert(expr); \ + if (!(expr)) exec_on_fail; \ + } while (0) +#else +# define PJ_ASSERT_ON_FAIL(expr,exec_on_fail) pj_assert(expr) +#endif + +/** @} */ + +#endif /* __PJ_ASSERT_H__ */ + diff --git a/pjlib/include/pj/compat/assert.h b/pjlib/include/pj/compat/assert.h new file mode 100644 index 0000000..f1b5c96 --- /dev/null +++ b/pjlib/include/pj/compat/assert.h @@ -0,0 +1,44 @@ +/* $Id: assert.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 + * + * 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_COMPAT_ASSERT_H__ +#define __PJ_COMPAT_ASSERT_H__ + +/** + * @file assert.h + * @brief Provides assert() macro. + */ + +#if defined(PJ_HAS_ASSERT_H) && PJ_HAS_ASSERT_H != 0 +# include + +#elif defined(PJ_LINUX_KERNEL) && PJ_LINUX_KERNEL != 0 +# define assert(expr) do { \ + if (!(expr)) \ + printk("!!ASSERTION FAILED: [%s:%d] \"" #expr "\"\n",\ + __FILE__, __LINE__); \ + } while (0) + +#else +# warning "assert() is not implemented" +# define assert(expr) +#endif + +#endif /* __PJ_COMPAT_ASSERT_H__ */ + diff --git a/pjlib/include/pj/compat/cc_armcc.h b/pjlib/include/pj/compat/cc_armcc.h new file mode 100644 index 0000000..e21c4f8 --- /dev/null +++ b/pjlib/include/pj/compat/cc_armcc.h @@ -0,0 +1,57 @@ +/* $Id: cc_armcc.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 + * + * 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_COMPAT_CC_ARMCC_H__ +#define __PJ_COMPAT_CC_ARMCC_H__ + +/** + * @file cc_armcc.h + * @brief Describes ARMCC compiler specifics. + */ + +#ifndef __ARMCC__ +# error "This file is only for armcc!" +#endif + +#define PJ_CC_NAME "armcc" +#define PJ_CC_VER_1 (__ARMCC_VERSION/100000) +#define PJ_CC_VER_2 ((__ARMCC_VERSION%100000)/10000) +#define PJ_CC_VER_3 (__ARMCC_VERSION%10000) + +#ifdef __cplusplus +# define PJ_INLINE_SPECIFIER inline +#else +# define PJ_INLINE_SPECIFIER static __inline +#endif + +#define PJ_THREAD_FUNC +#define PJ_NORETURN +#define PJ_ATTR_NORETURN __attribute__ ((noreturn)) + +#define PJ_HAS_INT64 1 + +typedef long long pj_int64_t; +typedef unsigned long long pj_uint64_t; + +#define PJ_INT64_FMT "L" + +#define PJ_UNREACHED(x) + +#endif /* __PJ_COMPAT_CC_ARMCC_H__ */ + diff --git a/pjlib/include/pj/compat/cc_codew.h b/pjlib/include/pj/compat/cc_codew.h new file mode 100644 index 0000000..06638b8 --- /dev/null +++ b/pjlib/include/pj/compat/cc_codew.h @@ -0,0 +1,55 @@ +/* $Id: cc_codew.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 + * + * 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_COMPAT_CC_CODEW_H__ +#define __PJ_COMPAT_CC_CODEW_H__ + +/** + * @file cc_codew.h + * @brief Describes MetroWerks Code Warrior compiler specifics. + */ + +#ifndef __MWERKS__ +# error "This file is only for Code Warrior!" +#endif + +#define PJ_CC_NAME "codewarrior" +#define PJ_CC_VER_1 ((__MWERKS__ & 0xF000) >> 12) +#define PJ_CC_VER_2 ((__MWERKS__ & 0x0F00) >> 8) +#define PJ_CC_VER_3 ((__MWERKS__ & 0xFF)) + + +#define PJ_INLINE_SPECIFIER static inline +#define PJ_THREAD_FUNC +#define PJ_NORETURN +#define PJ_ATTR_NORETURN + +#define PJ_HAS_INT64 1 + +typedef long long pj_int64_t; +typedef unsigned long long pj_uint64_t; + +#define PJ_INT64(val) val##LL +#define PJ_UINT64(val) val##LLU +#define PJ_INT64_FMT "L" + +#define PJ_UNREACHED(x) + +#endif /* __PJ_COMPAT_CC_CODEW_H__ */ + diff --git a/pjlib/include/pj/compat/cc_gcc.h b/pjlib/include/pj/compat/cc_gcc.h new file mode 100644 index 0000000..db56bbc --- /dev/null +++ b/pjlib/include/pj/compat/cc_gcc.h @@ -0,0 +1,78 @@ +/* $Id: cc_gcc.h 3664 2011-07-19 03:42:28Z nanang $ */ +/* + * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono + * + * 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_COMPAT_CC_GCC_H__ +#define __PJ_COMPAT_CC_GCC_H__ + +/** + * @file cc_gcc.h + * @brief Describes GCC compiler specifics. + */ + +#ifndef __GNUC__ +# error "This file is only for gcc!" +#endif + +#define PJ_CC_NAME "gcc" +#define PJ_CC_VER_1 __GNUC__ +#define PJ_CC_VER_2 __GNUC_MINOR__ + +/* __GNUC_PATCHLEVEL__ doesn't exist in gcc-2.9x.x */ +#ifdef __GNUC_PATCHLEVEL__ +# define PJ_CC_VER_3 __GNUC_PATCHLEVEL__ +#else +# define PJ_CC_VER_3 0 +#endif + + + +#define PJ_THREAD_FUNC +#define PJ_NORETURN + +#define PJ_HAS_INT64 1 + +#ifdef __STRICT_ANSI__ + #include + typedef int64_t pj_int64_t; + typedef uint64_t pj_uint64_t; + #define PJ_INLINE_SPECIFIER static __inline + #define PJ_ATTR_NORETURN +#else + typedef long long pj_int64_t; + typedef unsigned long long pj_uint64_t; + #define PJ_INLINE_SPECIFIER static inline + #define PJ_ATTR_NORETURN __attribute__ ((noreturn)) +#endif + +#define PJ_INT64(val) val##LL +#define PJ_UINT64(val) val##LLU +#define PJ_INT64_FMT "L" + + +#ifdef __GLIBC__ +# define PJ_HAS_BZERO 1 +#endif + +#define PJ_UNREACHED(x) + +#define PJ_ALIGN_DATA(declaration, alignment) declaration __attribute__((aligned (alignment))) + + +#endif /* __PJ_COMPAT_CC_GCC_H__ */ + diff --git a/pjlib/include/pj/compat/cc_gcce.h b/pjlib/include/pj/compat/cc_gcce.h new file mode 100644 index 0000000..fae3e7e --- /dev/null +++ b/pjlib/include/pj/compat/cc_gcce.h @@ -0,0 +1,54 @@ +/* $Id: cc_gcce.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 + * + * 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_COMPAT_CC_GCCE_H__ +#define __PJ_COMPAT_CC_GCCE_H__ + +/** + * @file cc_gcce.h + * @brief Describes GCCE compiler specifics. + */ + +#ifndef __GCCE__ +# error "This file is only for gcce!" +#endif + +#define PJ_CC_NAME "gcce" +#define PJ_CC_VER_1 __GCCE__ +#define PJ_CC_VER_2 __GCCE_MINOR__ +#define PJ_CC_VER_3 __GCCE_PATCHLEVEL__ + + +#define PJ_INLINE_SPECIFIER static inline +#define PJ_THREAD_FUNC +#define PJ_NORETURN +#define PJ_ATTR_NORETURN __attribute__ ((noreturn)) + +#define PJ_HAS_INT64 1 + +typedef long long pj_int64_t; +typedef unsigned long long pj_uint64_t; + +#define PJ_INT64(val) val##LL +#define PJ_UINT64(val) val##LLU +#define PJ_INT64_FMT "L" + + +#endif /* __PJ_COMPAT_CC_GCCE_H__ */ + diff --git a/pjlib/include/pj/compat/cc_msvc.h b/pjlib/include/pj/compat/cc_msvc.h new file mode 100644 index 0000000..dbd0fde --- /dev/null +++ b/pjlib/include/pj/compat/cc_msvc.h @@ -0,0 +1,87 @@ +/* $Id: cc_msvc.h 3664 2011-07-19 03:42:28Z nanang $ */ +/* + * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono + * + * 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_COMPAT_CC_MSVC_H__ +#define __PJ_COMPAT_CC_MSVC_H__ + +/** + * @file cc_msvc.h + * @brief Describes Microsoft Visual C compiler specifics. + */ + +#ifndef _MSC_VER +# error "This header file is only for Visual C compiler!" +#endif + +#define PJ_CC_NAME "msvc" +#define PJ_CC_VER_1 (_MSC_VER/100) +#define PJ_CC_VER_2 (_MSC_VER%100) +#define PJ_CC_VER_3 0 + +/* Disable CRT deprecation warnings. */ +#if PJ_CC_VER_1 >= 8 && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif +#if PJ_CC_VER_1 >= 8 && !defined(_CRT_SECURE_NO_WARNINGS) +# define _CRT_SECURE_NO_WARNINGS + /* The above doesn't seem to work, at least on VS2005, so lets use + * this construct as well. + */ +# pragma warning(disable: 4996) +#endif + +#pragma warning(disable: 4127) // conditional expression is constant +#pragma warning(disable: 4611) // not wise to mix setjmp with C++ +#pragma warning(disable: 4514) // unref. inline function has been removed +#ifdef NDEBUG +# pragma warning(disable: 4702) // unreachable code +# pragma warning(disable: 4710) // function is not inlined. +# pragma warning(disable: 4711) // function selected for auto inline expansion +#endif + +#ifdef __cplusplus +# define PJ_INLINE_SPECIFIER inline +#else +# define PJ_INLINE_SPECIFIER static __inline +#endif + +#define PJ_EXPORT_DECL_SPECIFIER __declspec(dllexport) +#define PJ_EXPORT_DEF_SPECIFIER __declspec(dllexport) +#define PJ_IMPORT_DECL_SPECIFIER __declspec(dllimport) + +#define PJ_THREAD_FUNC +#define PJ_NORETURN __declspec(noreturn) +#define PJ_ATTR_NORETURN + +#define PJ_HAS_INT64 1 + +typedef __int64 pj_int64_t; +typedef unsigned __int64 pj_uint64_t; + +#define PJ_INT64(val) val##i64 +#define PJ_UINT64(val) val##ui64 +#define PJ_INT64_FMT "I64" + +#define PJ_UNREACHED(x) + +#define PJ_ALIGN_DATA(declaration, alignment) __declspec(align(alignment)) declaration + + +#endif /* __PJ_COMPAT_CC_MSVC_H__ */ + diff --git a/pjlib/include/pj/compat/cc_mwcc.h b/pjlib/include/pj/compat/cc_mwcc.h new file mode 100644 index 0000000..35248a2 --- /dev/null +++ b/pjlib/include/pj/compat/cc_mwcc.h @@ -0,0 +1,55 @@ +/* $Id: cc_mwcc.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 + * + * 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_COMPAT_CC_MWCC_H__ +#define __PJ_COMPAT_CC_MWCC_H__ + +/** + * @file cc_mwcc.h + * @brief Describes MWCC compiler specifics. + */ + +#ifndef __CW32__ +# error "This file is only for mwcc!" +#endif + +#define PJ_CC_NAME "mwcc32sym" +#define PJ_CC_VER_1 1 +#define PJ_CC_VER_2 0 +#define PJ_CC_VER_3 0 + + +#define PJ_INLINE_SPECIFIER static inline +#define PJ_THREAD_FUNC +#define PJ_NORETURN +#define PJ_ATTR_NORETURN __attribute__ ((noreturn)) + +#define PJ_HAS_INT64 1 + +typedef long long pj_int64_t; +typedef unsigned long long pj_uint64_t; + +#define PJ_INT64(val) val##LL +#define PJ_UINT64(val) val##LLU +#define PJ_INT64_FMT "L" + +#define PJ_UNREACHED(x) + +#endif /* __PJ_COMPAT_CC_MWCC_H__ */ + diff --git a/pjlib/include/pj/compat/ctype.h b/pjlib/include/pj/compat/ctype.h new file mode 100644 index 0000000..a79a1a0 --- /dev/null +++ b/pjlib/include/pj/compat/ctype.h @@ -0,0 +1,49 @@ +/* $Id: ctype.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 + * + * 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_COMPAT_CTYPE_H__ +#define __PJ_COMPAT_CTYPE_H__ + +/** + * @file ctype.h + * @brief Provides ctype function family. + */ + +#if defined(PJ_HAS_CTYPE_H) && PJ_HAS_CTYPE_H != 0 +# include +#else +# define isalnum(c) (isalpha(c) || isdigit(c)) +# define isalpha(c) (islower(c) || isupper(c)) +# define isascii(c) (((unsigned char)(c))<=0x7f) +# define isdigit(c) ((c)>='0' && (c)<='9') +# define isspace(c) ((c)==' ' || (c)=='\t' ||\ + (c)=='\n' || (c)=='\r' || (c)=='\v') +# define islower(c) ((c)>='a' && (c)<='z') +# define isupper(c) ((c)>='A' && (c)<='Z') +# define isxdigit(c) (isdigit(c) || (tolower(c)>='a'&&tolower(c)<='f')) +# define tolower(c) (((c) >= 'A' && (c) <= 'Z') ? (c)+('a'-'A') : (c)) +# define toupper(c) (((c) >= 'a' && (c) <= 'z') ? (c)-('a'-'A') : (c)) +#endif + +#ifndef isblank +# define isblank(c) (c==' ' || c=='\t') +#endif + + +#endif /* __PJ_COMPAT_CTYPE_H__ */ diff --git a/pjlib/include/pj/compat/errno.h b/pjlib/include/pj/compat/errno.h new file mode 100644 index 0000000..c41145c --- /dev/null +++ b/pjlib/include/pj/compat/errno.h @@ -0,0 +1,44 @@ +/* $Id: errno.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 + * + * 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_COMPAT_ERRNO_H__ +#define __PJ_COMPAT_ERRNO_H__ + +#if defined(PJ_WIN32) && PJ_WIN32 != 0 || \ + defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE != 0 + + typedef unsigned long pj_os_err_type; +# define pj_get_native_os_error() GetLastError() +# define pj_get_native_netos_error() WSAGetLastError() + +#elif defined(PJ_HAS_ERRNO_VAR) && PJ_HAS_ERRNO_VAR!= 0 + + typedef int pj_os_err_type; +# define pj_get_native_os_error() (errno) +# define pj_get_native_netos_error() (errno) + +#else + +# error "Please define how to get errno for this platform here!" + +#endif + + +#endif /* __PJ_COMPAT_ERRNO_H__ */ + diff --git a/pjlib/include/pj/compat/high_precision.h b/pjlib/include/pj/compat/high_precision.h new file mode 100644 index 0000000..277389f --- /dev/null +++ b/pjlib/include/pj/compat/high_precision.h @@ -0,0 +1,103 @@ +/* $Id: high_precision.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 + * + * 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_COMPAT_HIGH_PRECISION_H__ +#define __PJ_COMPAT_HIGH_PRECISION_H__ + + +#if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT != 0 + /* + * The first choice for high precision math is to use double. + */ +# include + typedef double pj_highprec_t; + +# define PJ_HIGHPREC_VALUE_IS_ZERO(a) (a==0) +# define pj_highprec_mod(a,b) (a=fmod(a,b)) + +#elif defined(PJ_LINUX_KERNEL) && PJ_LINUX_KERNEL != 0 + +# include + + typedef pj_int64_t pj_highprec_t; + +# define pj_highprec_div(a1,a2) do_div(a1,a2) +# define pj_highprec_mod(a1,a2) (a1=do_mod(a1, a2)) + + PJ_INLINE(pj_int64_t) do_mod( pj_int64_t a1, pj_int64_t a2) + { + return do_div(a1,a2); + } + + +#elif defined(PJ_HAS_INT64) && PJ_HAS_INT64 != 0 + /* + * Next choice is to use 64-bit arithmatics. + */ + typedef pj_int64_t pj_highprec_t; + +#else +# warning "High precision math is not available" + + /* + * Last, fallback to 32-bit arithmetics. + */ + typedef pj_int32_t pj_highprec_t; + +#endif + +/** + * @def pj_highprec_mul + * pj_highprec_mul(a1, a2) - High Precision Multiplication + * Multiply a1 and a2, and store the result in a1. + */ +#ifndef pj_highprec_mul +# define pj_highprec_mul(a1,a2) (a1 = a1 * a2) +#endif + +/** + * @def pj_highprec_div + * pj_highprec_div(a1, a2) - High Precision Division + * Divide a2 from a1, and store the result in a1. + */ +#ifndef pj_highprec_div +# define pj_highprec_div(a1,a2) (a1 = a1 / a2) +#endif + +/** + * @def pj_highprec_mod + * pj_highprec_mod(a1, a2) - High Precision Modulus + * Get the modulus a2 from a1, and store the result in a1. + */ +#ifndef pj_highprec_mod +# define pj_highprec_mod(a1,a2) (a1 = a1 % a2) +#endif + + +/** + * @def PJ_HIGHPREC_VALUE_IS_ZERO(a) + * Test if the specified high precision value is zero. + */ +#ifndef PJ_HIGHPREC_VALUE_IS_ZERO +# define PJ_HIGHPREC_VALUE_IS_ZERO(a) (a==0) +#endif + + +#endif /* __PJ_COMPAT_HIGH_PRECISION_H__ */ + diff --git a/pjlib/include/pj/compat/m_alpha.h b/pjlib/include/pj/compat/m_alpha.h new file mode 100644 index 0000000..fa22f54 --- /dev/null +++ b/pjlib/include/pj/compat/m_alpha.h @@ -0,0 +1,36 @@ +/* $Id: m_alpha.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 + * + * 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_COMPAT_M_ALPHA_H__ +#define __PJ_COMPAT_M_ALPHA_H__ + +/** + * @file m_alpha.h + * @brief Describes Alpha processor family specifics. + */ + +#define PJ_M_NAME "alpha" + +#define PJ_HAS_PENTIUM 0 +#define PJ_IS_LITTLE_ENDIAN 1 +#define PJ_IS_BIG_ENDIAN 0 + + +#endif /* __PJ_COMPAT_M_ALPHA_H__ */ + diff --git a/pjlib/include/pj/compat/m_armv4.h b/pjlib/include/pj/compat/m_armv4.h new file mode 100644 index 0000000..74d2c84 --- /dev/null +++ b/pjlib/include/pj/compat/m_armv4.h @@ -0,0 +1,39 @@ +/* $Id: m_armv4.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 + * + * 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_COMPAT_M_ARMV4_H__ +#define __PJ_COMPAT_M_ARMV4_H__ + +/** + * @file m_armv4.h + * @brief Describes ARM family processor specifics. + */ + +/* + * This file covers PJ_M_ARMV4 etc. + */ + +#define PJ_M_NAME "armv4" + +#define PJ_HAS_PENTIUM 0 +#define PJ_IS_LITTLE_ENDIAN 1 +#define PJ_IS_BIG_ENDIAN 0 + + +#endif /* __PJ_COMPAT_M_ARMV4_H__ */ diff --git a/pjlib/include/pj/compat/m_auto.h.in b/pjlib/include/pj/compat/m_auto.h.in new file mode 100644 index 0000000..48763ea --- /dev/null +++ b/pjlib/include/pj/compat/m_auto.h.in @@ -0,0 +1,60 @@ +/* $Id: m_auto.h.in 3295 2010-08-25 12:51:29Z bennylp $ */ +/* + * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono + * + * 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_COMPAT_M_AUTO_H__ +#define __PJ_COMPAT_M_AUTO_H__ + +/** + * @file m_auto.h + * @brief Automatically generated process definition file. + */ + +/* Machine name, filled in by autoconf script */ +#undef PJ_M_NAME + +/* Endianness. It's reported on pjsip list on 09/02/13 that autoconf + * endianness detection failed for universal build, so special case + * for it here. Thanks Ruud Klaver for the fix. + */ +#ifdef PJ_DARWINOS +# ifdef __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else + /* Endianness, as detected by autoconf */ +# undef WORDS_BIGENDIAN +#endif + +#ifdef WORDS_BIGENDIAN +# define PJ_IS_LITTLE_ENDIAN 0 +# define PJ_IS_BIG_ENDIAN 1 +#else +# define PJ_IS_LITTLE_ENDIAN 1 +# define PJ_IS_BIG_ENDIAN 0 +#endif + + +/* Specify if floating point is present/desired */ +#undef PJ_HAS_FLOATING_POINT + +/* Deprecated */ +#define PJ_HAS_PENTIUM 0 + +#endif /* __PJ_COMPAT_M_AUTO_H__ */ + diff --git a/pjlib/include/pj/compat/m_i386.h b/pjlib/include/pj/compat/m_i386.h new file mode 100644 index 0000000..7967d6f --- /dev/null +++ b/pjlib/include/pj/compat/m_i386.h @@ -0,0 +1,35 @@ +/* $Id: m_i386.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 + * + * 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_COMPAT_M_i386_H__ +#define __PJ_COMPAT_M_i386_H__ + +/** + * @file m_i386.h + * @brief Describes Intel i386 family processor specifics. + */ + +#define PJ_M_NAME "i386" + +#define PJ_HAS_PENTIUM 1 +#define PJ_IS_LITTLE_ENDIAN 1 +#define PJ_IS_BIG_ENDIAN 0 + + +#endif /* __PJ_COMPAT_M_i386_H__ */ diff --git a/pjlib/include/pj/compat/m_m68k.h b/pjlib/include/pj/compat/m_m68k.h new file mode 100644 index 0000000..e0469de --- /dev/null +++ b/pjlib/include/pj/compat/m_m68k.h @@ -0,0 +1,35 @@ +/* $Id: m_m68k.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 + * + * 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_COMPAT_M_M68K_H__ +#define __PJ_COMPAT_M_M68K_H__ + +/** + * @file m_m68k.h + * @brief Describes Motorola m68k family processor specifics. + */ + +#define PJ_M_NAME "m68k" + +#define PJ_HAS_PENTIUM 0 +#define PJ_IS_LITTLE_ENDIAN 1 +#define PJ_IS_BIG_ENDIAN 0 + + +#endif /* __PJ_COMPAT_M_M68K_H__ */ diff --git a/pjlib/include/pj/compat/m_powerpc.h b/pjlib/include/pj/compat/m_powerpc.h new file mode 100644 index 0000000..03b2bd8 --- /dev/null +++ b/pjlib/include/pj/compat/m_powerpc.h @@ -0,0 +1,36 @@ +/* $Id: m_powerpc.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 + * + * 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_COMPAT_M_POWERPC_H__ +#define __PJ_COMPAT_M_POWERPC_H__ + +/** + * @file m_ppc.h + * @brief Describes PowerPC family processor specifics. + */ + +#define PJ_M_NAME "powerpc" + +#define PJ_HAS_PENTIUM 0 +#define PJ_IS_LITTLE_ENDIAN 0 +#define PJ_IS_BIG_ENDIAN 1 + + +#endif /* __PJ_COMPAT_M_POWERPC_H__ */ + diff --git a/pjlib/include/pj/compat/m_sparc.h b/pjlib/include/pj/compat/m_sparc.h new file mode 100644 index 0000000..3539ea4 --- /dev/null +++ b/pjlib/include/pj/compat/m_sparc.h @@ -0,0 +1,35 @@ +/* $Id: m_sparc.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 + * + * 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_COMPAT_M_SPARC_H__ +#define __PJ_COMPAT_M_SPARC_H__ + +/** + * @file m_sparc.h + * @brief Describes SPARC family processor specifics. + */ + +#define PJ_M_NAME "sparc" + +#define PJ_HAS_PENTIUM 0 +#define PJ_IS_LITTLE_ENDIAN 0 +#define PJ_IS_BIG_ENDIAN 1 + + +#endif /* __PJ_COMPAT_M_SPARC_H__ */ diff --git a/pjlib/include/pj/compat/m_x86_64.h b/pjlib/include/pj/compat/m_x86_64.h new file mode 100644 index 0000000..29795ef --- /dev/null +++ b/pjlib/include/pj/compat/m_x86_64.h @@ -0,0 +1,36 @@ +/* $Id: m_x86_64.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 + * + * 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_COMPAT_M_x86_64_H__ +#define __PJ_COMPAT_M_x86_64_H__ + +/** + * @file m_i386.h + * @brief Describes 64bit x86 Intel/AMD family processor specifics. + */ + +#define PJ_M_NAME "x86_64" + +#define PJ_HAS_PENTIUM 1 +#define PJ_IS_LITTLE_ENDIAN 1 +#define PJ_IS_BIG_ENDIAN 0 + + +#endif /* __PJ_COMPAT_M_x86_64_H__ */ + diff --git a/pjlib/include/pj/compat/malloc.h b/pjlib/include/pj/compat/malloc.h new file mode 100644 index 0000000..94c1431 --- /dev/null +++ b/pjlib/include/pj/compat/malloc.h @@ -0,0 +1,34 @@ +/* $Id: malloc.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 + * + * 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_COMPAT_MALLOC_H__ +#define __PJ_COMPAT_MALLOC_H__ + +/** + * @file malloc.h + * @brief Provides malloc() and free() functions. + */ + +#if defined(PJ_HAS_MALLOC_H) && PJ_HAS_MALLOC_H != 0 +# include +#elif defined(PJ_HAS_STDLIB_H) && PJ_HAS_STDLIB_H != 0 +# include +#endif + +#endif /* __PJ_COMPAT_MALLOC_H__ */ diff --git a/pjlib/include/pj/compat/os_auto.h.in b/pjlib/include/pj/compat/os_auto.h.in new file mode 100644 index 0000000..18df2bf --- /dev/null +++ b/pjlib/include/pj/compat/os_auto.h.in @@ -0,0 +1,212 @@ +/* $Id: os_auto.h.in 3841 2011-10-24 09:28:13Z ming $ */ +/* + * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono + * + * 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_COMPAT_OS_AUTO_H__ +#define __PJ_COMPAT_OS_AUTO_H__ + +/** + * @file os_auto.h + * @brief Describes operating system specifics (automatically detected by + * autoconf) + */ + +/* Canonical OS name */ +#undef PJ_OS_NAME + +/* Legacy macros */ +#undef PJ_WIN32 +#undef PJ_WIN32_WINNT +#undef WIN32_LEAN_AND_MEAN +#undef PJ_DARWINOS +#undef PJ_LINUX +#undef PJ_RTEMS +#undef PJ_SUNOS + +#if defined(PJ_WIN32_WINNT) && !defined(_WIN32_WINNT) +# define _WIN32_WINNT PJ_WIN32_WINNT +#endif + +/* Headers availability */ +#undef PJ_HAS_ARPA_INET_H +#undef PJ_HAS_ASSERT_H +#undef PJ_HAS_CTYPE_H +#undef PJ_HAS_ERRNO_H +#undef PJ_HAS_FCNTL_H +#undef PJ_HAS_LIMITS_H +#undef PJ_HAS_LINUX_SOCKET_H +#undef PJ_HAS_MALLOC_H +#undef PJ_HAS_NETDB_H +#undef PJ_HAS_NETINET_IN_SYSTM_H +#undef PJ_HAS_NETINET_IN_H +#undef PJ_HAS_NETINET_IP_H +#undef PJ_HAS_NETINET_TCP_H +#undef PJ_HAS_NET_IF_H +#undef PJ_HAS_IFADDRS_H +#undef PJ_HAS_SEMAPHORE_H +#undef PJ_HAS_SETJMP_H +#undef PJ_HAS_STDARG_H +#undef PJ_HAS_STDDEF_H +#undef PJ_HAS_STDIO_H +#undef PJ_HAS_STDINT_H +#undef PJ_HAS_STDLIB_H +#undef PJ_HAS_STRING_H +#undef PJ_HAS_SYS_IOCTL_H +#undef PJ_HAS_SYS_SELECT_H +#undef PJ_HAS_SYS_SOCKET_H +#undef PJ_HAS_SYS_TIME_H +#undef PJ_HAS_SYS_TIMEB_H +#undef PJ_HAS_SYS_TYPES_H +#undef PJ_HAS_SYS_FILIO_H +#undef PJ_HAS_SYS_SOCKIO_H +#undef PJ_HAS_SYS_UTSNAME_H +#undef PJ_HAS_TIME_H +#undef PJ_HAS_UNISTD_H + +#undef PJ_HAS_MSWSOCK_H +#undef PJ_HAS_WINSOCK_H +#undef PJ_HAS_WINSOCK2_H +#undef PJ_HAS_WS2TCPIP_H + +#undef PJ_SOCK_HAS_INET_ATON +#undef PJ_SOCK_HAS_INET_PTON +#undef PJ_SOCK_HAS_INET_NTOP +#undef PJ_SOCK_HAS_GETADDRINFO + +/* On these OSes, semaphore feature depends on semaphore.h */ +#if defined(PJ_HAS_SEMAPHORE_H) && PJ_HAS_SEMAPHORE_H!=0 +# define PJ_HAS_SEMAPHORE 1 +#elif defined(PJ_WIN32) && PJ_WIN32!=0 +# define PJ_HAS_SEMAPHORE 1 +#else +# define PJ_HAS_SEMAPHORE 0 +#endif + +/* Do we have pthread_mutexattr_settype()? */ +#undef PJ_HAS_PTHREAD_MUTEXATTR_SETTYPE + +/* Does pthread_mutexattr_t has "recursive" member? */ +#undef PJ_PTHREAD_MUTEXATTR_T_HAS_RECURSIVE + +/* Set 1 if native sockaddr_in has sin_len member. + * Default: 0 + */ +#undef PJ_SOCKADDR_HAS_LEN + +/* Does the OS have socklen_t? */ +#undef PJ_HAS_SOCKLEN_T + +#if !defined(socklen_t) && (!defined(PJ_HAS_SOCKLEN_T) || PJ_HAS_SOCKLEN_T==0) +# define PJ_HAS_SOCKLEN_T 1 + typedef int socklen_t; +#endif + +/** + * If this macro is set, it tells select I/O Queue that select() needs to + * be given correct value of nfds (i.e. largest fd + 1). This requires + * select ioqueue to re-scan the descriptors on each registration and + * unregistration. + * If this macro is not set, then ioqueue will always give FD_SETSIZE for + * nfds argument when calling select(). + * + * Default: 0 + */ +#undef PJ_SELECT_NEEDS_NFDS + +/* Is errno a good way to retrieve OS errors? + */ +#undef PJ_HAS_ERRNO_VAR + +/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return + * the status of non-blocking connect() operation. + */ +#undef PJ_HAS_SO_ERROR + +/* This value specifies the value set in errno by the OS when a non-blocking + * socket recv() can not return immediate daata. + */ +#undef PJ_BLOCKING_ERROR_VAL + +/* This value specifies the value set in errno by the OS when a non-blocking + * socket connect() can not get connected immediately. + */ +#undef PJ_BLOCKING_CONNECT_ERROR_VAL + +/* Default threading is enabled, unless it's overridden. */ +#ifndef PJ_HAS_THREADS +# define PJ_HAS_THREADS (1) +#endif + +/* Do we need high resolution timer? */ +#undef PJ_HAS_HIGH_RES_TIMER + +/* Is malloc() available? */ +#undef PJ_HAS_MALLOC + +#ifndef PJ_OS_HAS_CHECK_STACK +# define PJ_OS_HAS_CHECK_STACK 0 +#endif + +/* Unicode? */ +#undef PJ_NATIVE_STRING_IS_UNICODE + +/* Pool alignment in bytes */ +#undef PJ_POOL_ALIGNMENT + +/* The type of atomic variable value: */ +#undef PJ_ATOMIC_VALUE_TYPE + +#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 +# include "TargetConditionals.h" +# if TARGET_OS_IPHONE +# include "Availability.h" + /* Use CFHost API for pj_getaddrinfo() (see ticket #1246) */ +# define PJ_GETADDRINFO_USE_CFHOST 1 + /* Disable local host resolution in pj_gethostip() (see ticket #1342) */ +# define PJ_GETHOSTIP_DISABLE_LOCAL_RESOLUTION 1 +# ifdef __IPHONE_4_0 + /* Is multitasking support available? (see ticket #1107) */ +# define PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT 1 + /* Enable activesock TCP background mode support */ +# define PJ_ACTIVESOCK_TCP_IPHONE_OS_BG 1 +# endif +# endif +#endif + +/* If 1, use Read/Write mutex emulation for platforms that don't support it */ +#undef PJ_EMULATE_RWMUTEX + +/* If 1, pj_thread_create() should enforce the stack size when creating + * threads. + * Default: 0 (let OS decide the thread's stack size). + */ +#undef PJ_THREAD_SET_STACK_SIZE + +/* If 1, pj_thread_create() should allocate stack from the pool supplied. + * Default: 0 (let OS allocate memory for thread's stack). + */ +#undef PJ_THREAD_ALLOCATE_STACK + +/* SSL socket availability. */ +#ifndef PJ_HAS_SSL_SOCK +#undef PJ_HAS_SSL_SOCK +#endif + + +#endif /* __PJ_COMPAT_OS_AUTO_H__ */ + diff --git a/pjlib/include/pj/compat/os_darwinos.h b/pjlib/include/pj/compat/os_darwinos.h new file mode 100644 index 0000000..a01dd16 --- /dev/null +++ b/pjlib/include/pj/compat/os_darwinos.h @@ -0,0 +1,145 @@ +/* $Id: os_darwinos.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 + * + * 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_COMPAT_OS_DARWINOS_H__ +#define __PJ_COMPAT_OS_DARWINOS_H__ + +/** + * @file os_darwinos.h + * @brief Describes Darwin/MacOSX operating system specifics. + */ + +#define PJ_OS_NAME "darwin" + +#define PJ_HAS_ARPA_INET_H 1 +#define PJ_HAS_ASSERT_H 1 +#define PJ_HAS_CTYPE_H 1 +#define PJ_HAS_ERRNO_H 1 +#define PJ_HAS_LINUX_SOCKET_H 0 +#define PJ_HAS_MALLOC_H 0 +#define PJ_HAS_NETDB_H 1 +#define PJ_HAS_NETINET_IN_H 1 +#define PJ_HAS_NETINET_TCP_H 1 +#define PJ_HAS_SETJMP_H 1 +#define PJ_HAS_STDARG_H 1 +#define PJ_HAS_STDDEF_H 1 +#define PJ_HAS_STDIO_H 1 +#define PJ_HAS_STDLIB_H 1 +#define PJ_HAS_STRING_H 1 +#define PJ_HAS_SYS_IOCTL_H 1 +#define PJ_HAS_SYS_SELECT_H 1 +#define PJ_HAS_SYS_SOCKET_H 1 +#define PJ_HAS_SYS_TIME_H 1 +#define PJ_HAS_SYS_TIMEB_H 1 +#define PJ_HAS_SYS_TYPES_H 1 +#define PJ_HAS_TIME_H 1 +#define PJ_HAS_UNISTD_H 1 + +#define PJ_HAS_MSWSOCK_H 0 +#define PJ_HAS_WINSOCK_H 0 +#define PJ_HAS_WINSOCK2_H 0 + +/* Is errno a good way to retrieve OS errors? + */ +#define PJ_HAS_ERRNO_VAR 1 + +/* Has inet_aton() ? + */ +#define PJ_SOCK_HAS_INET_ATON 1 + +/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return + * the status of non-blocking connect() operation. + */ +#define PJ_HAS_SO_ERROR 1 + +/* This value specifies the value set in errno by the OS when a non-blocking + * socket recv() can not return immediate daata. + */ +#define PJ_BLOCKING_ERROR_VAL EWOULDBLOCK + +/* This value specifies the value set in errno by the OS when a non-blocking + * socket connect() can not get connected immediately. + */ +#define PJ_BLOCKING_CONNECT_ERROR_VAL EINPROGRESS + +/* Default threading is enabled, unless it's overridden. */ +#ifndef PJ_HAS_THREADS +# define PJ_HAS_THREADS (1) +#endif + +#define PJ_HAS_HIGH_RES_TIMER 1 +#define PJ_HAS_MALLOC 1 +#ifndef PJ_OS_HAS_CHECK_STACK +# define PJ_OS_HAS_CHECK_STACK 0 +#endif +#define PJ_NATIVE_STRING_IS_UNICODE 0 + +#define PJ_ATOMIC_VALUE_TYPE long + +/* + * Socket related + */ +typedef int socklen_t; + +/* Set 1 if native sockaddr_in has sin_len member. + * Default: 0 + */ +#define PJ_SOCKADDR_HAS_LEN 1 + +/* + * gcc complains that it can not use precompiled header because + * the value of FD_SETSIZE that we declare in pj/config.h is + * different than the value in /usr/include/sys/types.h. + * + * This changes the default value for Darwin. + */ +#define PJ_IOQUEUE_MAX_HANDLES 1024 + +/** + * If this macro is set, it tells select I/O Queue that select() needs to + * be given correct value of nfds (i.e. largest fd + 1). This requires + * select ioqueue to re-scan the descriptors on each registration and + * unregistration. + * If this macro is not set, then ioqueue will always give FD_SETSIZE for + * nfds argument when calling select(). + * + * Default: 0 + */ +#define PJ_SELECT_NEEDS_NFDS 0 + +/* If 1, use Read/Write mutex emulation for platforms that don't support it */ +#define PJ_EMULATE_RWMUTEX 0 + +/* If 1, pj_thread_create() should enforce the stack size when creating + * threads. + * Default: 0 (let OS decide the thread's stack size). + */ +#define PJ_THREAD_SET_STACK_SIZE 0 + +/* If 1, pj_thread_create() should allocate stack from the pool supplied. + * Default: 0 (let OS allocate memory for thread's stack). + */ +#define PJ_THREAD_ALLOCATE_STACK 0 + +/* Oh well.. MacOS 10.2 doesn't have socklen_t, but 10.4 has! */ +#define PJ_HAS_SOCKLEN_T 0 + + +#endif /* __PJ_COMPAT_OS_DARWINOS_H__ */ + diff --git a/pjlib/include/pj/compat/os_linux.h b/pjlib/include/pj/compat/os_linux.h new file mode 100644 index 0000000..820d744 --- /dev/null +++ b/pjlib/include/pj/compat/os_linux.h @@ -0,0 +1,129 @@ +/* $Id: os_linux.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 + * + * 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_COMPAT_OS_LINUX_H__ +#define __PJ_COMPAT_OS_LINUX_H__ + +/** + * @file os_linux.h + * @brief Describes Linux operating system specifics. + */ + +#define PJ_OS_NAME "linux" + +#define PJ_HAS_ARPA_INET_H 1 +#define PJ_HAS_ASSERT_H 1 +#define PJ_HAS_CTYPE_H 1 +#define PJ_HAS_ERRNO_H 1 +#define PJ_HAS_LINUX_SOCKET_H 0 +#define PJ_HAS_MALLOC_H 1 +#define PJ_HAS_NETDB_H 1 +#define PJ_HAS_NETINET_IN_H 1 +#define PJ_HAS_SETJMP_H 1 +#define PJ_HAS_STDARG_H 1 +#define PJ_HAS_STDDEF_H 1 +#define PJ_HAS_STDIO_H 1 +#define PJ_HAS_STDLIB_H 1 +#define PJ_HAS_STRING_H 1 +#define PJ_HAS_SYS_IOCTL_H 1 +#define PJ_HAS_SYS_SELECT_H 1 +#define PJ_HAS_SYS_SOCKET_H 1 +#define PJ_HAS_SYS_TIME_H 1 +#define PJ_HAS_SYS_TIMEB_H 1 +#define PJ_HAS_SYS_TYPES_H 1 +#define PJ_HAS_TIME_H 1 +#define PJ_HAS_UNISTD_H 1 +#define PJ_HAS_SEMAPHORE_H 1 + +#define PJ_HAS_MSWSOCK_H 0 +#define PJ_HAS_WINSOCK_H 0 +#define PJ_HAS_WINSOCK2_H 0 + +#define PJ_SOCK_HAS_INET_ATON 1 + +/* Set 1 if native sockaddr_in has sin_len member. + * Default: 0 + */ +#define PJ_SOCKADDR_HAS_LEN 0 + +/** + * If this macro is set, it tells select I/O Queue that select() needs to + * be given correct value of nfds (i.e. largest fd + 1). This requires + * select ioqueue to re-scan the descriptors on each registration and + * unregistration. + * If this macro is not set, then ioqueue will always give FD_SETSIZE for + * nfds argument when calling select(). + * + * Default: 0 + */ +#define PJ_SELECT_NEEDS_NFDS 0 + +/* Is errno a good way to retrieve OS errors? + */ +#define PJ_HAS_ERRNO_VAR 1 + +/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return + * the status of non-blocking connect() operation. + */ +#define PJ_HAS_SO_ERROR 1 + +/* This value specifies the value set in errno by the OS when a non-blocking + * socket recv() can not return immediate daata. + */ +#define PJ_BLOCKING_ERROR_VAL EAGAIN + +/* This value specifies the value set in errno by the OS when a non-blocking + * socket connect() can not get connected immediately. + */ +#define PJ_BLOCKING_CONNECT_ERROR_VAL EINPROGRESS + +/* Default threading is enabled, unless it's overridden. */ +#ifndef PJ_HAS_THREADS +# define PJ_HAS_THREADS (1) +#endif + +#define PJ_HAS_HIGH_RES_TIMER 1 +#define PJ_HAS_MALLOC 1 +#ifndef PJ_OS_HAS_CHECK_STACK +# define PJ_OS_HAS_CHECK_STACK 0 +#endif +#define PJ_NATIVE_STRING_IS_UNICODE 0 + +#define PJ_ATOMIC_VALUE_TYPE long + +/* If 1, use Read/Write mutex emulation for platforms that don't support it */ +#define PJ_EMULATE_RWMUTEX 0 + +/* If 1, pj_thread_create() should enforce the stack size when creating + * threads. + * Default: 0 (let OS decide the thread's stack size). + */ +#define PJ_THREAD_SET_STACK_SIZE 0 + +/* If 1, pj_thread_create() should allocate stack from the pool supplied. + * Default: 0 (let OS allocate memory for thread's stack). + */ +#define PJ_THREAD_ALLOCATE_STACK 0 + +/* Linux has socklen_t */ +#define PJ_HAS_SOCKLEN_T 1 + + +#endif /* __PJ_COMPAT_OS_LINUX_H__ */ + diff --git a/pjlib/include/pj/compat/os_linux_kernel.h b/pjlib/include/pj/compat/os_linux_kernel.h new file mode 100644 index 0000000..1894160 --- /dev/null +++ b/pjlib/include/pj/compat/os_linux_kernel.h @@ -0,0 +1,149 @@ +/* $Id: os_linux_kernel.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 + * + * 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_COMPAT_OS_LINUX_KERNEL_H__ +#define __PJ_COMPAT_OS_LINUX_KERNEL_H__ + +/** + * @file os_linux.h + * @brief Describes Linux operating system specifics. + */ + +#define PJ_OS_NAME "linux-module" + +#define PJ_HAS_ARPA_INET_H 0 +#define PJ_HAS_ASSERT_H 0 +#define PJ_HAS_CTYPE_H 0 +#define PJ_HAS_ERRNO_H 0 +#define PJ_HAS_LINUX_SOCKET_H 1 +#define PJ_HAS_MALLOC_H 0 +#define PJ_HAS_NETDB_H 0 +#define PJ_HAS_NETINET_IN_H 0 +#define PJ_HAS_SETJMP_H 0 +#define PJ_HAS_STDARG_H 1 +#define PJ_HAS_STDDEF_H 0 +#define PJ_HAS_STDIO_H 0 +#define PJ_HAS_STDLIB_H 0 +#define PJ_HAS_STRING_H 0 +#define PJ_HAS_SYS_IOCTL_H 0 +#define PJ_HAS_SYS_SELECT_H 0 +#define PJ_HAS_SYS_SOCKET_H 0 +#define PJ_HAS_SYS_TIME_H 0 +#define PJ_HAS_SYS_TIMEB_H 0 +#define PJ_HAS_SYS_TYPES_H 0 +#define PJ_HAS_TIME_H 0 +#define PJ_HAS_UNISTD_H 0 + +#define PJ_HAS_MSWSOCK_H 0 +#define PJ_HAS_WINSOCK_H 0 +#define PJ_HAS_WINSOCK2_H 0 + +#define PJ_SOCK_HAS_INET_ATON 0 + +/* Set 1 if native sockaddr_in has sin_len member. + * Default: 0 + */ +#define PJ_SOCKADDR_HAS_LEN 0 + +/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return + * the status of non-blocking connect() operation. + */ +#define PJ_HAS_SO_ERROR 1 + +/** + * If this macro is set, it tells select I/O Queue that select() needs to + * be given correct value of nfds (i.e. largest fd + 1). This requires + * select ioqueue to re-scan the descriptors on each registration and + * unregistration. + * If this macro is not set, then ioqueue will always give FD_SETSIZE for + * nfds argument when calling select(). + * + * Default: 0 + */ +#define PJ_SELECT_NEEDS_NFDS 0 + +/* Is errno a good way to retrieve OS errors? + * (probably no for linux kernel) + * If you answer no here, you'll need to tell pjlib how to get OS + * error (a compile error will tell you exactly where) + */ +#define PJ_HAS_ERRNO_VAR 0 + +/* This value specifies the value set in errno by the OS when a non-blocking + * socket recv() can not return immediate daata. + */ +#define PJ_BLOCKING_ERROR_VAL EAGAIN + +/* This value specifies the value set in errno by the OS when a non-blocking + * socket connect() can not get connected immediately. + */ +#define PJ_BLOCKING_CONNECT_ERROR_VAL EINPROGRESS + +#ifndef PJ_HAS_THREADS +# define PJ_HAS_THREADS (1) +#endif + + +/* + * Declare __FD_SETSIZE now before including . + */ +#define __FD_SETSIZE PJ_IOQUEUE_MAX_HANDLES + +#define NULL ((void*)0) + +#include /* Needed by all modules */ +#include /* Needed for KERN_INFO */ + +#define __PJ_EXPORT_SYMBOL(a) EXPORT_SYMBOL(a); + +/* + * Override features. + */ +#define PJ_HAS_FLOATING_POINT 0 +#define PJ_HAS_MALLOC 0 +#define PJ_HAS_SEMAPHORE 0 +#define PJ_HAS_EVENT_OBJ 0 +#define PJ_HAS_HIGH_RES_TIMER 1 +#ifndef PJ_OS_HAS_CHECK_STACK +# define PJ_OS_HAS_CHECK_STACK 0 +#endif +#define PJ_TERM_HAS_COLOR 0 +#define PJ_NATIVE_STRING_IS_UNICODE 0 + +#define PJ_ATOMIC_VALUE_TYPE int +#define PJ_THREAD_DESC_SIZE 128 + +/* If 1, use Read/Write mutex emulation for platforms that don't support it */ +#define PJ_EMULATE_RWMUTEX 0 + +/* If 1, pj_thread_create() should enforce the stack size when creating + * threads. + * Default: 0 (let OS decide the thread's stack size). + */ +#define PJ_THREAD_SET_STACK_SIZE 0 + +/* If 1, pj_thread_create() should allocate stack from the pool supplied. + * Default: 0 (let OS allocate memory for thread's stack). + */ +#define PJ_THREAD_ALLOCATE_STACK 0 + + + +#endif /* __PJ_COMPAT_OS_LINUX_KERNEL_H__ */ + diff --git a/pjlib/include/pj/compat/os_palmos.h b/pjlib/include/pj/compat/os_palmos.h new file mode 100644 index 0000000..1fd4d86 --- /dev/null +++ b/pjlib/include/pj/compat/os_palmos.h @@ -0,0 +1,119 @@ +/* $Id: os_palmos.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 + * + * 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_COMPAT_OS_PALMOS_H__ +#define __PJ_COMPAT_OS_PALMOS_H__ + +/** + * @file os_palmos.h + * @brief Describes PalmOS operating system specifics. + */ + +#define PJ_OS_NAME "palmos" + +#define PJ_HAS_ARPA_INET_H 0 +#define PJ_HAS_ASSERT_H 1 +#define PJ_HAS_CTYPE_H 1 +#define PJ_HAS_ERRNO_H 0 +#define PJ_HAS_MALLOC_H 1 +#define PJ_HAS_NETDB_H 0 +#define PJ_HAS_NETINET_IN_H 0 +#define PJ_HAS_SETJMP_H 1 +#define PJ_HAS_STDARG_H 1 +#define PJ_HAS_STDDEF_H 1 +#define PJ_HAS_STDIO_H 1 +#define PJ_HAS_STDLIB_H 1 +#define PJ_HAS_STRING_H 1 +#define PJ_HAS_SYS_IOCTL_H 0 +#define PJ_HAS_SYS_SELECT_H 0 +#define PJ_HAS_SYS_SOCKET_H 0 +#define PJ_HAS_SYS_TIMEB_H 0 +#define PJ_HAS_SYS_TYPES_H 1 +#define PJ_HAS_TIME_H 1 +#define PJ_HAS_UNISTD_H 0 + +#define PJ_HAS_MSWSOCK_H 0 +#define PJ_HAS_WINSOCK_H 0 +#define PJ_HAS_WINSOCK2_H 0 + +#define PJ_SOCK_HAS_INET_ATON 0 + +/* Set 1 if native sockaddr_in has sin_len member. + * Default: 0 + */ +#define PJ_SOCKADDR_HAS_LEN 0 + +/** + * If this macro is set, it tells select I/O Queue that select() needs to + * be given correct value of nfds (i.e. largest fd + 1). This requires + * select ioqueue to re-scan the descriptors on each registration and + * unregistration. + * If this macro is not set, then ioqueue will always give FD_SETSIZE for + * nfds argument when calling select(). + * + * Default: 0 + */ +#define PJ_SELECT_NEEDS_NFDS 0 + +/* Is errno a good way to retrieve OS errors? + */ +#define PJ_HAS_ERRNO_VAR 0 + +/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return + * the status of non-blocking connect() operation. + */ +#define PJ_HAS_SO_ERROR 0 + +/* This value specifies the value set in errno by the OS when a non-blocking + * socket recv() can not return immediate daata. + */ +#define PJ_BLOCKING_ERROR_VAL xxx + +/* This value specifies the value set in errno by the OS when a non-blocking + * socket connect() can not get connected immediately. + */ +#define PJ_BLOCKING_CONNECT_ERROR_VAL xxx + +/* Default threading is enabled, unless it's overridden. */ +#ifndef PJ_HAS_THREADS +# define PJ_HAS_THREADS (1) +#endif + +#define PJ_HAS_HIGH_RES_TIMER 1 +#ifndef PJ_OS_HAS_CHECK_STACK +# define PJ_OS_HAS_CHECK_STACK 0 +#define PJ_NATIVE_STRING_IS_UNICODE 0 + +/* If 1, use Read/Write mutex emulation for platforms that don't support it */ +#define PJ_EMULATE_RWMUTEX 1 + +/* If 1, pj_thread_create() should enforce the stack size when creating + * threads. + * Default: 0 (let OS decide the thread's stack size). + */ +#define PJ_THREAD_SET_STACK_SIZE 0 + +/* If 1, pj_thread_create() should allocate stack from the pool supplied. + * Default: 0 (let OS allocate memory for thread's stack). + */ +#define PJ_THREAD_ALLOCATE_STACK 0 + + +#endif /* __PJ_COMPAT_OS_PALMOS_H__ */ + diff --git a/pjlib/include/pj/compat/os_rtems.h b/pjlib/include/pj/compat/os_rtems.h new file mode 100644 index 0000000..ac7224d --- /dev/null +++ b/pjlib/include/pj/compat/os_rtems.h @@ -0,0 +1,139 @@ +/* $Id: os_rtems.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 + * + * 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 + */ + +/* + * Thanks Zetron, Inc and Phil Torre for donating PJLIB + * port to RTEMS. + */ + +#ifndef __PJ_COMPAT_OS_RTEMS_H__ +#define __PJ_COMPAT_OS_RTEMS_H__ + +/** + * @file os_linux.h + * @brief Describes Linux operating system specifics. + */ + +#define PJ_OS_NAME "rtems" + +#define PJ_HAS_ARPA_INET_H 1 +#define PJ_HAS_ASSERT_H 1 +#define PJ_HAS_CTYPE_H 1 +#define PJ_HAS_ERRNO_H 1 +#define PJ_HAS_LINUX_SOCKET_H 0 +#define PJ_HAS_MALLOC_H 1 +#define PJ_HAS_NETDB_H 1 +#define PJ_HAS_NETINET_IN_H 1 +#define PJ_HAS_SETJMP_H 1 +#define PJ_HAS_STDARG_H 0 +#define PJ_HAS_STDDEF_H 1 +#define PJ_HAS_STDIO_H 1 +#define PJ_HAS_STDLIB_H 1 +#define PJ_HAS_STRING_H 1 +#define PJ_HAS_SYS_IOCTL_H 1 +#define PJ_HAS_SYS_SELECT_H 1 +#define PJ_HAS_SYS_SOCKET_H 1 +#define PJ_HAS_SYS_TIME_H 1 +#define PJ_HAS_SYS_TIMEB_H 1 +#define PJ_HAS_SYS_TYPES_H 1 +#define PJ_HAS_TIME_H 1 +#define PJ_HAS_UNISTD_H 1 + +#define PJ_HAS_MSWSOCK_H 0 +#define PJ_HAS_WINSOCK_H 0 +#define PJ_HAS_WINSOCK2_H 0 + +#define PJ_SOCK_HAS_INET_ATON 1 + +/* Set 1 if native sockaddr_in has sin_len member. + * Default: 0 + */ +#define PJ_SOCKADDR_HAS_LEN 1 + +/* Is errno a good way to retrieve OS errors? + */ +#define PJ_HAS_ERRNO_VAR 1 + +/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return + * the status of non-blocking connect() operation. + */ +#define PJ_HAS_SO_ERROR 1 + +/** + * If this macro is set, it tells select I/O Queue that select() needs to + * be given correct value of nfds (i.e. largest fd + 1). This requires + * select ioqueue to re-scan the descriptors on each registration and + * unregistration. + * If this macro is not set, then ioqueue will always give FD_SETSIZE for + * nfds argument when calling select(). + * + * Default: 0 + */ +#define PJ_SELECT_NEEDS_NFDS 1 + +/* This value specifies the value set in errno by the OS when a non-blocking + * socket recv() can not return immediate daata. + */ +#define PJ_BLOCKING_ERROR_VAL EWOULDBLOCK + +/* This value specifies the value set in errno by the OS when a non-blocking + * socket connect() can not get connected immediately. + */ +#define PJ_BLOCKING_CONNECT_ERROR_VAL EINPROGRESS + +/* Default threading is enabled, unless it's overridden. */ +#ifndef PJ_HAS_THREADS +# define PJ_HAS_THREADS (1) +#endif + +#define PJ_HAS_HIGH_RES_TIMER 1 +#define PJ_HAS_MALLOC 1 +#ifndef PJ_OS_HAS_CHECK_STACK +# define PJ_OS_HAS_CHECK_STACK 0 +#endif +#define PJ_NATIVE_STRING_IS_UNICODE 0 + +#define PJ_ATOMIC_VALUE_TYPE int + +/* If 1, use Read/Write mutex emulation for platforms that don't support it */ +#define PJ_EMULATE_RWMUTEX 1 + +/* Missing socklen_t */ +typedef int socklen_t; + +/* If 1, pj_thread_create() should enforce the stack size when creating + * threads. + * Default: 0 (let OS decide the thread's stack size). + */ +#define PJ_THREAD_SET_STACK_SIZE 1 + +/* If 1, pj_thread_create() should allocate stack from the pool supplied. + * Default: 0 (let OS allocate memory for thread's stack). + */ +#define PJ_THREAD_ALLOCATE_STACK 1 + +/* RTEMS has socklen_t (does it? )*/ +#define PJ_HAS_SOCKLEN_T 1 + + + + +#endif /* __PJ_COMPAT_OS_RTEMS_H__ */ + diff --git a/pjlib/include/pj/compat/os_sunos.h b/pjlib/include/pj/compat/os_sunos.h new file mode 100644 index 0000000..245c35a --- /dev/null +++ b/pjlib/include/pj/compat/os_sunos.h @@ -0,0 +1,132 @@ +/* $Id: os_sunos.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 + * + * 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_COMPAT_OS_SUNOS_H__ +#define __PJ_COMPAT_OS_SUNOS_H__ + +/** + * @file os_sunos.h + * @brief Describes SunOS/Solaris operating system specifics. + */ + +#define PJ_OS_NAME "sunos" + +#define PJ_HAS_ARPA_INET_H 1 +#define PJ_HAS_ASSERT_H 1 +#define PJ_HAS_CTYPE_H 1 +#define PJ_HAS_ERRNO_H 1 +#define PJ_HAS_LINUX_SOCKET_H 0 +#define PJ_HAS_MALLOC_H 1 +#define PJ_HAS_NETDB_H 1 +#define PJ_HAS_NETINET_IN_H 1 +#define PJ_HAS_SETJMP_H 1 +#define PJ_HAS_STDARG_H 1 +#define PJ_HAS_STDDEF_H 1 +#define PJ_HAS_STDIO_H 1 +#define PJ_HAS_STDLIB_H 1 +#define PJ_HAS_STRING_H 1 +#define PJ_HAS_SYS_IOCTL_H 1 +#define PJ_HAS_SYS_SELECT_H 1 +#define PJ_HAS_SYS_SOCKET_H 1 +#define PJ_HAS_SYS_TIME_H 0 +#define PJ_HAS_SYS_TIMEB_H 1 +#define PJ_HAS_SYS_TYPES_H 1 +#define PJ_HAS_TIME_H 1 +#define PJ_HAS_UNISTD_H 1 + +#define PJ_HAS_MSWSOCK_H 0 +#define PJ_HAS_WINSOCK_H 0 +#define PJ_HAS_WINSOCK2_H 0 + +#define PJ_SOCK_HAS_INET_ATON 0 + +/* Set 1 if native sockaddr_in has sin_len member. + * Default: 0 + */ +#define PJ_SOCKADDR_HAS_LEN 0 + +/* Is errno a good way to retrieve OS errors? + */ +#define PJ_HAS_ERRNO_VAR 1 + +/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return + * the status of non-blocking connect() operation. + */ +#define PJ_HAS_SO_ERROR 0 + +/* This value specifies the value set in errno by the OS when a non-blocking + * socket recv() can not return immediate daata. + */ +#define PJ_BLOCKING_ERROR_VAL EWOULDBLOCK + +/* This value specifies the value set in errno by the OS when a non-blocking + * socket connect() can not get connected immediately. + */ +#define PJ_BLOCKING_CONNECT_ERROR_VAL EINPROGRESS + +/** + * If this macro is set, it tells select I/O Queue that select() needs to + * be given correct value of nfds (i.e. largest fd + 1). This requires + * select ioqueue to re-scan the descriptors on each registration and + * unregistration. + * If this macro is not set, then ioqueue will always give FD_SETSIZE for + * nfds argument when calling select(). + * + * Default: 0 + */ +#define PJ_SELECT_NEEDS_NFDS 0 + +/* Default threading is enabled, unless it's overridden. */ +#ifndef PJ_HAS_THREADS +# define PJ_HAS_THREADS (1) +#endif + +#define PJ_HAS_HIGH_RES_TIMER 1 +#define PJ_HAS_MALLOC 1 +#ifndef PJ_OS_HAS_CHECK_STACK +# define PJ_OS_HAS_CHECK_STACK 0 +#endif +#define PJ_NATIVE_STRING_IS_UNICODE 0 + +#define PJ_ATOMIC_VALUE_TYPE long + +/* Get BSD related identifers in Sun's include files */ +#define BSD_COMP + +/* If 1, use Read/Write mutex emulation for platforms that don't support it */ +#define PJ_EMULATE_RWMUTEX 0 + +/* If 1, pj_thread_create() should enforce the stack size when creating + * threads. + * Default: 0 (let OS decide the thread's stack size). + */ +#define PJ_THREAD_SET_STACK_SIZE 0 + +/* If 1, pj_thread_create() should allocate stack from the pool supplied. + * Default: 0 (let OS allocate memory for thread's stack). + */ +#define PJ_THREAD_ALLOCATE_STACK 0 + +/* SunOS has socklen_t (does it? )*/ +#define PJ_HAS_SOCKLEN_T 1 + + + +#endif /* __PJ_COMPAT_OS_SUNOS_H__ */ + diff --git a/pjlib/include/pj/compat/os_symbian.h b/pjlib/include/pj/compat/os_symbian.h new file mode 100644 index 0000000..7906d6f --- /dev/null +++ b/pjlib/include/pj/compat/os_symbian.h @@ -0,0 +1,167 @@ +/* $Id: os_symbian.h 3841 2011-10-24 09:28:13Z ming $ */ +/* + * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono + * + * 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_COMPAT_OS_SYMBIAN_H__ +#define __PJ_COMPAT_OS_SYMBIAN_H__ + +/** + * @file os_symbian.h + * @brief Describes Symbian operating system specifics. + */ + +#define PJ_OS_NAME "symbian" + +#define PJ_HAS_ARPA_INET_H 1 +#define PJ_HAS_ASSERT_H 1 +#define PJ_HAS_CTYPE_H 1 +#define PJ_HAS_ERRNO_H 1 +#define PJ_HAS_LINUX_SOCKET_H 0 +#define PJ_HAS_MALLOC_H 0 +#define PJ_HAS_NETDB_H 1 +#define PJ_HAS_NETINET_IN_H 1 +#define PJ_HAS_NETINET_TCP_H 0 +#define PJ_HAS_SETJMP_H 1 +#define PJ_HAS_STDARG_H 1 +#define PJ_HAS_STDDEF_H 1 +#define PJ_HAS_STDIO_H 1 +#define PJ_HAS_STDLIB_H 1 +#define PJ_HAS_STRING_H 1 +#define PJ_HAS_NO_SNPRINTF 1 +#define PJ_HAS_SYS_IOCTL_H 1 +#define PJ_HAS_SYS_SELECT_H 0 +#define PJ_HAS_SYS_SOCKET_H 1 +#define PJ_HAS_SYS_TIME_H 1 +#define PJ_HAS_SYS_TIMEB_H 0 +#define PJ_HAS_SYS_TYPES_H 1 +#define PJ_HAS_TIME_H 1 +#define PJ_HAS_UNISTD_H 1 + +#define PJ_HAS_MSWSOCK_H 0 +#define PJ_HAS_WINSOCK_H 0 +#define PJ_HAS_WINSOCK2_H 0 + +#define PJ_SOCK_HAS_INET_ATON 0 + +/* Set 1 if native sockaddr_in has sin_len member. + * Default: 0 + */ +#define PJ_SOCKADDR_HAS_LEN 0 +/* Is errno a good way to retrieve OS errors? + */ +#define PJ_HAS_ERRNO_VAR 1 + +/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return + * the status of non-blocking connect() operation. + */ +#define PJ_HAS_SO_ERROR 1 + +/** + * If this macro is set, it tells select I/O Queue that select() needs to + * be given correct value of nfds (i.e. largest fd + 1). This requires + * select ioqueue to re-scan the descriptors on each registration and + * unregistration. + * If this macro is not set, then ioqueue will always give FD_SETSIZE for + * nfds argument when calling select(). + * + * Default: 0 + */ +#define PJ_SELECT_NEEDS_NFDS 0 + +/* This value specifies the value set in errno by the OS when a non-blocking + * socket recv() can not return immediate daata. + */ +#define PJ_BLOCKING_ERROR_VAL EAGAIN + +/* This value specifies the value set in errno by the OS when a non-blocking + * socket connect() can not get connected immediately. + */ +#define PJ_BLOCKING_CONNECT_ERROR_VAL EINPROGRESS + +/* + * We don't want to use threads in Symbian + */ +#define PJ_HAS_THREADS 0 + + +/* + * Declare __FD_SETSIZE now before including . +#define __FD_SETSIZE PJ_IOQUEUE_MAX_HANDLES + */ + +#ifndef NULL +# define NULL 0 +#endif + +/* Endianness */ +#ifndef PJ_IS_LITTLE_ENDIAN +# define PJ_IS_LITTLE_ENDIAN 1 +# define PJ_IS_BIG_ENDIAN 0 +#endif + +/* Doesn't seem to allow more than this */ +#define PJ_IOQUEUE_MAX_HANDLES 8 + +/* + * Override features. + */ +#define PJ_HAS_FLOATING_POINT 0 +#define PJ_HAS_MALLOC 0 +#define PJ_HAS_SEMAPHORE 1 +#define PJ_HAS_EVENT_OBJ 0 +#define PJ_HAS_HIGH_RES_TIMER 1 +#define PJ_OS_HAS_CHECK_STACK 0 +#define PJ_TERM_HAS_COLOR 0 +#define PJ_NATIVE_STRING_IS_UNICODE 0 +#define PJ_NATIVE_ERR_POSITIVE 0 + +#define PJ_ATOMIC_VALUE_TYPE int +#define PJ_THREAD_DESC_SIZE 128 + +/* If 1, use Read/Write mutex emulation for platforms that don't support it */ +#define PJ_EMULATE_RWMUTEX 1 + +/* If 1, pj_thread_create() should enforce the stack size when creating + * threads. + * Default: 0 (let OS decide the thread's stack size). + */ +#define PJ_THREAD_SET_STACK_SIZE 0 + +/* If 1, pj_thread_create() should allocate stack from the pool supplied. + * Default: 0 (let OS allocate memory for thread's stack). + */ +#define PJ_THREAD_ALLOCATE_STACK 0 + +/* Missing socklen_t */ +#define PJ_HAS_SOCKLEN_T 1 +typedef unsigned int socklen_t; + +#ifndef __GCCE__ +#include +#endif + +#define PJ_EXPORT_DECL_SPECIFIER IMPORT_C +//#define PJ_EXPORT_DECL_SPECIFIER +#define PJ_EXPORT_DEF_SPECIFIER EXPORT_C +#define PJ_IMPORT_DECL_SPECIFIER IMPORT_C + + +#endif /* __PJ_COMPAT_OS_SYMBIAN_H__ */ + + + diff --git a/pjlib/include/pj/compat/os_win32.h b/pjlib/include/pj/compat/os_win32.h new file mode 100644 index 0000000..f1bd597 --- /dev/null +++ b/pjlib/include/pj/compat/os_win32.h @@ -0,0 +1,139 @@ +/* $Id: os_win32.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 + * + * 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_COMPAT_OS_WIN32_H__ +#define __PJ_COMPAT_OS_WIN32_H__ + +/** + * @file os_win32.h + * @brief Describes Win32 operating system family specifics. + */ + +#define PJ_OS_NAME "win32" + +#define WIN32_LEAN_AND_MEAN +#define PJ_WIN32_WINNT 0x0400 +#ifndef _WIN32_WINNT +# define _WIN32_WINNT PJ_WIN32_WINNT +#endif + +#define PJ_HAS_ARPA_INET_H 0 +#define PJ_HAS_ASSERT_H 1 +#define PJ_HAS_CTYPE_H 1 +#define PJ_HAS_ERRNO_H 0 /* Must be zero, otherwise errno_test() fails. */ +#define PJ_HAS_LINUX_SOCKET_H 0 +#define PJ_HAS_MALLOC_H 1 +#define PJ_HAS_NETDB_H 0 +#define PJ_HAS_NETINET_IN_H 0 +#define PJ_HAS_NETINET_TCP_H 0 +#define PJ_HAS_SETJMP_H 1 +#define PJ_HAS_STDARG_H 1 +#define PJ_HAS_STDDEF_H 1 +#undef PJ_HAS_STDINT_H +#define PJ_HAS_STDIO_H 1 +#define PJ_HAS_STDLIB_H 1 +#define PJ_HAS_STRING_H 1 +#define PJ_HAS_SYS_IOCTL_H 0 +#define PJ_HAS_SYS_SELECT_H 0 +#define PJ_HAS_SYS_SOCKET_H 0 +#define PJ_HAS_SYS_TIME_H 0 +#define PJ_HAS_SYS_TIMEB_H 1 +#define PJ_HAS_SYS_TYPES_H 1 +#define PJ_HAS_TIME_H 1 +#define PJ_HAS_UNISTD_H 0 + +#define PJ_HAS_MSWSOCK_H 1 +#define PJ_HAS_WINSOCK_H 0 +#define PJ_HAS_WINSOCK2_H 1 +#define PJ_HAS_WS2TCPIP_H 1 + +#define PJ_SOCK_HAS_INET_ATON 0 + +/* Set 1 if native sockaddr_in has sin_len member. + * Default: 0 + */ +#define PJ_SOCKADDR_HAS_LEN 0 + +/* Is errno a good way to retrieve OS errors? (No) + */ +#define PJ_HAS_ERRNO_VAR 0 + +/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return + * the status of non-blocking connect() operation. + */ +#define PJ_HAS_SO_ERROR 1 + +/* This value specifies the value set in errno by the OS when a non-blocking + * socket recv() or send() can not return immediately. + */ +#define PJ_BLOCKING_ERROR_VAL WSAEWOULDBLOCK + +/* This value specifies the value set in errno by the OS when a non-blocking + * socket connect() can not get connected immediately. + */ +#define PJ_BLOCKING_CONNECT_ERROR_VAL WSAEWOULDBLOCK + +/** + * If this macro is set, it tells select I/O Queue that select() needs to + * be given correct value of nfds (i.e. largest fd + 1). This requires + * select ioqueue to re-scan the descriptors on each registration and + * unregistration. + * If this macro is not set, then ioqueue will always give FD_SETSIZE for + * nfds argument when calling select(). + * + * Default: 0 + */ +#define PJ_SELECT_NEEDS_NFDS 0 + +/* Default threading is enabled, unless it's overridden. */ +#ifndef PJ_HAS_THREADS +# define PJ_HAS_THREADS (1) +#endif + +#define PJ_HAS_HIGH_RES_TIMER 1 +#define PJ_HAS_MALLOC 1 +#ifndef PJ_OS_HAS_CHECK_STACK +# define PJ_OS_HAS_CHECK_STACK 1 +#endif + +#ifdef UNICODE +# define PJ_NATIVE_STRING_IS_UNICODE 1 +#else +# define PJ_NATIVE_STRING_IS_UNICODE 0 +#endif + +#define PJ_ATOMIC_VALUE_TYPE long + +/* If 1, use Read/Write mutex emulation for platforms that don't support it */ +#define PJ_EMULATE_RWMUTEX 1 + +/* If 1, pj_thread_create() should enforce the stack size when creating + * threads. + * Default: 0 (let OS decide the thread's stack size). + */ +#define PJ_THREAD_SET_STACK_SIZE 0 + +/* If 1, pj_thread_create() should allocate stack from the pool supplied. + * Default: 0 (let OS allocate memory for thread's stack). + */ +#define PJ_THREAD_ALLOCATE_STACK 0 + + +#endif /* __PJ_COMPAT_OS_WIN32_H__ */ + diff --git a/pjlib/include/pj/compat/os_win32_wince.h b/pjlib/include/pj/compat/os_win32_wince.h new file mode 100644 index 0000000..d6f228d --- /dev/null +++ b/pjlib/include/pj/compat/os_win32_wince.h @@ -0,0 +1,146 @@ +/* $Id: os_win32_wince.h 3841 2011-10-24 09:28:13Z ming $ */ +/* + * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono + * + * 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_COMPAT_OS_WIN32_WINCE_H__ +#define __PJ_COMPAT_OS_WIN32_WINCE_H__ + +/** + * @file os_win32.h + * @brief Describes Win32 operating system family specifics. + */ + +#define PJ_OS_NAME "win32-wince" + +#define WIN32_LEAN_AND_MEAN +#define RPC_NO_WINDOWS_H +//#define PJ_WIN32_WINNT 0x0400 +//#define _WIN32_WINNT PJ_WIN32_WINNT + +#define PJ_HAS_ARPA_INET_H 0 +#define PJ_HAS_ASSERT_H 1 +#define PJ_HAS_CTYPE_H 1 +#define PJ_HAS_ERRNO_H 0 /* Must be zero, otherwise errno_test() fails. */ +#define PJ_HAS_LINUX_SOCKET_H 0 +#define PJ_HAS_MALLOC_H 1 +#define PJ_HAS_NETDB_H 0 +#define PJ_HAS_NETINET_IN_H 0 +#define PJ_HAS_NETINET_TCP_H 0 +#define PJ_HAS_SETJMP_H 1 +#define PJ_HAS_STDARG_H 1 +#define PJ_HAS_STDDEF_H 1 +#define PJ_HAS_STDIO_H 1 +#define PJ_HAS_STDLIB_H 1 +#define PJ_HAS_STRING_H 1 +#define PJ_HAS_SYS_IOCTL_H 0 +#define PJ_HAS_SYS_SELECT_H 0 +#define PJ_HAS_SYS_SOCKET_H 0 +#define PJ_HAS_SYS_TIME_H 0 +#define PJ_HAS_SYS_TIMEB_H 0 /* Doesn't have sys/timeb.h */ +#define PJ_HAS_SYS_TYPES_H 0 /* Doesn't have sys/types.h */ +#define PJ_HAS_TIME_H 1 +#define PJ_HAS_UNISTD_H 0 + +#define PJ_HAS_MSWSOCK_H 1 +#define PJ_HAS_WINSOCK_H 0 +#define PJ_HAS_WINSOCK2_H 1 + +#define PJ_SOCK_HAS_INET_ATON 0 + +/* Set 1 if native sockaddr_in has sin_len member. + * Default: 0 + */ +#define PJ_SOCKADDR_HAS_LEN 0 + +/* Is errno a good way to retrieve OS errors? (no) + */ +#define PJ_HAS_ERRNO_VAR 0 + +/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return + * the status of non-blocking connect() operation. + */ +#define PJ_HAS_SO_ERROR 0 + +/* This value specifies the value set in errno by the OS when a non-blocking + * socket recv() or send() can not return immediately. + */ +#define PJ_BLOCKING_ERROR_VAL WSAEWOULDBLOCK + +/* This value specifies the value set in errno by the OS when a non-blocking + * socket connect() can not get connected immediately. + */ +#define PJ_BLOCKING_CONNECT_ERROR_VAL WSAEWOULDBLOCK + +/** + * If this macro is set, it tells select I/O Queue that select() needs to + * be given correct value of nfds (i.e. largest fd + 1). This requires + * select ioqueue to re-scan the descriptors on each registration and + * unregistration. + * If this macro is not set, then ioqueue will always give FD_SETSIZE for + * nfds argument when calling select(). + * + * Default: 0 + */ +#define PJ_SELECT_NEEDS_NFDS 0 + +/* Endianness */ +#ifndef PJ_IS_LITTLE_ENDIAN +# define PJ_IS_LITTLE_ENDIAN 1 +# define PJ_IS_BIG_ENDIAN 0 +#endif + +/* Default threading is enabled, unless it's overridden. */ +#ifndef PJ_HAS_THREADS +# define PJ_HAS_THREADS (1) +#endif + +#define PJ_HAS_HIGH_RES_TIMER 1 +#define PJ_HAS_MALLOC 1 +#define PJ_OS_HAS_CHECK_STACK 1 + +#define PJ_ATOMIC_VALUE_TYPE long + +/* TlsAlloc() error value. */ +#define TLS_OUT_OF_INDEXES 0xFFFFFFFF + +/* No console. */ +#define PJ_TERM_HAS_COLOR 0 + +/* No rdtsc */ +#define PJ_TIMESTAMP_USE_RDTSC 0 + +/* Native string is Unicode. */ +#define PJ_NATIVE_STRING_IS_UNICODE 1 + +/* If 1, use Read/Write mutex emulation for platforms that don't support it */ +#define PJ_EMULATE_RWMUTEX 1 + +/* If 1, pj_thread_create() should enforce the stack size when creating + * threads. + * Default: 0 (let OS decide the thread's stack size). + */ +#define PJ_THREAD_SET_STACK_SIZE 0 + +/* If 1, pj_thread_create() should allocate stack from the pool supplied. + * Default: 0 (let OS allocate memory for thread's stack). + */ +#define PJ_THREAD_ALLOCATE_STACK 0 + + +#endif /* __PJ_COMPAT_OS_WIN32_WINCE_H__ */ + diff --git a/pjlib/include/pj/compat/rand.h b/pjlib/include/pj/compat/rand.h new file mode 100644 index 0000000..32467ee --- /dev/null +++ b/pjlib/include/pj/compat/rand.h @@ -0,0 +1,70 @@ +/* $Id: rand.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 + * + * 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_COMPAT_RAND_H__ +#define __PJ_COMPAT_RAND_H__ + +/** + * @file rand.h + * @brief Provides platform_rand() and platform_srand() functions. + */ + +#if defined(PJ_HAS_STDLIB_H) && PJ_HAS_STDLIB_H != 0 + /* + * Use stdlib based rand() and srand(). + */ +# include +# define platform_srand srand +# if defined(RAND_MAX) && RAND_MAX <= 0xFFFF + /* + * When rand() is only 16 bit strong, double the strength + * by calling it twice! + */ + PJ_INLINE(int) platform_rand(void) + { + return ((rand() & 0xFFFF) << 16) | (rand() & 0xFFFF); + } +# else +# define platform_rand rand +# endif + +#elif defined(PJ_LINUX_KERNEL) && PJ_LINUX_KERNEL != 0 + /* + * Linux kernel mode random number generator. + */ +# include +# define platform_srand(seed) + + PJ_INLINE(int) platform_rand(void) + { + int value; + get_random_bytes((void*)&value, sizeof(value)); + return value; + } + +#else +# warning "platform_rand() is not implemented" +# define platform_rand() 1 +# define platform_srand(seed) + +#endif + + +#endif /* __PJ_COMPAT_RAND_H__ */ + diff --git a/pjlib/include/pj/compat/setjmp.h b/pjlib/include/pj/compat/setjmp.h new file mode 100644 index 0000000..0aea218 --- /dev/null +++ b/pjlib/include/pj/compat/setjmp.h @@ -0,0 +1,98 @@ +/* $Id: setjmp.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 + * + * 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_COMPAT_SETJMP_H__ +#define __PJ_COMPAT_SETJMP_H__ + +/** + * @file setjmp.h + * @brief Provides setjmp.h functionality. + */ + +#if defined(PJ_HAS_SETJMP_H) && PJ_HAS_SETJMP_H != 0 +# include + typedef jmp_buf pj_jmp_buf; +# ifndef pj_setjmp +# define pj_setjmp(buf) setjmp(buf) +# endif +# ifndef pj_longjmp +# define pj_longjmp(buf,d) longjmp(buf,d) +# endif + +#elif defined(PJ_LINUX_KERNEL) && PJ_LINUX_KERNEL != 0 && \ + defined(PJ_M_I386) && PJ_M_I386 != 0 + + /* + * These are taken from uClibc. + * Copyright (C) 2000-2003 Erik Andersen + */ +# if defined __USE_MISC || defined _ASM +# define JB_BX 0 +# define JB_SI 1 +# define JB_DI 2 +# define JB_BP 3 +# define JB_SP 4 +# define JB_PC 5 +# define JB_SIZE 24 +# endif + +# ifndef _ASM + typedef int __jmp_buf[6]; + + /* A `sigset_t' has a bit for each signal. */ +# define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int))) + typedef struct __sigset_t_tag + { + unsigned long int __val[_SIGSET_NWORDS]; + } __sigset_t; + + /* Calling environment, plus possibly a saved signal mask. */ + typedef struct __jmp_buf_tag /* C++ doesn't like tagless structs. */ + { + /* NOTE: The machine-dependent definitions of `__sigsetjmp' + assume that a `jmp_buf' begins with a `__jmp_buf' and that + `__mask_was_saved' follows it. Do not move these members + or add others before it. */ + __jmp_buf __jmpbuf; /* Calling environment. */ + int __mask_was_saved; /* Saved the signal mask? */ + // we never saved the mask. + __sigset_t __saved_mask; /* Saved signal mask. */ + } jmp_buf[1]; + + typedef jmp_buf sigjmp_buf; + typedef jmp_buf pj_jmp_buf; + + PJ_DECL(int) pj_setjmp(pj_jmp_buf env); + PJ_DECL(void) pj_longjmp(pj_jmp_buf env, int val) __attribute__((noreturn)); + +# endif /* _ASM */ + +#elif defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0 + /* Symbian framework don't use setjmp/longjmp */ + +#else +# warning "setjmp()/longjmp() is not implemented" + typedef int pj_jmp_buf[1]; +# define pj_setjmp(buf) 0 +# define pj_longjmp(buf,d) 0 +#endif + + +#endif /* __PJ_COMPAT_SETJMP_H__ */ + diff --git a/pjlib/include/pj/compat/size_t.h b/pjlib/include/pj/compat/size_t.h new file mode 100644 index 0000000..25c58a6 --- /dev/null +++ b/pjlib/include/pj/compat/size_t.h @@ -0,0 +1,32 @@ +/* $Id: size_t.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 + * + * 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_COMPAT_SIZE_T_H__ +#define __PJ_COMPAT_SIZE_T_H__ + +/** + * @file size_t.h + * @brief Provides size_t type. + */ +#if PJ_HAS_STDDEF_H +# include +#endif + +#endif /* __PJ_COMPAT_SIZE_T_H__ */ + diff --git a/pjlib/include/pj/compat/socket.h b/pjlib/include/pj/compat/socket.h new file mode 100644 index 0000000..5dccc01 --- /dev/null +++ b/pjlib/include/pj/compat/socket.h @@ -0,0 +1,239 @@ +/* $Id: socket.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 + * + * 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_COMPAT_SOCKET_H__ +#define __PJ_COMPAT_SOCKET_H__ + +/** + * @file socket.h + * @brief Provides all socket related functions,data types, error codes, etc. + */ + +#if defined(PJ_HAS_WINSOCK2_H) && PJ_HAS_WINSOCK2_H != 0 +# include +#endif + +#if defined(PJ_HAS_WINSOCK_H) && PJ_HAS_WINSOCK_H != 0 +# include +#endif + +#if defined(PJ_HAS_WS2TCPIP_H) && PJ_HAS_WS2TCPIP_H != 0 +# include +#endif + + +/* + * IPv6 for Visual Studio's + * + * = Visual Studio 6 = + * + * Visual Studio 6 does not ship with IPv6 support, so you MUST + * download and install IPv6 Tehnology Preview (IPv6Kit) from: + * http://msdn.microsoft.com/downloads/sdks/platform/tpipv6/ReadMe.asp + * Then put IPv6Kit\inc in your Visual Studio include path. + * + * In addition, by default IPv6Kit does not want to install on + * Windows 2000 SP4. Please see: + * http://msdn.microsoft.com/downloads/sdks/platform/tpipv6/faq.asp + * on how to install IPv6Kit on Win2K SP4. + * + * + * = Visual Studio 2003, 2005 (including Express) = + * + * These VS uses Microsoft Platform SDK for Windows Server 2003 SP1, and + * it has built-in IPv6 support. + */ +#if defined(_MSC_VER) && defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0 +# ifndef s_addr +# define s_addr S_un.S_addr +# endif + +# if !defined(IPPROTO_IPV6) + /* Need to download and install IPv6Kit for this platform. + * Please see the comments above about Visual Studio 6. + */ +# include +# endif + +# define PJ_SOCK_HAS_GETADDRINFO 1 +#endif /* _MSC_VER */ + +#if defined(PJ_HAS_SYS_TYPES_H) && PJ_HAS_SYS_TYPES_H != 0 +# include +#endif + +#if defined(PJ_HAS_SYS_SOCKET_H) && PJ_HAS_SYS_SOCKET_H != 0 +# include +#endif + +#if defined(PJ_HAS_LINUX_SOCKET_H) && PJ_HAS_LINUX_SOCKET_H != 0 +# include +#endif + +#if defined(PJ_HAS_SYS_SELECT_H) && PJ_HAS_SYS_SELECT_H != 0 +# include +#endif + +#if defined(PJ_HAS_NETINET_IN_H) && PJ_HAS_NETINET_IN_H != 0 +# include +#endif + +#if defined(PJ_HAS_NETINET_IN_SYSTM_H) && PJ_HAS_NETINET_IN_SYSTM_H != 0 +/* Required to include netinet/ip.h in FreeBSD 7.0 */ +# include +#endif + +#if defined(PJ_HAS_NETINET_IP_H) && PJ_HAS_NETINET_IP_H != 0 +/* To pull in IPTOS_* constants */ +# include +#endif + +#if defined(PJ_HAS_NETINET_TCP_H) && PJ_HAS_NETINET_TCP_H != 0 +/* To pull in TCP_NODELAY constants */ +# include +#endif + +#if defined(PJ_HAS_NET_IF_H) && PJ_HAS_NET_IF_H != 0 +/* For interface enumeration in ip_helper */ +# include +#endif + +#if defined(PJ_HAS_IFADDRS_H) && PJ_HAS_IFADDRS_H != 0 +/* Interface enum with getifaddrs() which works with IPv6 */ +# include +#endif + +#if defined(PJ_HAS_ARPA_INET_H) && PJ_HAS_ARPA_INET_H != 0 +# include +#endif + +#if defined(PJ_HAS_SYS_IOCTL_H) && PJ_HAS_SYS_IOCTL_H != 0 +# include /* FBIONBIO */ +#endif + +#if defined(PJ_HAS_ERRNO_H) && PJ_HAS_ERRNO_H != 0 +# include +#endif + +#if defined(PJ_HAS_NETDB_H) && PJ_HAS_NETDB_H != 0 +# include +#endif + +#if defined(PJ_HAS_UNISTD_H) && PJ_HAS_UNISTD_H != 0 +# include +#endif + +#if defined(PJ_HAS_SYS_FILIO_H) && PJ_HAS_SYS_FILIO_H != 0 +# include +#endif + +#if defined(PJ_HAS_SYS_SOCKIO_H) && PJ_HAS_SYS_SOCKIO_H != 0 +# include +#endif + + +/* + * Define common errors. + */ +#if (defined(PJ_WIN32) && PJ_WIN32!=0) || \ + (defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0) +# define OSERR_EWOULDBLOCK WSAEWOULDBLOCK +# define OSERR_EINPROGRESS WSAEINPROGRESS +# define OSERR_ECONNRESET WSAECONNRESET +# define OSERR_ENOTCONN WSAENOTCONN +#elif defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0 +# define OSERR_EWOULDBLOCK -1 +# define OSERR_EINPROGRESS -1 +# define OSERR_ECONNRESET -1 +# define OSERR_ENOTCONN -1 +#else +# define OSERR_EWOULDBLOCK EWOULDBLOCK +# define OSERR_EINPROGRESS EINPROGRESS +# define OSERR_ECONNRESET ECONNRESET +# define OSERR_ENOTCONN ENOTCONN +#endif + + +/* + * And undefine these.. + */ +#undef s_addr +#undef s6_addr + +/* + * Linux kernel specifics + */ +#if defined(PJ_LINUX_KERNEL) +# include +# include /* FIONBIO */ +# include /* sys_select() */ +# include /* set/get_fs() */ + + typedef int socklen_t; +# define getsockopt sys_getsockopt + + /* + * Wrapper for select() in Linux kernel. + */ + PJ_INLINE(int) select(int n, fd_set *inp, fd_set *outp, fd_set *exp, + struct timeval *tvp) + { + int count; + mm_segment_t oldfs = get_fs(); + set_fs(KERNEL_DS); + count = sys_select(n, inp, outp, exp, tvp); + set_fs(oldfs); + return count; + } +#endif /* PJ_LINUX_KERNEL */ + + +/* + * This will finally be obsoleted, since it should be declared in + * os_auto.h + */ +#if !defined(PJ_HAS_SOCKLEN_T) || PJ_HAS_SOCKLEN_T==0 + typedef int socklen_t; +#endif + +/* Regarding sin_len member of sockaddr_in: + * BSD systems (including MacOS X requires that the sin_len member of + * sockaddr_in be set to sizeof(sockaddr_in), while other systems (Windows + * and Linux included) do not. + * + * To maintain compatibility between systems, PJLIB will automatically + * set this field before invoking native OS socket API, and it will + * always reset the field to zero before returning pj_sockaddr_in to + * application (such as in pj_getsockname() and pj_recvfrom()). + * + * Application MUST always set this field to zero. + * + * This way we can avoid hard to find problem such as when the socket + * address is used as hash table key. + */ +#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0 +# define PJ_SOCKADDR_SET_LEN(addr,len) (((pj_addr_hdr*)(addr))->sa_zero_len=(len)) +# define PJ_SOCKADDR_RESET_LEN(addr) (((pj_addr_hdr*)(addr))->sa_zero_len=0) +#else +# define PJ_SOCKADDR_SET_LEN(addr,len) +# define PJ_SOCKADDR_RESET_LEN(addr) +#endif + +#endif /* __PJ_COMPAT_SOCKET_H__ */ + diff --git a/pjlib/include/pj/compat/stdarg.h b/pjlib/include/pj/compat/stdarg.h new file mode 100644 index 0000000..8e1d9ab --- /dev/null +++ b/pjlib/include/pj/compat/stdarg.h @@ -0,0 +1,32 @@ +/* $Id: stdarg.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 + * + * 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_COMPAT_STDARG_H__ +#define __PJ_COMPAT_STDARG_H__ + +/** + * @file stdarg.h + * @brief Provides stdarg functionality. + */ + +#if defined(PJ_HAS_STDARG_H) && PJ_HAS_STDARG_H != 0 +# include +#endif + +#endif /* __PJ_COMPAT_STDARG_H__ */ diff --git a/pjlib/include/pj/compat/stdfileio.h b/pjlib/include/pj/compat/stdfileio.h new file mode 100644 index 0000000..aba17aa --- /dev/null +++ b/pjlib/include/pj/compat/stdfileio.h @@ -0,0 +1,32 @@ +/* $Id: stdfileio.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 + * + * 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_COMPAT_STDFILEIO_H__ +#define __PJ_COMPAT_STDFILEIO_H__ + +/** + * @file stdfileio.h + * @brief Compatibility for ANSI file I/O like fputs, fflush, etc. + */ + +#if defined(PJ_HAS_STDIO_H) && PJ_HAS_STDIO_H != 0 +# include +#endif + +#endif /* __PJ_COMPAT_STDFILEIO_H__ */ diff --git a/pjlib/include/pj/compat/string.h b/pjlib/include/pj/compat/string.h new file mode 100644 index 0000000..a2a78b3 --- /dev/null +++ b/pjlib/include/pj/compat/string.h @@ -0,0 +1,144 @@ +/* $Id: string.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 + * + * 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_COMPAT_STRING_H__ +#define __PJ_COMPAT_STRING_H__ + +/** + * @file string.h + * @brief Provides string manipulation functions found in ANSI string.h. + */ + + +#if defined(PJ_HAS_STRING_H) && PJ_HAS_STRING_H != 0 +# include +#else + + PJ_DECL(int) strcasecmp(const char *s1, const char *s2); + PJ_DECL(int) strncasecmp(const char *s1, const char *s2, int len); + +#endif + +/* For sprintf family */ +#include + +/* On WinCE, string stuffs are declared in stdlib.h */ +#if defined(PJ_HAS_STDLIB_H) && PJ_HAS_STDLIB_H!=0 +# include +#endif + +#if defined(_MSC_VER) +# define strcasecmp _stricmp +# define strncasecmp _strnicmp +# define snprintf _snprintf +# define vsnprintf _vsnprintf +# define snwprintf _snwprintf +# define wcsicmp _wcsicmp +# define wcsnicmp _wcsnicmp +#else +# define stricmp strcasecmp +# define strnicmp strncasecmp + +# if defined(PJ_NATIVE_STRING_IS_UNICODE) && PJ_NATIVE_STRING_IS_UNICODE!=0 +# error "Implement Unicode string functions" +# endif +#endif + +#define pj_ansi_strcmp strcmp +#define pj_ansi_strncmp strncmp +#define pj_ansi_strlen strlen +#define pj_ansi_strcpy strcpy +#define pj_ansi_strncpy strncpy +#define pj_ansi_strcat strcat +#define pj_ansi_strstr strstr +#define pj_ansi_strchr strchr +#define pj_ansi_strcasecmp strcasecmp +#define pj_ansi_stricmp strcasecmp +#define pj_ansi_strncasecmp strncasecmp +#define pj_ansi_strnicmp strncasecmp +#define pj_ansi_sprintf sprintf + +#if defined(PJ_HAS_NO_SNPRINTF) && PJ_HAS_NO_SNPRINTF != 0 +# include +# include + PJ_BEGIN_DECL + PJ_DECL(int) snprintf(char*s1, pj_size_t len, const char*s2, ...); + PJ_DECL(int) vsnprintf(char*s1, pj_size_t len, const char*s2, va_list arg); + PJ_END_DECL +#endif + +#define pj_ansi_snprintf snprintf +#define pj_ansi_vsprintf vsprintf +#define pj_ansi_vsnprintf vsnprintf + +#define pj_unicode_strcmp wcscmp +#define pj_unicode_strncmp wcsncmp +#define pj_unicode_strlen wcslen +#define pj_unicode_strcpy wcscpy +#define pj_unicode_strncpy wcsncpy +#define pj_unicode_strcat wcscat +#define pj_unicode_strstr wcsstr +#define pj_unicode_strchr wcschr +#define pj_unicode_strcasecmp wcsicmp +#define pj_unicode_stricmp wcsicmp +#define pj_unicode_strncasecmp wcsnicmp +#define pj_unicode_strnicmp wcsnicmp +#define pj_unicode_sprintf swprintf +#define pj_unicode_snprintf snwprintf +#define pj_unicode_vsprintf vswprintf +#define pj_unicode_vsnprintf vsnwprintf + +#if defined(PJ_NATIVE_STRING_IS_UNICODE) && PJ_NATIVE_STRING_IS_UNICODE!=0 +# define pj_native_strcmp pj_unicode_strcmp +# define pj_native_strncmp pj_unicode_strncmp +# define pj_native_strlen pj_unicode_strlen +# define pj_native_strcpy pj_unicode_strcpy +# define pj_native_strncpy pj_unicode_strncpy +# define pj_native_strcat pj_unicode_strcat +# define pj_native_strstr pj_unicode_strstr +# define pj_native_strchr pj_unicode_strchr +# define pj_native_strcasecmp pj_unicode_strcasecmp +# define pj_native_stricmp pj_unicode_stricmp +# define pj_native_strncasecmp pj_unicode_strncasecmp +# define pj_native_strnicmp pj_unicode_strnicmp +# define pj_native_sprintf pj_unicode_sprintf +# define pj_native_snprintf pj_unicode_snprintf +# define pj_native_vsprintf pj_unicode_vsprintf +# define pj_native_vsnprintf pj_unicode_vsnprintf +#else +# define pj_native_strcmp pj_ansi_strcmp +# define pj_native_strncmp pj_ansi_strncmp +# define pj_native_strlen pj_ansi_strlen +# define pj_native_strcpy pj_ansi_strcpy +# define pj_native_strncpy pj_ansi_strncpy +# define pj_native_strcat pj_ansi_strcat +# define pj_native_strstr pj_ansi_strstr +# define pj_native_strchr pj_ansi_strchr +# define pj_native_strcasecmp pj_ansi_strcasecmp +# define pj_native_stricmp pj_ansi_stricmp +# define pj_native_strncasecmp pj_ansi_strncasecmp +# define pj_native_strnicmp pj_ansi_strnicmp +# define pj_native_sprintf pj_ansi_sprintf +# define pj_native_snprintf pj_ansi_snprintf +# define pj_native_vsprintf pj_ansi_vsprintf +# define pj_native_vsnprintf pj_ansi_vsnprintf +#endif + + +#endif /* __PJ_COMPAT_STRING_H__ */ diff --git a/pjlib/include/pj/compat/time.h b/pjlib/include/pj/compat/time.h new file mode 100644 index 0000000..97d259a --- /dev/null +++ b/pjlib/include/pj/compat/time.h @@ -0,0 +1,42 @@ +/* $Id: time.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 + * + * 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_COMPAT_TIME_H__ +#define __PJ_COMPAT_TIME_H__ + +/** + * @file time.h + * @brief Provides ftime() and localtime() etc functions. + */ + +#if defined(PJ_HAS_TIME_H) && PJ_HAS_TIME_H != 0 +# include +#endif + +#if defined(PJ_HAS_SYS_TIME_H) && PJ_HAS_SYS_TIME_H != 0 +# include +#endif + +#if defined(PJ_HAS_SYS_TIMEB_H) && PJ_HAS_SYS_TIMEB_H != 0 +# include +#endif + + +#endif /* __PJ_COMPAT_TIME_H__ */ + diff --git a/pjlib/include/pj/config.h b/pjlib/include/pj/config.h new file mode 100644 index 0000000..629fa44 --- /dev/null +++ b/pjlib/include/pj/config.h @@ -0,0 +1,1211 @@ +/* $Id: config.h 4189 2012-07-03 03:11:24Z ming $ */ +/* + * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono + * + * 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_CONFIG_H__ +#define __PJ_CONFIG_H__ + + +/** + * @file config.h + * @brief PJLIB Main configuration settings. + */ + +/******************************************************************** + * Include compiler specific configuration. + */ +#if defined(_MSC_VER) +# include +#elif defined(__GNUC__) +# include +#elif defined(__CW32__) +# include +#elif defined(__MWERKS__) +# include +#elif defined(__GCCE__) +# include +#elif defined(__ARMCC__) +# include +#else +# error "Unknown compiler." +#endif + +/* PJ_ALIGN_DATA is compiler specific directive to align data address */ +#ifndef PJ_ALIGN_DATA +# error "PJ_ALIGN_DATA is not defined!" +#endif + +/******************************************************************** + * Include target OS specific configuration. + */ +#if defined(PJ_AUTOCONF) + /* + * Autoconf + */ +# include + +#elif defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0 + /* + * SymbianOS + */ +# include + +#elif defined(PJ_WIN32_WINCE) || defined(_WIN32_WCE) || defined(UNDER_CE) + /* + * Windows CE + */ +# undef PJ_WIN32_WINCE +# define PJ_WIN32_WINCE 1 +# include + + /* Also define Win32 */ +# define PJ_WIN32 1 + +#elif defined(PJ_WIN32) || defined(_WIN32) || defined(__WIN32__) || \ + defined(_WIN64) || defined(WIN32) || defined(__TOS_WIN__) + /* + * Win32 + */ +# undef PJ_WIN32 +# define PJ_WIN32 1 +# include + +#elif defined(PJ_LINUX_KERNEL) && PJ_LINUX_KERNEL!=0 + /* + * Linux kernel + */ +# include + +#elif defined(PJ_LINUX) || defined(linux) || defined(__linux) + /* + * Linux + */ +# undef PJ_LINUX +# define PJ_LINUX 1 +# include + +#elif defined(PJ_PALMOS) && PJ_PALMOS!=0 + /* + * Palm + */ +# include + +#elif defined(PJ_SUNOS) || defined(sun) || defined(__sun) + /* + * SunOS + */ +# undef PJ_SUNOS +# define PJ_SUNOS 1 +# include + +#elif defined(PJ_DARWINOS) || defined(__MACOSX__) || \ + defined (__APPLE__) || defined (__MACH__) + /* + * MacOS X + */ +# undef PJ_DARWINOS +# define PJ_DARWINOS 1 +# include + +#elif defined(PJ_RTEMS) && PJ_RTEMS!=0 + /* + * RTEMS + */ +# include +#else +# error "Please specify target os." +#endif + + +/******************************************************************** + * Target machine specific configuration. + */ +#if defined(PJ_AUTOCONF) + /* + * Autoconf configured + */ +#include + +#elif defined (PJ_M_I386) || defined(_i386_) || defined(i_386_) || \ + defined(_X86_) || defined(x86) || defined(__i386__) || \ + defined(__i386) || defined(_M_IX86) || defined(__I86__) + /* + * Generic i386 processor family, little-endian + */ +# undef PJ_M_I386 +# define PJ_M_I386 1 +# define PJ_M_NAME "i386" +# define PJ_HAS_PENTIUM 1 +# define PJ_IS_LITTLE_ENDIAN 1 +# define PJ_IS_BIG_ENDIAN 0 + + +#elif defined (PJ_M_X86_64) || defined(__amd64__) || defined(__amd64) || \ + defined(__x86_64__) || defined(__x86_64) + /* + * AMD 64bit processor, little endian + */ +# undef PJ_M_X86_64 +# define PJ_M_X86_64 1 +# define PJ_M_NAME "x86_64" +# define PJ_HAS_PENTIUM 1 +# define PJ_IS_LITTLE_ENDIAN 1 +# define PJ_IS_BIG_ENDIAN 0 + +#elif defined(PJ_M_IA64) || defined(__ia64__) || defined(_IA64) || \ + defined(__IA64__) || defined( _M_IA64) + /* + * Intel IA64 processor, default to little endian + */ +# undef PJ_M_IA64 +# define PJ_M_IA64 1 +# define PJ_M_NAME "ia64" +# define PJ_HAS_PENTIUM 1 +# define PJ_IS_LITTLE_ENDIAN 1 +# define PJ_IS_BIG_ENDIAN 0 + +#elif defined (PJ_M_M68K) && PJ_M_M68K != 0 + + /* + * Motorola m68k processor, big endian + */ +# undef PJ_M_M68K +# define PJ_M_M68K 1 +# define PJ_M_NAME "m68k" +# define PJ_HAS_PENTIUM 0 +# define PJ_IS_LITTLE_ENDIAN 0 +# define PJ_IS_BIG_ENDIAN 1 + + +#elif defined (PJ_M_ALPHA) || defined (__alpha__) || defined (__alpha) || \ + defined (_M_ALPHA) + /* + * DEC Alpha processor, little endian + */ +# undef PJ_M_ALPHA +# define PJ_M_ALPHA 1 +# define PJ_M_NAME "alpha" +# define PJ_HAS_PENTIUM 0 +# define PJ_IS_LITTLE_ENDIAN 1 +# define PJ_IS_BIG_ENDIAN 0 + + +#elif defined(PJ_M_MIPS) || defined(__mips__) || defined(__mips) || \ + defined(__MIPS__) || defined(MIPS) || defined(_MIPS_) + /* + * MIPS, bi-endian, so raise error if endianness is not configured + */ +# undef PJ_M_MIPS +# define PJ_M_MIPS 1 +# define PJ_M_NAME "mips" +# define PJ_HAS_PENTIUM 0 +# if !PJ_IS_LITTLE_ENDIAN && !PJ_IS_BIG_ENDIAN +# error Endianness must be declared for this processor +# endif + + +#elif defined (PJ_M_SPARC) || defined( __sparc__) || defined(__sparc) + /* + * Sun Sparc, big endian + */ +# undef PJ_M_SPARC +# define PJ_M_SPARC 1 +# define PJ_M_NAME "sparc" +# define PJ_HAS_PENTIUM 0 +# define PJ_IS_LITTLE_ENDIAN 0 +# define PJ_IS_BIG_ENDIAN 1 + +#elif defined (PJ_M_ARMV4) || defined(ARM) || defined(_ARM_) || \ + defined(ARMV4) || defined(__arm__) + /* + * ARM, bi-endian, so raise error if endianness is not configured + */ +# undef PJ_M_ARMV4 +# define PJ_M_ARMV4 1 +# define PJ_M_NAME "armv4" +# define PJ_HAS_PENTIUM 0 +# if !PJ_IS_LITTLE_ENDIAN && !PJ_IS_BIG_ENDIAN +# error Endianness must be declared for this processor +# endif + +#elif defined (PJ_M_POWERPC) || defined(__powerpc) || defined(__powerpc__) || \ + defined(__POWERPC__) || defined(__ppc__) || defined(_M_PPC) || \ + defined(_ARCH_PPC) + /* + * PowerPC, bi-endian, so raise error if endianness is not configured + */ +# undef PJ_M_POWERPC +# define PJ_M_POWERPC 1 +# define PJ_M_NAME "powerpc" +# define PJ_HAS_PENTIUM 0 +# if !PJ_IS_LITTLE_ENDIAN && !PJ_IS_BIG_ENDIAN +# error Endianness must be declared for this processor +# endif + +#elif defined (PJ_M_NIOS2) || defined(__nios2) || defined(__nios2__) || \ + defined(__NIOS2__) || defined(__M_NIOS2) || defined(_ARCH_NIOS2) + /* + * Nios2, little endian + */ +# undef PJ_M_NIOS2 +# define PJ_M_NIOS2 1 +# define PJ_M_NAME "nios2" +# define PJ_HAS_PENTIUM 0 +# define PJ_IS_LITTLE_ENDIAN 1 +# define PJ_IS_BIG_ENDIAN 0 + +#else +# error "Please specify target machine." +#endif + +/* Include size_t definition. */ +#include + +/* Include site/user specific configuration to control PJLIB features. + * YOU MUST CREATE THIS FILE YOURSELF!! + */ +#include + +/******************************************************************** + * PJLIB Features. + */ + +/* Overrides for DOXYGEN */ +#ifdef DOXYGEN +# undef PJ_FUNCTIONS_ARE_INLINED +# undef PJ_HAS_FLOATING_POINT +# undef PJ_LOG_MAX_LEVEL +# undef PJ_LOG_MAX_SIZE +# undef PJ_LOG_USE_STACK_BUFFER +# undef PJ_TERM_HAS_COLOR +# undef PJ_POOL_DEBUG +# undef PJ_HAS_TCP +# undef PJ_MAX_HOSTNAME +# undef PJ_IOQUEUE_MAX_HANDLES +# undef FD_SETSIZE +# undef PJ_HAS_SEMAPHORE +# undef PJ_HAS_EVENT_OBJ +# undef PJ_ENABLE_EXTRA_CHECK +# undef PJ_EXCEPTION_USE_WIN32_SEH +# undef PJ_HAS_ERROR_STRING + +# define PJ_HAS_IPV6 1 +#endif + +/** + * @defgroup pj_config Build Configuration + * @{ + * + * This section contains macros that can set during PJLIB build process + * to controll various aspects of the library. + * + * Note: the values in this page does NOT necessarily reflect to the + * macro values during the build process. + */ + +/** + * If this macro is set to 1, it will enable some debugging checking + * in the library. + * + * Default: equal to (NOT NDEBUG). + */ +#ifndef PJ_DEBUG +# ifndef NDEBUG +# define PJ_DEBUG 1 +# else +# define PJ_DEBUG 0 +# endif +#endif + +/** + * Enable this macro to activate logging to mutex/semaphore related events. + * This is useful to troubleshoot concurrency problems such as deadlocks. + * In addition, you should also add PJ_LOG_HAS_THREAD_ID flag to the + * log decoration to assist the troubleshooting. + * + * Default: 0 + */ +#ifndef PJ_DEBUG_MUTEX +# define PJ_DEBUG_MUTEX 0 +#endif + +/** + * Expand functions in *_i.h header files as inline. + * + * Default: 0. + */ +#ifndef PJ_FUNCTIONS_ARE_INLINED +# define PJ_FUNCTIONS_ARE_INLINED 0 +#endif + +/** + * Use floating point computations in the library. + * + * Default: 1. + */ +#ifndef PJ_HAS_FLOATING_POINT +# define PJ_HAS_FLOATING_POINT 1 +#endif + +/** + * Declare maximum logging level/verbosity. Lower number indicates higher + * importance, with the highest importance has level zero. The least + * important level is five in this implementation, but this can be extended + * by supplying the appropriate implementation. + * + * The level conventions: + * - 0: fatal error + * - 1: error + * - 2: warning + * - 3: info + * - 4: debug + * - 5: trace + * - 6: more detailed trace + * + * Default: 4 + */ +#ifndef PJ_LOG_MAX_LEVEL +# define PJ_LOG_MAX_LEVEL 5 +#endif + +/** + * Maximum message size that can be sent to output device for each call + * to PJ_LOG(). If the message size is longer than this value, it will be cut. + * This may affect the stack usage, depending whether PJ_LOG_USE_STACK_BUFFER + * flag is set. + * + * Default: 4000 + */ +#ifndef PJ_LOG_MAX_SIZE +# define PJ_LOG_MAX_SIZE 4000 +#endif + +/** + * Log buffer. + * Does the log get the buffer from the stack? (default is yes). + * If the value is set to NO, then the buffer will be taken from static + * buffer, which in this case will make the log function non-reentrant. + * + * Default: 1 + */ +#ifndef PJ_LOG_USE_STACK_BUFFER +# define PJ_LOG_USE_STACK_BUFFER 1 +#endif + +/** + * Enable log indentation feature. + * + * Default: 1 + */ +#ifndef PJ_LOG_ENABLE_INDENT +# define PJ_LOG_ENABLE_INDENT 1 +#endif + +/** + * Number of PJ_LOG_INDENT_CHAR to put every time pj_log_push_indent() + * is called. + * + * Default: 1 + */ +#ifndef PJ_LOG_INDENT_SIZE +# define PJ_LOG_INDENT_SIZE 1 +#endif + +/** + * Log indentation character. + * + * Default: space + */ +#ifndef PJ_LOG_INDENT_CHAR +# define PJ_LOG_INDENT_CHAR '.' +#endif + +/** + * Colorfull terminal (for logging etc). + * + * Default: 1 + */ +#ifndef PJ_TERM_HAS_COLOR +# define PJ_TERM_HAS_COLOR 1 +#endif + + +/** + * Set this flag to non-zero to enable various checking for pool + * operations. When this flag is set, assertion must be enabled + * in the application. + * + * This will slow down pool creation and destruction and will add + * few bytes of overhead, so application would normally want to + * disable this feature on release build. + * + * Default: 0 + */ +#ifndef PJ_SAFE_POOL +# define PJ_SAFE_POOL 0 +#endif + + +/** + * If pool debugging is used, then each memory allocation from the pool + * will call malloc(), and pool will release all memory chunks when it + * is destroyed. This works better when memory verification programs + * such as Rational Purify is used. + * + * Default: 0 + */ +#ifndef PJ_POOL_DEBUG +# define PJ_POOL_DEBUG 0 +#endif + + +/** + * Enable timer heap debugging facility. When this is enabled, application + * can call pj_timer_heap_dump() to show the contents of the timer heap + * along with the source location where the timer entries were scheduled. + * See https://trac.pjsip.org/repos/ticket/1527 for more info. + * + * Default: 0 + */ +#ifndef PJ_TIMER_DEBUG +# define PJ_TIMER_DEBUG 0 +#endif + + +/** + * Specify this as \a stack_size argument in #pj_thread_create() to specify + * that thread should use default stack size for the current platform. + * + * Default: 8192 + */ +#ifndef PJ_THREAD_DEFAULT_STACK_SIZE +# define PJ_THREAD_DEFAULT_STACK_SIZE 8192 +#endif + + +/** + * Specify if PJ_CHECK_STACK() macro is enabled to check the sanity of + * the stack. The OS implementation may check that no stack overflow + * occurs, and it also may collect statistic about stack usage. Note + * that this will increase the footprint of the libraries since it + * tracks the filename and line number of each functions. + */ +#ifndef PJ_OS_HAS_CHECK_STACK +# define PJ_OS_HAS_CHECK_STACK 0 +#endif + +/** + * Do we have alternate pool implementation? + * + * Default: 0 + */ +#ifndef PJ_HAS_POOL_ALT_API +# define PJ_HAS_POOL_ALT_API PJ_POOL_DEBUG +#endif + + +/** + * Support TCP in the library. + * Disabling TCP will reduce the footprint slightly (about 6KB). + * + * Default: 1 + */ +#ifndef PJ_HAS_TCP +# define PJ_HAS_TCP 1 +#endif + +/** + * Support IPv6 in the library. If this support is disabled, some IPv6 + * related functions will return PJ_EIPV6NOTSUP. + * + * Default: 0 (disabled, for now) + */ +#ifndef PJ_HAS_IPV6 +# define PJ_HAS_IPV6 0 +#endif + + /** + * Maximum hostname length. + * Libraries sometimes needs to make copy of an address to stack buffer; + * the value here affects the stack usage. + * + * Default: 128 + */ +#ifndef PJ_MAX_HOSTNAME +# define PJ_MAX_HOSTNAME (128) +#endif + +/** + * Maximum consecutive identical error for accept() operation before + * activesock stops calling the next ioqueue accept. + * + * Default: 50 + */ +#ifndef PJ_ACTIVESOCK_MAX_CONSECUTIVE_ACCEPT_ERROR +# define PJ_ACTIVESOCK_MAX_CONSECUTIVE_ACCEPT_ERROR 50 +#endif + +/** + * Constants for declaring the maximum handles that can be supported by + * a single IOQ framework. This constant might not be relevant to the + * underlying I/O queue impelementation, but still, developers should be + * aware of this constant, to make sure that the program will not break when + * the underlying implementation changes. + */ +#ifndef PJ_IOQUEUE_MAX_HANDLES +# define PJ_IOQUEUE_MAX_HANDLES (64) +#endif + + +/** + * If PJ_IOQUEUE_HAS_SAFE_UNREG macro is defined, then ioqueue will do more + * things to ensure thread safety of handle unregistration operation by + * employing reference counter to each handle. + * + * In addition, the ioqueue will preallocate memory for the handles, + * according to the maximum number of handles that is specified during + * ioqueue creation. + * + * All applications would normally want this enabled, but you may disable + * this if: + * - there is no dynamic unregistration to all ioqueues. + * - there is no threading, or there is no preemptive multitasking. + * + * Default: 1 + */ +#ifndef PJ_IOQUEUE_HAS_SAFE_UNREG +# define PJ_IOQUEUE_HAS_SAFE_UNREG 1 +#endif + + +/** + * Default concurrency setting for sockets/handles registered to ioqueue. + * This controls whether the ioqueue is allowed to call the key's callback + * concurrently/in parallel. The default is yes, which means that if there + * are more than one pending operations complete simultaneously, more + * than one threads may call the key's callback at the same time. This + * generally would promote good scalability for application, at the + * expense of more complexity to manage the concurrent accesses. + * + * Please see the ioqueue documentation for more info. + */ +#ifndef PJ_IOQUEUE_DEFAULT_ALLOW_CONCURRENCY +# define PJ_IOQUEUE_DEFAULT_ALLOW_CONCURRENCY 1 +#endif + + +/* Sanity check: + * if ioqueue concurrency is disallowed, PJ_IOQUEUE_HAS_SAFE_UNREG + * must be enabled. + */ +#if (PJ_IOQUEUE_DEFAULT_ALLOW_CONCURRENCY==0) && (PJ_IOQUEUE_HAS_SAFE_UNREG==0) +# error PJ_IOQUEUE_HAS_SAFE_UNREG must be enabled if ioqueue concurrency \ + is disabled +#endif + + +/** + * When safe unregistration (PJ_IOQUEUE_HAS_SAFE_UNREG) is configured in + * ioqueue, the PJ_IOQUEUE_KEY_FREE_DELAY macro specifies how long the + * ioqueue key is kept in closing state before it can be reused. + * + * The value is in miliseconds. + * + * Default: 500 msec. + */ +#ifndef PJ_IOQUEUE_KEY_FREE_DELAY +# define PJ_IOQUEUE_KEY_FREE_DELAY 500 +#endif + + +/** + * Determine if FD_SETSIZE is changeable/set-able. If so, then we will + * set it to PJ_IOQUEUE_MAX_HANDLES. Currently we detect this by checking + * for Winsock. + */ +#ifndef PJ_FD_SETSIZE_SETABLE +# if (defined(PJ_HAS_WINSOCK_H) && PJ_HAS_WINSOCK_H!=0) || \ + (defined(PJ_HAS_WINSOCK2_H) && PJ_HAS_WINSOCK2_H!=0) +# define PJ_FD_SETSIZE_SETABLE 1 +# else +# define PJ_FD_SETSIZE_SETABLE 0 +# endif +#endif + +/** + * Overrides FD_SETSIZE so it is consistent throughout the library. + * We only do this if we detected that FD_SETSIZE is changeable. If + * FD_SETSIZE is not set-able, then PJ_IOQUEUE_MAX_HANDLES must be + * set to value lower than FD_SETSIZE. + */ +#if PJ_FD_SETSIZE_SETABLE + /* Only override FD_SETSIZE if the value has not been set */ +# ifndef FD_SETSIZE +# define FD_SETSIZE PJ_IOQUEUE_MAX_HANDLES +# endif +#else + /* When FD_SETSIZE is not changeable, check if PJ_IOQUEUE_MAX_HANDLES + * is lower than FD_SETSIZE value. + */ +# ifdef FD_SETSIZE +# if PJ_IOQUEUE_MAX_HANDLES > FD_SETSIZE +# error "PJ_IOQUEUE_MAX_HANDLES is greater than FD_SETSIZE" +# endif +# endif +#endif + + +/** + * Specify whether #pj_enum_ip_interface() function should exclude + * loopback interfaces. + * + * Default: 1 + */ +#ifndef PJ_IP_HELPER_IGNORE_LOOPBACK_IF +# define PJ_IP_HELPER_IGNORE_LOOPBACK_IF 1 +#endif + + +/** + * Has semaphore functionality? + * + * Default: 1 + */ +#ifndef PJ_HAS_SEMAPHORE +# define PJ_HAS_SEMAPHORE 1 +#endif + + +/** + * Event object (for synchronization, e.g. in Win32) + * + * Default: 1 + */ +#ifndef PJ_HAS_EVENT_OBJ +# define PJ_HAS_EVENT_OBJ 1 +#endif + + +/** + * Maximum file name length. + */ +#ifndef PJ_MAXPATH +# define PJ_MAXPATH 260 +#endif + + +/** + * Enable library's extra check. + * If this macro is enabled, #PJ_ASSERT_RETURN macro will expand to + * run-time checking. If this macro is disabled, #PJ_ASSERT_RETURN + * will simply evaluate to #pj_assert(). + * + * You can disable this macro to reduce size, at the risk of crashes + * if invalid value (e.g. NULL) is passed to the library. + * + * Default: 1 + */ +#ifndef PJ_ENABLE_EXTRA_CHECK +# define PJ_ENABLE_EXTRA_CHECK 1 +#endif + + +/** + * Enable name registration for exceptions with #pj_exception_id_alloc(). + * If this feature is enabled, then the library will keep track of + * names associated with each exception ID requested by application via + * #pj_exception_id_alloc(). + * + * Disabling this macro will reduce the code and .bss size by a tad bit. + * See also #PJ_MAX_EXCEPTION_ID. + * + * Default: 1 + */ +#ifndef PJ_HAS_EXCEPTION_NAMES +# define PJ_HAS_EXCEPTION_NAMES 1 +#endif + +/** + * Maximum number of unique exception IDs that can be requested + * with #pj_exception_id_alloc(). For each entry, a small record will + * be allocated in the .bss segment. + * + * Default: 16 + */ +#ifndef PJ_MAX_EXCEPTION_ID +# define PJ_MAX_EXCEPTION_ID 16 +#endif + +/** + * Should we use Windows Structured Exception Handling (SEH) for the + * PJLIB exceptions. + * + * Default: 0 + */ +#ifndef PJ_EXCEPTION_USE_WIN32_SEH +# define PJ_EXCEPTION_USE_WIN32_SEH 0 +#endif + +/** + * Should we attempt to use Pentium's rdtsc for high resolution + * timestamp. + * + * Default: 0 + */ +#ifndef PJ_TIMESTAMP_USE_RDTSC +# define PJ_TIMESTAMP_USE_RDTSC 0 +#endif + +/** + * Is native platform error positive number? + * Default: 1 (yes) + */ +#ifndef PJ_NATIVE_ERR_POSITIVE +# define PJ_NATIVE_ERR_POSITIVE 1 +#endif + +/** + * Include error message string in the library (pj_strerror()). + * This is very much desirable! + * + * Default: 1 + */ +#ifndef PJ_HAS_ERROR_STRING +# define PJ_HAS_ERROR_STRING 1 +#endif + + +/** + * Include pj_stricmp_alnum() and pj_strnicmp_alnum(), i.e. custom + * functions to compare alnum strings. On some systems, they're faster + * then stricmp/strcasecmp, but they can be slower on other systems. + * When disabled, pjlib will fallback to stricmp/strnicmp. + * + * Default: 0 + */ +#ifndef PJ_HAS_STRICMP_ALNUM +# define PJ_HAS_STRICMP_ALNUM 0 +#endif + + +/* + * Types of QoS backend implementation. + */ + +/** + * Dummy QoS backend implementation, will always return error on all + * the APIs. + */ +#define PJ_QOS_DUMMY 1 + +/** QoS backend based on setsockopt(IP_TOS) */ +#define PJ_QOS_BSD 2 + +/** QoS backend for Windows Mobile 6 */ +#define PJ_QOS_WM 3 + +/** QoS backend for Symbian */ +#define PJ_QOS_SYMBIAN 4 + +/** + * Force the use of some QoS backend API for some platforms. + */ +#ifndef PJ_QOS_IMPLEMENTATION +# if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE && _WIN32_WCE >= 0x502 + /* Windows Mobile 6 or later */ +# define PJ_QOS_IMPLEMENTATION PJ_QOS_WM +# endif +#endif + + +/** + * Enable secure socket. For most platforms, this is implemented using + * OpenSSL, so this will require OpenSSL to be installed. For Symbian + * platform, this is implemented natively using CSecureSocket. + * + * Default: 0 (for now) + */ +#ifndef PJ_HAS_SSL_SOCK +# define PJ_HAS_SSL_SOCK 0 +#endif + + +/** + * Disable WSAECONNRESET error for UDP sockets on Win32 platforms. See + * https://trac.pjsip.org/repos/ticket/1197. + * + * Default: 1 + */ +#ifndef PJ_SOCK_DISABLE_WSAECONNRESET +# define PJ_SOCK_DISABLE_WSAECONNRESET 1 +#endif + + +/** @} */ + +/******************************************************************** + * General macros. + */ + +/** + * @defgroup pj_dll_target Building Dynamic Link Libraries (DLL/DSO) + * @ingroup pj_config + * @{ + * + * The libraries support generation of dynamic link libraries for + * Symbian ABIv2 target (.dso/Dynamic Shared Object files, in Symbian + * terms). Similar procedures may be applied for Win32 DLL with some + * modification. + * + * Depending on the platforms, these steps may be necessary in order to + * produce the dynamic libraries: + * - Create the (Visual Studio) projects to produce DLL output. PJLIB + * does not provide ready to use project files to produce DLL, so + * you need to create these projects yourself. For Symbian, the MMP + * files have been setup to produce DSO files for targets that + * require them. + * - In the (Visual Studio) projects, some macros need to be declared + * so that appropriate modifiers are added to symbol declarations + * and definitions. Please see the macro section below for information + * regarding these macros. For Symbian, these have been taken care by the + * MMP files. + * - Some build systems require .DEF file to be specified when creating + * the DLL. For Symbian, .DEF files are included in pjlib distribution, + * in pjlib/build.symbian directory. These DEF files are + * created by running ./makedef.sh all from this directory, + * inside Mingw. + * + * Macros related for building DLL/DSO files: + * - For platforms that supports dynamic link libraries generation, + * it must declare PJ_EXPORT_SPECIFIER macro which value contains + * the prefix to be added to symbol definition, to export this + * symbol in the DLL/DSO. For example, on Win32/Visual Studio, the + * value of this macro is \a __declspec(dllexport), and for ARM + * ABIv2/Symbian, the value is \a EXPORT_C. + * - For platforms that supports linking with dynamic link libraries, + * it must declare PJ_IMPORT_SPECIFIER macro which value contains + * the prefix to be added to symbol declaration, to import this + * symbol from a DLL/DSO. For example, on Win32/Visual Studio, the + * value of this macro is \a __declspec(dllimport), and for ARM + * ABIv2/Symbian, the value is \a IMPORT_C. + * - Both PJ_EXPORT_SPECIFIER and PJ_IMPORT_SPECIFIER + * macros above can be declared in your \a config_site.h if they are not + * declared by pjlib. + * - When PJLIB is built as DLL/DSO, both PJ_DLL and + * PJ_EXPORTING macros must be declared, so that + * PJ_EXPORT_SPECIFIER modifier will be added into function + * definition. + * - When application wants to link dynamically with PJLIB, then it + * must declare PJ_DLL macro when using/including PJLIB header, + * so that PJ_IMPORT_SPECIFIER modifier is properly added into + * symbol declarations. + * + * When PJ_DLL macro is not declared, static linking is assumed. + * + * For example, here are some settings to produce DLLs with Visual Studio + * on Windows/Win32: + * - Create Visual Studio projects to produce DLL. Add the appropriate + * project dependencies to avoid link errors. + * - In the projects, declare PJ_DLL and PJ_EXPORTING + * macros. + * - Declare these macros in your config_site.h: + \verbatim + #define PJ_EXPORT_SPECIFIER __declspec(dllexport) + #define PJ_IMPORT_SPECIFIER __declspec(dllimport) + \endverbatim + * - And in the application (that links with the DLL) project, add + * PJ_DLL in the macro declarations. + */ + +/** @} */ + +/** + * @defgroup pj_config Build Configuration + * @{ + */ + +/** + * @def PJ_INLINE(type) + * @param type The return type of the function. + * Expand the function as inline. + */ +#define PJ_INLINE(type) PJ_INLINE_SPECIFIER type + +/** + * This macro declares platform/compiler specific specifier prefix + * to be added to symbol declaration to export the symbol when PJLIB + * is built as dynamic library. + * + * This macro should have been added by platform specific headers, + * if the platform supports building dynamic library target. + */ +#ifndef PJ_EXPORT_DECL_SPECIFIER +# define PJ_EXPORT_DECL_SPECIFIER +#endif + + +/** + * This macro declares platform/compiler specific specifier prefix + * to be added to symbol definition to export the symbol when PJLIB + * is built as dynamic library. + * + * This macro should have been added by platform specific headers, + * if the platform supports building dynamic library target. + */ +#ifndef PJ_EXPORT_DEF_SPECIFIER +# define PJ_EXPORT_DEF_SPECIFIER +#endif + + +/** + * This macro declares platform/compiler specific specifier prefix + * to be added to symbol declaration to import the symbol. + * + * This macro should have been added by platform specific headers, + * if the platform supports building dynamic library target. + */ +#ifndef PJ_IMPORT_DECL_SPECIFIER +# define PJ_IMPORT_DECL_SPECIFIER +#endif + + +/** + * This macro has been deprecated. It will evaluate to nothing. + */ +#ifndef PJ_EXPORT_SYMBOL +# define PJ_EXPORT_SYMBOL(x) +#endif + + +/** + * @def PJ_DECL(type) + * @param type The return type of the function. + * Declare a function. + */ +#if defined(PJ_DLL) +# if defined(PJ_EXPORTING) +# define PJ_DECL(type) PJ_EXPORT_DECL_SPECIFIER type +# else +# define PJ_DECL(type) PJ_IMPORT_DECL_SPECIFIER type +# endif +#elif !defined(PJ_DECL) +# if defined(__cplusplus) +# define PJ_DECL(type) type +# else +# define PJ_DECL(type) extern type +# endif +#endif + + +/** + * @def PJ_DEF(type) + * @param type The return type of the function. + * Define a function. + */ +#if defined(PJ_DLL) && defined(PJ_EXPORTING) +# define PJ_DEF(type) PJ_EXPORT_DEF_SPECIFIER type +#elif !defined(PJ_DEF) +# define PJ_DEF(type) type +#endif + + +/** + * @def PJ_DECL_NO_RETURN(type) + * @param type The return type of the function. + * Declare a function that will not return. + */ +/** + * @def PJ_IDECL_NO_RETURN(type) + * @param type The return type of the function. + * Declare an inline function that will not return. + */ +/** + * @def PJ_BEGIN_DECL + * Mark beginning of declaration section in a header file. + */ +/** + * @def PJ_END_DECL + * Mark end of declaration section in a header file. + */ +#ifdef __cplusplus +# define PJ_DECL_NO_RETURN(type) PJ_DECL(type) PJ_NORETURN +# define PJ_IDECL_NO_RETURN(type) PJ_INLINE(type) PJ_NORETURN +# define PJ_BEGIN_DECL extern "C" { +# define PJ_END_DECL } +#else +# define PJ_DECL_NO_RETURN(type) PJ_NORETURN PJ_DECL(type) +# define PJ_IDECL_NO_RETURN(type) PJ_NORETURN PJ_INLINE(type) +# define PJ_BEGIN_DECL +# define PJ_END_DECL +#endif + + + +/** + * @def PJ_DECL_DATA(type) + * @param type The data type. + * Declare a global data. + */ +#if defined(PJ_DLL) +# if defined(PJ_EXPORTING) +# define PJ_DECL_DATA(type) PJ_EXPORT_DECL_SPECIFIER extern type +# else +# define PJ_DECL_DATA(type) PJ_IMPORT_DECL_SPECIFIER extern type +# endif +#elif !defined(PJ_DECL_DATA) +# define PJ_DECL_DATA(type) extern type +#endif + + +/** + * @def PJ_DEF_DATA(type) + * @param type The data type. + * Define a global data. + */ +#if defined(PJ_DLL) && defined(PJ_EXPORTING) +# define PJ_DEF_DATA(type) PJ_EXPORT_DEF_SPECIFIER type +#elif !defined(PJ_DEF_DATA) +# define PJ_DEF_DATA(type) type +#endif + + +/** + * @def PJ_IDECL(type) + * @param type The function's return type. + * Declare a function that may be expanded as inline. + */ +/** + * @def PJ_IDEF(type) + * @param type The function's return type. + * Define a function that may be expanded as inline. + */ + +#if PJ_FUNCTIONS_ARE_INLINED +# define PJ_IDECL(type) PJ_INLINE(type) +# define PJ_IDEF(type) PJ_INLINE(type) +#else +# define PJ_IDECL(type) PJ_DECL(type) +# define PJ_IDEF(type) PJ_DEF(type) +#endif + + +/** + * @def PJ_UNUSED_ARG(arg) + * @param arg The argument name. + * PJ_UNUSED_ARG prevents warning about unused argument in a function. + */ +#define PJ_UNUSED_ARG(arg) (void)arg + +/** + * @def PJ_TODO(id) + * @param id Any identifier that will be printed as TODO message. + * PJ_TODO macro will display TODO message as warning during compilation. + * Example: PJ_TODO(CLEAN_UP_ERROR); + */ +#ifndef PJ_TODO +# define PJ_TODO(id) TODO___##id: +#endif + +/** + * Function attributes to inform that the function may throw exception. + * + * @param x The exception list, enclosed in parenthesis. + */ +#define __pj_throw__(x) + +/** @} */ + +/******************************************************************** + * Sanity Checks + */ +#ifndef PJ_HAS_HIGH_RES_TIMER +# error "PJ_HAS_HIGH_RES_TIMER is not defined!" +#endif + +#if !defined(PJ_HAS_PENTIUM) +# error "PJ_HAS_PENTIUM is not defined!" +#endif + +#if !defined(PJ_IS_LITTLE_ENDIAN) +# error "PJ_IS_LITTLE_ENDIAN is not defined!" +#endif + +#if !defined(PJ_IS_BIG_ENDIAN) +# error "PJ_IS_BIG_ENDIAN is not defined!" +#endif + +#if !defined(PJ_EMULATE_RWMUTEX) +# error "PJ_EMULATE_RWMUTEX should be defined in compat/os_xx.h" +#endif + +#if !defined(PJ_THREAD_SET_STACK_SIZE) +# error "PJ_THREAD_SET_STACK_SIZE should be defined in compat/os_xx.h" +#endif + +#if !defined(PJ_THREAD_ALLOCATE_STACK) +# error "PJ_THREAD_ALLOCATE_STACK should be defined in compat/os_xx.h" +#endif + +PJ_BEGIN_DECL + +/** PJLIB version major number. */ +#define PJ_VERSION_NUM_MAJOR 2 + +/** PJLIB version minor number. */ +#define PJ_VERSION_NUM_MINOR 0 + +/** PJLIB version revision number. */ +#define PJ_VERSION_NUM_REV 1 + +/** + * Extra suffix for the version (e.g. "-trunk"), or empty for + * web release version. + */ +#define PJ_VERSION_NUM_EXTRA "" + +/** + * PJLIB version number consists of three bytes with the following format: + * 0xMMIIRR00, where MM: major number, II: minor number, RR: revision + * number, 00: always zero for now. + */ +#define PJ_VERSION_NUM ((PJ_VERSION_NUM_MAJOR << 24) | \ + (PJ_VERSION_NUM_MINOR << 16) | \ + (PJ_VERSION_NUM_REV << 8)) + +/** + * PJLIB version string constant. @see pj_get_version() + */ +PJ_DECL_DATA(const char*) PJ_VERSION; + +/** + * Get PJLIB version string. + * + * @return #PJ_VERSION constant. + */ +PJ_DECL(const char*) pj_get_version(void); + +/** + * Dump configuration to log with verbosity equal to info(3). + */ +PJ_DECL(void) pj_dump_config(void); + +PJ_END_DECL + + +#endif /* __PJ_CONFIG_H__ */ + diff --git a/pjlib/include/pj/config_site_sample.h b/pjlib/include/pj/config_site_sample.h new file mode 100644 index 0000000..0c7832f --- /dev/null +++ b/pjlib/include/pj/config_site_sample.h @@ -0,0 +1,407 @@ +/* + * This file contains several sample settings especially for Windows + * Mobile and Symbian targets. You can include this file in your + * file. + * + * The Windows Mobile and Symbian settings will be activated + * automatically if you include this file. + * + * In addition, you may specify one of these macros (before including + * this file) to activate additional settings: + * + * #define PJ_CONFIG_NOKIA_APS_DIRECT + * Use this macro to activate the APS-Direct feature. Please see + * http://trac.pjsip.org/repos/wiki/Nokia_APS_VAS_Direct for more + * info. + * + * #define PJ_CONFIG_WIN32_WMME_DIRECT + * Configuration to activate "APS-Direct" media mode on Windows or + * Windows Mobile, useful for testing purposes only. + */ + + +/* + * Typical configuration for WinCE target. + */ +#if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0 + + /* + * PJLIB settings. + */ + + /* Disable floating point support */ + #define PJ_HAS_FLOATING_POINT 0 + + /* + * PJMEDIA settings + */ + + /* Select codecs to disable */ + #define PJMEDIA_HAS_L16_CODEC 0 + #define PJMEDIA_HAS_ILBC_CODEC 0 + + /* We probably need more buffers on WM, so increase the limit */ + #define PJMEDIA_SOUND_BUFFER_COUNT 32 + + /* Fine tune Speex's default settings for best performance/quality */ + #define PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY 5 + + /* For CPU reason, disable speex AEC and use the echo suppressor. */ + #define PJMEDIA_HAS_SPEEX_AEC 0 + + /* Previously, resampling is disabled due to performance reason and + * this condition prevented some 'light' wideband codecs (e.g: G722.1) + * to work along with narrowband codecs. Lately, some tests showed + * that 16kHz <-> 8kHz resampling using libresample small filter was + * affordable on ARM9 260 MHz, so here we decided to enable resampling. + * Note that it is important to make sure that libresample is created + * using small filter. For example PJSUA_DEFAULT_CODEC_QUALITY must + * be set to 3 or 4 so pjsua-lib will apply small filter resampling. + */ + //#define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_NONE + #define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_LIBRESAMPLE + + /* Use the lighter WSOLA implementation */ + #define PJMEDIA_WSOLA_IMP PJMEDIA_WSOLA_IMP_WSOLA_LITE + + /* + * PJSIP settings. + */ + + /* Set maximum number of dialog/transaction/calls to minimum to reduce + * memory usage + */ + #define PJSIP_MAX_TSX_COUNT 31 + #define PJSIP_MAX_DIALOG_COUNT 31 + #define PJSUA_MAX_CALLS 4 + + /* + * PJSUA settings + */ + + /* Default codec quality, previously was set to 5, however it is now + * set to 4 to make sure pjsua instantiates resampler with small filter. + */ + #define PJSUA_DEFAULT_CODEC_QUALITY 4 + + /* Set maximum number of objects to minimum to reduce memory usage */ + #define PJSUA_MAX_ACC 4 + #define PJSUA_MAX_PLAYERS 4 + #define PJSUA_MAX_RECORDERS 4 + #define PJSUA_MAX_CONF_PORTS (PJSUA_MAX_CALLS+2*PJSUA_MAX_PLAYERS) + #define PJSUA_MAX_BUDDIES 32 + +#endif /* PJ_WIN32_WINCE */ + + +/* + * Typical configuration for Symbian OS target + */ +#if defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0 + + /* + * PJLIB settings. + */ + + /* Disable floating point support */ + #define PJ_HAS_FLOATING_POINT 0 + + /* Misc PJLIB setting */ + #define PJ_MAXPATH 80 + + /* This is important for Symbian. Symbian lacks vsnprintf(), so + * if the log buffer is not long enough it's possible that + * large incoming packet will corrupt memory when the log tries + * to log the packet. + */ + #define PJ_LOG_MAX_SIZE (PJSIP_MAX_PKT_LEN+500) + + /* Since we don't have threads, log buffer can use static buffer + * rather than stack + */ + #define PJ_LOG_USE_STACK_BUFFER 0 + + /* Disable check stack since it increases footprint */ + #define PJ_OS_HAS_CHECK_STACK 0 + + + /* + * PJMEDIA settings + */ + + /* Disable non-Symbian audio devices */ + #define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO 0 + #define PJMEDIA_AUDIO_DEV_HAS_WMME 0 + + /* Select codecs to disable */ + #define PJMEDIA_HAS_L16_CODEC 0 + #define PJMEDIA_HAS_ILBC_CODEC 0 + #define PJMEDIA_HAS_G722_CODEC 0 + + /* Fine tune Speex's default settings for best performance/quality */ + #define PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY 5 + + /* For CPU reason, disable speex AEC and use the echo suppressor. */ + #define PJMEDIA_HAS_SPEEX_AEC 0 + + /* Previously, resampling is disabled due to performance reason and + * this condition prevented some 'light' wideband codecs (e.g: G722.1) + * to work along with narrowband codecs. Lately, some tests showed + * that 16kHz <-> 8kHz resampling using libresample small filter was + * affordable on ARM9 222 MHz, so here we decided to enable resampling. + * Note that it is important to make sure that libresample is created + * using small filter. For example PJSUA_DEFAULT_CODEC_QUALITY must + * be set to 3 or 4 so pjsua-lib will apply small filter resampling. + */ + //#define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_NONE + #define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_LIBRESAMPLE + + /* Use the lighter WSOLA implementation */ + #define PJMEDIA_WSOLA_IMP PJMEDIA_WSOLA_IMP_WSOLA_LITE + + /* We probably need more buffers especially if MDA audio backend + * is used, so increase the limit + */ + #define PJMEDIA_SOUND_BUFFER_COUNT 32 + + /* + * PJSIP settings. + */ + + /* Disable safe module access, since we don't use multithreading */ + #define PJSIP_SAFE_MODULE 0 + + /* Use large enough packet size */ + #define PJSIP_MAX_PKT_LEN 2000 + + /* Symbian has problem with too many large blocks */ + #define PJSIP_POOL_LEN_ENDPT 1000 + #define PJSIP_POOL_INC_ENDPT 1000 + #define PJSIP_POOL_RDATA_LEN 2000 + #define PJSIP_POOL_RDATA_INC 2000 + #define PJSIP_POOL_LEN_TDATA 2000 + #define PJSIP_POOL_INC_TDATA 512 + #define PJSIP_POOL_LEN_UA 2000 + #define PJSIP_POOL_INC_UA 1000 + #define PJSIP_POOL_TSX_LAYER_LEN 256 + #define PJSIP_POOL_TSX_LAYER_INC 256 + #define PJSIP_POOL_TSX_LEN 512 + #define PJSIP_POOL_TSX_INC 128 + + /* + * PJSUA settings. + */ + + /* Default codec quality, previously was set to 5, however it is now + * set to 4 to make sure pjsua instantiates resampler with small filter. + */ + #define PJSUA_DEFAULT_CODEC_QUALITY 4 + + /* Set maximum number of dialog/transaction/calls to minimum */ + #define PJSIP_MAX_TSX_COUNT 31 + #define PJSIP_MAX_DIALOG_COUNT 31 + #define PJSUA_MAX_CALLS 4 + + /* Other pjsua settings */ + #define PJSUA_MAX_ACC 4 + #define PJSUA_MAX_PLAYERS 4 + #define PJSUA_MAX_RECORDERS 4 + #define PJSUA_MAX_CONF_PORTS (PJSUA_MAX_CALLS+2*PJSUA_MAX_PLAYERS) + #define PJSUA_MAX_BUDDIES 32 +#endif + + +/* + * Additional configuration to activate APS-Direct feature for + * Nokia S60 target + * + * Please see http://trac.pjsip.org/repos/wiki/Nokia_APS_VAS_Direct + */ +#ifdef PJ_CONFIG_NOKIA_APS_DIRECT + + /* MUST use switchboard rather than the conference bridge */ + #define PJMEDIA_CONF_USE_SWITCH_BOARD 1 + + /* Enable APS sound device backend and disable MDA & VAS */ + #define PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA 0 + #define PJMEDIA_AUDIO_DEV_HAS_SYMB_APS 1 + #define PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS 0 + + /* Enable passthrough codec framework */ + #define PJMEDIA_HAS_PASSTHROUGH_CODECS 1 + + /* And selectively enable which codecs are supported by the handset */ + #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU 1 + #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA 1 + #define PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR 1 + #define PJMEDIA_HAS_PASSTHROUGH_CODEC_G729 1 + #define PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC 1 + +#endif + + +/* + * Additional configuration to activate VAS-Direct feature for + * Nokia S60 target + * + * Please see http://trac.pjsip.org/repos/wiki/Nokia_APS_VAS_Direct + */ +#ifdef PJ_CONFIG_NOKIA_VAS_DIRECT + + /* MUST use switchboard rather than the conference bridge */ + #define PJMEDIA_CONF_USE_SWITCH_BOARD 1 + + /* Enable VAS sound device backend and disable MDA & APS */ + #define PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA 0 + #define PJMEDIA_AUDIO_DEV_HAS_SYMB_APS 0 + #define PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS 1 + + /* Enable passthrough codec framework */ + #define PJMEDIA_HAS_PASSTHROUGH_CODECS 1 + + /* And selectively enable which codecs are supported by the handset */ + #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU 1 + #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA 1 + #define PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR 1 + #define PJMEDIA_HAS_PASSTHROUGH_CODEC_G729 1 + #define PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC 1 + +#endif + + +/* + * Configuration to activate "APS-Direct" media mode on Windows, + * useful for testing purposes only. + */ +#ifdef PJ_CONFIG_WIN32_WMME_DIRECT + + /* MUST use switchboard rather than the conference bridge */ + #define PJMEDIA_CONF_USE_SWITCH_BOARD 1 + + /* Only WMME supports the "direct" feature */ + #define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO 0 + #define PJMEDIA_AUDIO_DEV_HAS_WMME 1 + + /* Enable passthrough codec framework */ + #define PJMEDIA_HAS_PASSTHROUGH_CODECS 1 + + /* Only PCMA and PCMU are supported by WMME-direct */ + #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU 1 + #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA 1 + #define PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR 0 + #define PJMEDIA_HAS_PASSTHROUGH_CODEC_G729 0 + #define PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC 0 + +#endif + +/* + * iPhone sample settings. + */ +#if PJ_CONFIG_IPHONE + /* + * PJLIB settings. + */ + + /* Disable floating point support */ + #define PJ_HAS_FLOATING_POINT 0 + + /* + * PJMEDIA settings + */ + + /* We have our own native CoreAudio backend */ + #define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO 0 + #define PJMEDIA_AUDIO_DEV_HAS_WMME 0 + #define PJMEDIA_AUDIO_DEV_HAS_COREAUDIO 1 + + /* The CoreAudio backend has built-in echo canceller! */ + #define PJMEDIA_HAS_SPEEX_AEC 0 + + /* Disable some codecs */ + #define PJMEDIA_HAS_L16_CODEC 0 + #define PJMEDIA_HAS_G722_CODEC 0 + + /* Use the built-in CoreAudio's iLBC codec (yay!) */ + #define PJMEDIA_HAS_ILBC_CODEC 1 + #define PJMEDIA_ILBC_CODEC_USE_COREAUDIO 1 + + /* Fine tune Speex's default settings for best performance/quality */ + #define PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY 5 + + /* + * PJSIP settings. + */ + + /* Increase allowable packet size, just in case */ + //#define PJSIP_MAX_PKT_LEN 2000 + + /* + * PJSUA settings. + */ + + /* Default codec quality, previously was set to 5, however it is now + * set to 4 to make sure pjsua instantiates resampler with small filter. + */ + #define PJSUA_DEFAULT_CODEC_QUALITY 4 + + /* Set maximum number of dialog/transaction/calls to minimum */ + #define PJSIP_MAX_TSX_COUNT 31 + #define PJSIP_MAX_DIALOG_COUNT 31 + #define PJSUA_MAX_CALLS 4 + + /* Other pjsua settings */ + #define PJSUA_MAX_ACC 4 + #define PJSUA_MAX_PLAYERS 4 + #define PJSUA_MAX_RECORDERS 4 + #define PJSUA_MAX_CONF_PORTS (PJSUA_MAX_CALLS+2*PJSUA_MAX_PLAYERS) + #define PJSUA_MAX_BUDDIES 32 + +#endif + +/* + * Minimum size + */ +#ifdef PJ_CONFIG_MINIMAL_SIZE + +# undef PJ_OS_HAS_CHECK_STACK +# define PJ_OS_HAS_CHECK_STACK 0 +# define PJ_LOG_MAX_LEVEL 0 +# define PJ_ENABLE_EXTRA_CHECK 0 +# define PJ_HAS_ERROR_STRING 0 +# undef PJ_IOQUEUE_MAX_HANDLES +/* Putting max handles to lower than 32 will make pj_fd_set_t size smaller + * than native fdset_t and will trigger assertion on sock_select.c. + */ +# define PJ_IOQUEUE_MAX_HANDLES 32 +# define PJ_CRC32_HAS_TABLES 0 +# define PJSIP_MAX_TSX_COUNT 15 +# define PJSIP_MAX_DIALOG_COUNT 15 +# define PJSIP_UDP_SO_SNDBUF_SIZE 4000 +# define PJSIP_UDP_SO_RCVBUF_SIZE 4000 +# define PJMEDIA_HAS_ALAW_ULAW_TABLE 0 + +#elif defined(PJ_CONFIG_MAXIMUM_SPEED) +# define PJ_SCANNER_USE_BITWISE 0 +# undef PJ_OS_HAS_CHECK_STACK +# define PJ_OS_HAS_CHECK_STACK 0 +# define PJ_LOG_MAX_LEVEL 3 +# define PJ_ENABLE_EXTRA_CHECK 0 +# define PJ_IOQUEUE_MAX_HANDLES 5000 +# define PJSIP_MAX_TSX_COUNT ((640*1024)-1) +# define PJSIP_MAX_DIALOG_COUNT ((640*1024)-1) +# define PJSIP_UDP_SO_SNDBUF_SIZE (24*1024*1024) +# define PJSIP_UDP_SO_RCVBUF_SIZE (24*1024*1024) +# define PJ_DEBUG 0 +# define PJSIP_SAFE_MODULE 0 +# define PJ_HAS_STRICMP_ALNUM 0 +# define PJ_HASH_USE_OWN_TOLOWER 1 +# define PJSIP_UNESCAPE_IN_PLACE 1 + +# ifdef PJ_WIN32 +# define PJSIP_MAX_NET_EVENTS 10 +# endif + +# define PJSUA_MAX_CALLS 512 + +#endif + diff --git a/pjlib/include/pj/ctype.h b/pjlib/include/pj/ctype.h new file mode 100644 index 0000000..08adde8 --- /dev/null +++ b/pjlib/include/pj/ctype.h @@ -0,0 +1,175 @@ +/* $Id: ctype.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 + * + * 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_CTYPE_H__ +#define __PJ_CTYPE_H__ + +/** + * @file ctype.h + * @brief C type helper macros. + */ + +#include +#include + +PJ_BEGIN_DECL + +/** + * @defgroup pj_ctype ctype - Character Type + * @ingroup PJ_MISC + * @{ + * + * This module contains several inline functions/macros for testing or + * manipulating character types. It is provided in PJLIB because PJLIB + * must not depend to LIBC. + */ + +/** + * Returns a non-zero value if either isalpha or isdigit is true for c. + * @param c The integer character to test. + * @return Non-zero value if either isalpha or isdigit is true for c. + */ +PJ_INLINE(int) pj_isalnum(unsigned char c) { return isalnum(c); } + +/** + * Returns a non-zero value if c is a particular representation of an + * alphabetic character. + * @param c The integer character to test. + * @return Non-zero value if c is a particular representation of an + * alphabetic character. + */ +PJ_INLINE(int) pj_isalpha(unsigned char c) { return isalpha(c); } + +/** + * Returns a non-zero value if c is a particular representation of an + * ASCII character. + * @param c The integer character to test. + * @return Non-zero value if c is a particular representation of + * an ASCII character. + */ +PJ_INLINE(int) pj_isascii(unsigned char c) { return c<128; } + +/** + * Returns a non-zero value if c is a particular representation of + * a decimal-digit character. + * @param c The integer character to test. + * @return Non-zero value if c is a particular representation of + * a decimal-digit character. + */ +PJ_INLINE(int) pj_isdigit(unsigned char c) { return isdigit(c); } + +/** + * Returns a non-zero value if c is a particular representation of + * a space character (0x09 - 0x0D or 0x20). + * @param c The integer character to test. + * @return Non-zero value if c is a particular representation of + * a space character (0x09 - 0x0D or 0x20). + */ +PJ_INLINE(int) pj_isspace(unsigned char c) { return isspace(c); } + +/** + * Returns a non-zero value if c is a particular representation of + * a lowercase character. + * @param c The integer character to test. + * @return Non-zero value if c is a particular representation of + * a lowercase character. + */ +PJ_INLINE(int) pj_islower(unsigned char c) { return islower(c); } + + +/** + * Returns a non-zero value if c is a particular representation of + * a uppercase character. + * @param c The integer character to test. + * @return Non-zero value if c is a particular representation of + * a uppercase character. + */ +PJ_INLINE(int) pj_isupper(unsigned char c) { return isupper(c); } + +/** + * Returns a non-zero value if c is a either a space (' ') or horizontal + * tab ('\\t') character. + * @param c The integer character to test. + * @return Non-zero value if c is a either a space (' ') or horizontal + * tab ('\\t') character. + */ +PJ_INLINE(int) pj_isblank(unsigned char c) { return isblank(c); } + +/** + * Converts character to lowercase. + * @param c The integer character to convert. + * @return Lowercase character of c. + */ +PJ_INLINE(int) pj_tolower(unsigned char c) { return tolower(c); } + +/** + * Converts character to uppercase. + * @param c The integer character to convert. + * @return Uppercase character of c. + */ +PJ_INLINE(int) pj_toupper(unsigned char c) { return toupper(c); } + +/** + * Returns a non-zero value if c is a particular representation of + * an hexadecimal digit character. + * @param c The integer character to test. + * @return Non-zero value if c is a particular representation of + * an hexadecimal digit character. + */ +PJ_INLINE(int) pj_isxdigit(unsigned char c){ return isxdigit(c); } + +/** + * Array of hex digits, in lowerspace. + */ +/*extern char pj_hex_digits[];*/ +#define pj_hex_digits "0123456789abcdef" + +/** + * Convert a value to hex representation. + * @param value Integral value to convert. + * @param p Buffer to hold the hex representation, which must be + * at least two bytes length. + */ +PJ_INLINE(void) pj_val_to_hex_digit(unsigned value, char *p) +{ + *p++ = pj_hex_digits[ (value & 0xF0) >> 4 ]; + *p = pj_hex_digits[ (value & 0x0F) ]; +} + +/** + * Convert hex digit c to integral value. + * @param c The hex digit character. + * @return The integral value between 0 and 15. + */ +PJ_INLINE(unsigned) pj_hex_digit_to_val(unsigned char c) +{ + if (c <= '9') + return (c-'0') & 0x0F; + else if (c <= 'F') + return (c-'A'+10) & 0x0F; + else + return (c-'a'+10) & 0x0F; +} + +/** @} */ + +PJ_END_DECL + +#endif /* __PJ_CTYPE_H__ */ + diff --git a/pjlib/include/pj/doxygen.h b/pjlib/include/pj/doxygen.h new file mode 100644 index 0000000..1fe198b --- /dev/null +++ b/pjlib/include/pj/doxygen.h @@ -0,0 +1,996 @@ +/* $Id: doxygen.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 + * + * 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_DOXYGEN_H__ +#define __PJ_DOXYGEN_H__ + +/** + * @file doxygen.h + * @brief Doxygen's mainpage. + */ + +/*////////////////////////////////////////////////////////////////////////// */ +/* + INTRODUCTION PAGE + */ + +/** + * @mainpage Welcome to PJLIB! + * + * @section intro_sec What is PJLIB + * + * PJLIB is an Open Source, small footprint framework library written in C for + * making scalable applications. Because of its small footprint, it can be used + * in embedded applications (we hope so!), but yet the library is also aimed for + * facilitating the creation of high performance protocol stacks. + * + * PJLIB is released under GPL terms. + * + * @section download_sec Download + * + * PJLIB and all documentation can be downloaded from + * http://www.pjsip.org. + * + * + * @section how_to_use_sec About This Documentation + * + * This document is generated directly from PJLIB source file using + * \a doxygen (http://www.doxygen.org). Doxygen is a great (and free!) + * tools for generating such documentation. + * + * + * @subsection find_samples_subsec How to Read This Document + * + * This documentation is laid out more to be a reference guide instead + * of tutorial, therefore first time users may find it difficult to + * grasp PJLIB by reading this document alone. + * + * However, we've tried our best to make this document easy to follow. + * For first time users, we would suggest that you follow these steps + * when reading this documentation: + * + * - continue reading this introduction chapter. At the end of this + * chapter, you'll find section called \ref pjlib_fundamentals_sec + * which should guide you to understand basic things about PJLIB. + * + * - find information about specific features that you want to use + * in PJLIB. Use the Module Index to find out about all + * features in PJLIB (if you're browsing the HTML documentation, + * click on the \a Module link on top of the page, or if you're + * reading the PDF documentation, click on \a Module \a Documentation + * on the navigation pane on the left). + * + * @subsection doc_organize_sec How To's + * + * Please find below links to specific tasks that you probably + * want to do: + * + * - How to Build PJLIB + *\n + * Please refer to \ref pjlib_build_sys_pg page for more information. + * + * - How to Use PJLIB in My Application + *\n + * Please refer to \ref configure_app_sec for more information. + * + * - How to Port PJLIB + *\n + * Please refer to \ref porting_pjlib_pg page. + * + * - Where to Read Samples Documentation + *\n + * Most of the modules provide link to the corresponding sample file. + * Alternatively, to get the list of all examples, you can click on + * Related Pages on the top of HTML document or on + * PJLIB Page Documentation on navigation pane of your PDF reader. + * + * - How to Submit Code to PJLIB Project + *\n + * Please read \ref pjlib_coding_convention_page before submitting + * your code. Send your code as patch against current Subversion tree + * to the appropriate mailing list. + * + * + * @section features_sec Features + * + * @subsection open_source_feat It's Open Source! + * + * PJLIB is currently released on GPL license, but other arrangements + * can be made with the author. + * + * @subsection extreme_portable_feat Extreme Portability + * + * PJLIB is designed to be extremely portable. It can run on any kind + * of processors (16-bit, 32-bit, or 64-bit, big or little endian, single + * or multi-processors) and operating systems. Floating point or no + * floating point. Multi-threading or not. + * It can even run in environment where no ANSI LIBC is available. + * + * Currently PJLIB is known to run on these platforms: + * - Win32/x86 (Win95/98/ME, NT/2000/XP/2003, mingw). + * - arm, WinCE and Windows Mobile. + * - Linux/x86, (user mode and as kernel module(!)). + * - Linux/alpha + * - Solaris/ultra. + * - MacOS X/powerpc + * - RTEMS (x86 and powerpc). + * + * And efforts is under way to port PJLIB on: + * - Symbian OS + * + * + * @subsection small_size_feat Small in Size + * + * One of the primary objectives is to have library that is small in size for + * typical embedded applications. As a rough guidance, we aim to keep the + * library size below 100KB for it to be considered as small. + * As the result, most of the functionalities in the library can be tailored + * to meet the requirements; user can enable/disable specific functionalities + * to get the desired size/performance/functionality balance. + * + * For more info, please see @ref pj_config. + * + * + * @subsection big_perform_feat Big in Performance + * + * Almost everything in PJLIB is designed to achieve the highest possible + * performance out of the target platform. + * + * + * @subsection no_dyn_mem No Dynamic Memory Allocations + * + * The central idea of PJLIB is that for applications to run as fast as it can, + * it should not use \a malloc() at all, but instead should get the memory + * from a preallocated storage pool. There are few things that can be + * optimized with this approach: + * + * - \a alloc() is a O(1) operation. + * - no mutex is used inside alloc(). It is assumed that synchronization + * will be used in higher abstraction by application anyway. + * - no \a free() is required. All chunks will be deleted when the pool is + * destroyed. + * + * The performance gained on some systems can be as high as 30x speed up + * against \a malloc() and \a free() on certain configurations, but of + * course your mileage may vary. + * + * For more information, see \ref PJ_POOL_GROUP + * + * + * @subsection os_abstract_feat Operating System Abstraction + * + * PJLIB has abstractions for features that are normally not portable + * across operating systems: + * - @ref PJ_THREAD + *\n + * Portable thread manipulation. + * - @ref PJ_TLS + *\n + * Storing data in thread's private data. + * - @ref PJ_MUTEX + *\n + * Mutual exclusion protection. + * - @ref PJ_SEM + *\n + * Semaphores. + * - @ref PJ_ATOMIC + *\n + * Atomic variables and their operations. + * - @ref PJ_CRIT_SEC + *\n + * Fast locking of critical sections. + * - @ref PJ_LOCK + *\n + * High level abstraction for lock objects. + * - @ref PJ_EVENT + *\n + * Event object. + * - @ref PJ_TIME + *\n + * Portable time manipulation. + * - @ref PJ_TIMESTAMP + *\n + * High resolution time value. + * - etc. + * + * + * @subsection ll_network_io_sec Low-Level Network I/O + * + * PJLIB has very portable abstraction and fairly complete set of API for + * doing network I/O communications. At the lowest level, PJLIB provides: + * + * - @ref PJ_SOCK + *\n + * A highly portable socket abstraction, runs on all kind of + * network APIs such as standard BSD socket, Windows socket, Linux + * \b kernel socket, PalmOS networking API, etc. + * + * - @ref pj_addr_resolve + *\n + * Portable address resolution, which implements #pj_gethostbyname(). + * + * - @ref PJ_SOCK_SELECT + *\n + * A portable \a select() like API (#pj_sock_select()) which can be + * implemented with various back-end. + * + * + * + * @subsection timer_mgmt_sec Timer Management + * + * A passive framework for managing timer, see @ref PJ_TIMER for more info. + * There is also function to retrieve high resolution timestamp + * from the system (see @ref PJ_TIMESTAMP). + * + * + * @subsection data_struct_sec Various Data Structures + * + * Various data structures are provided in the library: + * + * - @ref PJ_PSTR + * - @ref PJ_ARRAY + * - @ref PJ_HASH + * - @ref PJ_LIST + * - @ref PJ_RBTREE + * + * + * @subsection exception_sec Exception Construct + * + * A convenient TRY/CATCH like construct to propagate errors, which by + * default are used by the @ref PJ_POOL_GROUP "memory pool" and + * the lexical scanner in pjlib-util. The exception + * construct can be used to write programs like below: + * + *
+ *    #define SYNTAX_ERROR  1
+ *
+ *    PJ_TRY {
+ *       msg = NULL;
+ *       msg = parse_msg(buf, len);
+ *    }
+ *    PJ_CATCH ( SYNTAX_ERROR ) {
+ *       .. handle error ..
+ *    }
+ *    PJ_END;
+ * 
+ * + * Please see @ref PJ_EXCEPT for more information. + * + * + * @subsection logging_sec Logging Facility + * + * PJLIB @ref PJ_LOG consists of macros to write logging information to + * some output device. Some of the features of the logging facility: + * + * - the verbosity can be fine-tuned both at compile time (to control + * the library size) or run-time (to control the verbosity of the + * information). + * - output device is configurable (e.g. stdout, printk, file, etc.) + * - log decoration is configurable. + * + * See @ref PJ_LOG for more information. + * + * + * @subsection guid_gen_sec Random and GUID Generation + * + * PJLIB provides facility to create random string + * (#pj_create_random_string()) or globally unique identifier + * (see @ref PJ_GUID). + * + * + * + * @section configure_app_sec Configuring Application to use PJLIB + * + * @subsection pjlib_compil_sec Building PJLIB + * + * Follow the instructions in \ref pjlib_build_sys_pg to build + * PJLIB. + * + * @subsection pjlib_compil_app_sec Building Applications with PJLIB + * + * Use the following settings when building applications with PJLIB. + * + * @subsubsection compil_inc_dir_sec Include Search Path + * + * Add this to your include search path ($PJLIB is PJLIB root directory): + *
+ *   $PJLIB/include
+ * 
+ * + * @subsubsection compil_inc_file_sec Include PJLIB Header + * + * To include all PJLIB headers: + * \verbatim + #include + \endverbatim + * + * Alternatively, you can include individual PJLIB headers like this: + * \verbatim + #include + #include + \endverbatim + * + * + * @subsubsection compil_lib_dir_sec Library Path + * + * Add this to your library search path: + *
+ *   $PJLIB/lib
+ * 
+ * + * Then add the appropriate PJLIB library to your link specification. For + * example, you would add \c libpj-i386-linux-gcc.a when you're building + * applications in Linux. + * + * + * @subsection pjlib_fundamentals_sec Principles in Using PJLIB + * + * Few things that you \b MUST do when using PJLIB, to make sure that + * you create trully portable applications. + * + * @subsubsection call_pjlib_init_sec Call pj_init() + * + * Before you do anything else, call \c pj_init(). This would make sure that + * PJLIB system is properly set up. + * + * @subsubsection no_ansi_subsec Do NOT Use ANSI C + * + * Contrary to popular teaching, ANSI C (and LIBC) is not the most portable + * library in the world, nor it's the most ubiquitous. For example, LIBC + * is not available in Linux kernel. Also normally LIBC will be excluded + * from compilation of RTOSes to reduce size. + * + * So for maximum portability, do NOT use ANSI C. Do not even try to include + * any other header files outside . Stick with the functionalities + * provided by PJLIB. + * + * + * @subsubsection string_rep_subsubsec Use pj_str_t instead of C Strings + * + * PJLIB uses pj_str_t instead of normal C strings. You SHOULD follow this + * convention too. Remember, ANSI string-h is not always available. And + * PJLIB string is faster! + * + * @subsubsection mem_alloc_subsubsec Use Pool for Memory Allocations + * + * You MUST NOT use \a malloc() or any other memory allocation functions. + * Use PJLIB @ref PJ_POOL_GROUP instead! It's faster and most portable. + * + * @subsection logging_subsubsec Use Logging for Text Display + * + * DO NOT use for text output. Use PJLIB @ref PJ_LOG instead. + * + * + * @section porting_pjlib_sec0 Porting PJLIB + * + * Please see \ref porting_pjlib_pg page on more information to port + * PJLIB to new target. + * + * @section enjoy_sec Enjoy Using PJLIB! + * + * We hope that you find PJLIB usefull for your application. If you + * have any questions, suggestions, critics, bug fixes, or anything + * else, we would be happy to hear it. + * + * Enjoy using PJLIB! + * + * Benny Prijono < bennylp at pjsip dot org > + */ + + + +/*////////////////////////////////////////////////////////////////////////// */ +/* + CODING CONVENTION + */ + +/** + * @page pjlib_coding_convention_page Coding Convention + * + * Before you submit your code/patches to be included with PJLIB, you must + * make sure that your code is compliant with PJLIB coding convention. + * This is very important! Otherwise we would not accept your code. + * + * @section coding_conv_editor_sec Editor Settings + * + * The single most important thing in the whole coding convention is editor + * settings. It's more important than the correctness of your code (bugs will + * only crash the system, but incorrect tab size is mental!). + * + * Kindly set your editor as follows: + * - tab size to \b 8. + * - indentation to \b 4. + * + * With \c vi, you can do it with: + *
+ *  :se ts=8
+ *  :se sts=4
+ * 
+ * + * You should replace tab with eight spaces. + * + * @section coding_conv_detail_sec Coding Style + * + * Coding style MUST strictly follow K&R style. The rest of coding style + * must follow current style. You SHOULD be able to observe the style + * currently used by PJLIB from PJLIB sources, and apply the style to your + * code. If you're not able to do simple thing like to observe PJLIB + * coding style from the sources, then logic dictates that your ability to + * observe more difficult area in PJLIB such as memory allocation strategy, + * concurrency, etc is questionable. + * + * @section coding_conv_comment_sec Commenting Your Code + * + * Public API (e.g. in header files) MUST have doxygen compliant comments. + * + */ + + +/*////////////////////////////////////////////////////////////////////////// */ +/* + BUILDING AND INSTALLING PJLIB + */ + + + +/** + * @page pjlib_build_sys_pg Building, and Installing PJLIB + * + * @section build_sys_install_sec Build and Installation + * + * \note + * The most up-to-date information on building and installing PJLIB + * should be found in the website, under "Getting Started" document. + * More over, the new PJLIB build system is now based on autoconf, + * so some of the information here might not be relevant anymore + * (although most still are, since the autoconf script still use + * the old Makefile system as the backend). + * + * @subsection build_sys_install_win32_sec Visual Studio + * + * The PJLIB Visual Studio workspace supports the building of PJLIB + * for Win32 target. Although currently only the Visual Studio 6 Workspace is + * actively maintained, developers with later version of Visual Studio + * can easily imports VS6 workspace into their IDE. + * + * To start building PJLIB projects with Visual Studio 6 or later, open + * the \a workspace file in the corresponding \b \c build directory. You have + * several choices on which \a dsw file to open: + \verbatim + $PJPROJECT/pjlib/build/pjlib.dsw + $PJPROJECT/pjsip/build/pjsip.dsw + ..etc + \endverbatim + * + * The easiest way is to open pjsip_apps.dsw file in \b \c $PJPROJECT/pjsip-apps/build + * directory, and build pjsua project or the samples project. + * However this will not build the complete projects. + * For example, the PJLIB test is not included in this workspace. + * To build the complete projects, you must + * open and build each \a dsw file in \c build directory in each + * subprojects. For example, to open the complete PJLIB workspace, open + * pjlib.dsw in $PJPROJECT/pjlib/build directory. + * + * + * @subsubsection config_site_create_vc_sec Create config_site.h + * + * The file $PJPROJECT/pjlib/include/pj/config_site.h + * is supposed to contain configuration that is specific to your site/target. + * This file is not part of PJLIB, so you must create it yourself. Normally + * you just need to create a blank file. + * + * The reason why it's not included in PJLIB is so that you would not accidently + * overwrite your site configuration. + * + * If you fail to do this, Visual C will complain with error like: + * + * "fatal error C1083: Cannot open include file: 'pj/config_site.h': No such file + * or directory". + * + * @subsubsection build_vc_subsubsec Build the Projects + * + * Just hit the build button! + * + * + * @subsection build_sys_install_unix_sec Make System + * + * For other targets, PJLIB provides a rather comprehensive build system + * that uses GNU \a make (and only GNU \a make will work). + * Currently, the build system supports building * PJLIB for these targets: + * - i386/Win32/mingw + * - i386/Linux + * - i386/Linux (kernel) + * - alpha/linux + * - sparc/SunOS + * - etc.. + * + * + * @subsubsection build_req_sec Requirements + * + * In order to use the \c make based build system, you MUST have: + * + * - GNU make + *\n + * The Makefiles heavily utilize GNU make commands which most likely + * are not available in other \c make system. + * - bash shell is recommended. + *\n + * Specificly, there is a command "echo -n" which may not work + * in other shells. This command is used when generating dependencies + * (make dep) and it's located in + * $PJPROJECT/build/rules.mak. + * - ar, ranlib from GNU binutils + *\n + * In your system has different ar or ranlib (e.g. they + * may have been installed as gar and granlib), then + * either you create the relevant symbolic links, or modify + * $PJPROJECT/build/cc-gcc.mak and rename ar and + * ranlib to the appropriate names. + * - gcc to generate dependency. + *\n + * Currently the build system uses "gcc -MM" to generate build + * dependencies. If gcc is not desired to generate dependency, + * then either you don't run make dep, or edit + * $PJPROJECT/build/rules.mak to calculate dependency using + * your prefered method. (And let me know when you do so so that I can + * update the file. :) ) + * + * @subsubsection build_overview_sec Building the Project + * + * Generally, steps required to build the PJLIB are: + * + \verbatim + $ cd /home/user/pjproject + $ ./configure + $ touch pjlib/include/pj/config_site.h + $ make dep + $ make + \endverbatim + * + * The above process will build all static libraries and all applications. + * + * \note the configure script is not a proper autoconf script, + * but rather a simple shell script to detect current host. This script + * currently does not support cross-compilation. + * + * \note For Linux kernel target, there are additional steps required, which + * will be explained in section \ref linux_kern_target_subsec. + * + * @subsubsection build_mak_sec Cross Compilation + * + * For cross compilation, you will need to edit the \c build.mak file in + * \c $PJPROJECT root directory manually. Please see README-configure file + * in the root directory for more information. + * + * For Linux kernel target, you are also required to declare the following + * variables in this file: + * - \c KERNEL_DIR: full path of kernel source tree. + * - \c KERNEL_ARCH: kernel ARCH options (e.g. "ARCH=um"), or leave blank + * for default. + * - \c PJPROJECT_DIR: full path of PJPROJECT source tree. + * + * Apart from these, there are also additional steps required to build + * Linux kernel target, which will be explained in \ref linux_kern_target_subsec. + * + * @subsubsection build_dir_sec Files in "build" Directory + * + * The *.mak files in \c $PJPROJECT/build directory are used to specify + * the configuration for the specified compiler, target machine target + * operating system, and host options. These files will be executed + * (included) by \a make during building process, depending on the values + * specified in $PJPROJECT/build.mak file. + * + * Normally you don't need to edit these files, except when you're porting + * PJLIB to new target. + * + * Below are the description of some files in this directory: + * + * - rules.mak: contains generic rules always included during make. + * - cc-gcc.mak: rules when gcc is used for compiler. + * - cc-vc.mak: rules when MSVC compiler is used. + * - host-mingw.mak: rules for building in mingw host. + * - host-unix.mak: rules for building in Unix/Posix host. + * - host-win32.mak: rules for building in Win32 command console + * (only valid when VC is used). + * - m-i386.mak: rules when target machine is an i386 processor. + * - m-m68k.mak: rules when target machine is an m68k processor. + * - os-linux.mak: rules when target OS is Linux. + * - os-linux-kernel.mak: rules when PJLIB is to be build as + * part of Linux kernel. + * - os-win32.mak: rules when target OS is Win32. + * + * + * @subsubsection config_site_create_sec Create config_site.h + * + * The file $PJPROJECT/pjlib/include/pj/config_site.h + * is supposed to contain configuration that is specific to your site/target. + * This file is not part of PJLIB, so you must create it yourself. + * + * The reason why it's not included in PJLIB is so that you would not accidently + * overwrite your site configuration. + * + * + * @subsubsection invoking_make_sec Invoking make + * + * Normally, \a make is invoked in \c build directory under each project. + * For example, to build PJLIB, you would invoke \a make in + * \c $PJPROJECT/pjlib/build directory like below: + * + \verbatim + $ cd pjlib/build + $ make + \endverbatim + * + * Alternatively you may invoke make in $PJPROJECT + * directory, to build all projects under that directory (e.g. + * PJLIB, PJSIP, etc.). + * + * + * @subsubsection linux_kern_target_subsec Linux Kernel Target + * + * \note + * BUILDING APPLICATIONS IN LINUX KERNEL MODE IS A VERY DANGEROUS BUSINESS. + * YOU MAY CRASH THE WHOLE OF YOUR SYSTEM, CORRUPT YOUR HARDISK, ETC. PJLIB + * KERNEL MODULES ARE STILL IN EXPERIMENTAL PHASE. DO NOT RUN IT IN PRODUCTION + * SYSTEMS OR OTHER SYSTEMS WHERE RISK OF LOSS OF DATA IS NOT ACCEPTABLE. + * YOU HAVE BEEN WARNED. + * + * \note + * User Mode Linux (UML) provides excellent way to experiment with Linux + * kernel without risking the stability of the host system. See + * http://user-mode-linux.sourceforge.net for details. + * + * \note + * I only use UML to experiment with PJLIB kernel modules. + * I wouldn't be so foolish to use my host Linux machine to experiment + * with this. + * + * \note + * You have been warned. + * + * For building PJLIB for Linux kernel target, there are additional steps required. + * In general, the additional tasks are: + * - Declare some more variables in build.mak file (this + * has been explained in \ref build_mak_sec above). + * - Perform these two small modifications in kernel source tree. + * + * There are two small modification need to be applied to the kernel tree. + * + * 1. Edit Makefile in kernel root source tree. + * + * Add the following lines at the end of the Makefile in your + * $KERNEL_SRC dir: + \verbatim +script: + $(SCRIPT) + \endverbatim + * + * \note Remember to replace spaces with tab in the Makefile. + * + * The modification above is needed to capture kernel's \c $CFLAGS and + * \c $CFLAGS_MODULE which will be used for PJLIB's compilation. + * + * 2. Add Additional Exports. + * + * We need the kernel to export some more symbols for our use. So we declare + * the additional symbols to be exported in extra-exports.c file, and add + * a this file to be compiled into the kernel: + * + * - Copy the file extra-exports.c from pjlib/src/pj + * directory to $KERNEL_SRC/kernel/ directory. + * - Edit Makefile in that directory, and add this line + * somewhere after the declaration of that variable: + \verbatim +obj-y += extra-exports.o + \endverbatim + * + * To illustrate what have been done in your kernel source tree, below + * is screenshot of my kernel source tree _after_ the modification. + * + \verbatim +[root@vpc-linux linux-2.6.7]# pwd +/usr/src/linux-2.6.7 +[root@vpc-linux linux-2.6.7]# +[root@vpc-linux linux-2.6.7]# +[root@vpc-linux linux-2.6.7]# tail Makefile + +endif # skip-makefile + +FORCE: + +.PHONY: script + +script: + $(SCRIPT) + +[root@vpc-linux linux-2.6.7]# +[root@vpc-linux linux-2.6.7]# +[root@vpc-linux linux-2.6.7]# head kernel/extra-exports.c +#include +#include + +EXPORT_SYMBOL(sys_select); + +EXPORT_SYMBOL(sys_epoll_create); +EXPORT_SYMBOL(sys_epoll_ctl); +EXPORT_SYMBOL(sys_epoll_wait); + +EXPORT_SYMBOL(sys_socket); +[root@vpc-linux linux-2.6.7]# +[root@vpc-linux linux-2.6.7]# +[root@vpc-linux linux-2.6.7]# head -15 kernel/Makefile +# +# Makefile for the linux kernel. +# + +obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ + exit.o itimer.o time.o softirq.o resource.o \ + sysctl.o capability.o ptrace.o timer.o user.o \ + signal.o sys.o kmod.o workqueue.o pid.o \ + rcupdate.o intermodule.o extable.o params.o posix-timers.o \ + kthread.o + +obj-y += extra-exports.o + +obj-$(CONFIG_FUTEX) += futex.o +obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o +[root@vpc-linux linux-2.6.7]# + + \endverbatim + * + * Then you must rebuild the kernel. + * If you fail to do this, you won't be able to insmod pjlib. + * + * \note You will see a lots of warning messages during pjlib-test compilation. + * The warning messages complain about unresolved symbols which are defined + * in pjlib module. You can safely ignore these warnings. However, you can not + * ignore warnings about non-pjlib unresolved symbols. + * + * + * @subsection makefile_explained_sec Makefile Explained + * + * The \a Makefile for each project (e.g. PJLIB, PJSIP, etc) should be + * very similar in the contents. The Makefile is located under \c build + * directory in each project subdir. + * + * @subsubsection pjlib_makefile_subsec PJLIB Makefile. + * + * Below is PJLIB's Makefile: + * + * \include build/Makefile + * + * @subsubsection pjlib_os_makefile_subsec PJLIB os-linux.mak. + * + * Below is file os-linux.mak file in + * $PJPROJECT/pjlib/build directory, + * which is OS specific configuration file for Linux target that is specific + * for PJLIB project. For \b global OS specific configuration, please see + * $PJPROJECT/build/os-*.mak. + * + * \include build/os-linux.mak + * + */ + + +/*////////////////////////////////////////////////////////////////////////// */ +/* + PORTING PJLIB + */ + + + +/** + * @page porting_pjlib_pg Porting PJLIB + * + * \note + * Since version 0.5.8, PJLIB build system is now based on autoconf, so + * most of the time we shouldn't need to apply the tweakings below to get + * PJLIB working on a new platform. However, since the autoconf build system + * still uses the old Makefile build system, the information below may still + * be useful for reference. + * + * + * @section new_arch_sec Porting to New CPU Architecture + * + * Below is step-by-step guide to add support for new CPU architecture. + * This sample is based on porting to Alpha architecture; however steps for + * porting to other CPU architectures should be pretty similar. + * + * Also note that in this example, the operating system used is Linux. + * Should you wish to add support for new operating system, then follow + * the next section \ref porting_os_sec. + * + * Step-by-step guide to port to new CPU architecture: + * - decide the name for the new architecture. In this case, we choose + * alpha. + * - edit file $PJPROJECT/build.mak, and add new section for + * the new target: + *
+ *      #
+ *      # Linux alpha, gcc
+ *      #
+ *      export MACHINE_NAME := alpha
+ *      export OS_NAME := linux
+ *      export CC_NAME := gcc
+ *      export HOST_NAME := unix
+ *    
+ * + * - create a new file $PJPROJECT/build/m-alpha.mak. + * Alternatively create a copy from other file in this directory. + * The contents of this file will look something like: + *
+ *      export M_CFLAGS := $(CC_DEF)PJ_M_ALPHA=1
+ *      export M_CXXFLAGS :=
+ *      export M_LDFLAGS :=
+ *      export M_SOURCES :=
+ *    
+ * - create a new file $PJPROJECT/pjlib/include/pj/compat/m_alpha.h. + * Alternatively create a copy from other header file in this directory. + * The contents of this file will look something like: + *
+ *      #define PJ_HAS_PENTIUM          0
+ *      #define PJ_IS_LITTLE_ENDIAN     1
+ *      #define PJ_IS_BIG_ENDIAN        0
+ *    
+ * - edit pjlib/include/pj/config.h. Add new processor + * configuration in this header file, like follows: + *
+ *      ...
+ *      #elif defined (PJ_M_ALPHA) && PJ_M_ALPHA != 0
+ *      #   include 
+ *      ...
+ *    
+ * - done. Build PJLIB with: + *
+ *      $ cd $PJPROJECT/pjlib/build
+ *      $ make dep
+ *      $ make clean
+ *      $ make
+ *    
+ * + * @section porting_os_sec Porting to New Operating System Target + * + * This section will try to give you rough guideline on how to + * port PJLIB to a new target. As a sample, we give the target a name tag, + * for example xos (for X OS). + * + * @subsection new_compat_os_h_file_sec Create New Compat Header File + * + * You'll need to create a new header file + * include/pj/compat/os_xos.h. You can copy as a + * template other header file and edit it accordingly. + * + * @subsection modify_config_h_file_sec Modify config.h + * + * Then modify file include/pj/config.h to include + * this file accordingly (e.g. when macro PJ_XOS is + * defined): + * + \verbatim + ... + #elif defined(PJ_XOS) + # include + #else + #... + \endverbatim + * + * @subsection new_target_mak_file_sec Create New Global Make Config File + * + * Then you'll need to create global configuration file that + * is specific for this OS, i.e. os-xos.mak in + * $PJPROJECT/build directory. + * + * At very minimum, the file will normally need to define + * PJ_XOS=1 in the \c CFLAGS section: + * + \verbatim +# +# $PJPROJECT/build/os-xos.mak: +# +export OS_CFLAGS := $(CC_DEF)PJ_XOS=1 +export OS_CXXFLAGS := +export OS_LDFLAGS := +export OS_SOURCES := + \endverbatim + * + * + * @subsection new_target_prj_mak_file_sec Create New Project's Make Config File + * + * Then you'll need to create xos-specific configuration file + * for PJLIB. This file is also named os-xos.mak, + * but its located in pjlib/build directory. + * This file will specify source files that are specific to + * this OS to be included in the build process. + * + * Below is a sample: + \verbatim +# +# pjlib/build/os-xos.mak: +# XOS specific configuration for PJLIB. +# +export PJLIB_OBJS += os_core_xos.o \ + os_error_unix.o \ + os_time_ansi.o +export TEST_OBJS += main.o +export TARGETS = pjlib pjlib-test + \endverbatim + * + * @subsection new_target_src_sec Create and Edit Source Files + * + * You'll normally need to create at least these files: + * - os_core_xos.c: core OS specific + * functionality. + * - os_timestamp_xos.c: how to get timestamp + * in this OS. + * + * Depending on how things are done in your OS, you may need + * to create these files: + * - os_error_*.c: how to manipulate + * OS error codes. Alternatively you may use existing + * os_error_unix.c if the OS has \c errno and + * \c strerror() function. + * - ioqueue_*.c: if the OS has specific method + * to perform asynchronous I/O. Alternatively you may + * use existing ioqueue_select.c if the OS supports + * \c select() function call. + * - sock_*.c: if the OS has specific method + * to perform socket communication. Alternatively you may + * use existing sock_bsd.c if the OS supports + * BSD socket API, and edit include/pj/compat/socket.h + * file accordingly. + * + * You will also need to check various files in + * include/pj/compat/*.h, to see if they're + * compatible with your OS. + * + * @subsection new_target_build_file_sec Build The Project + * + * After basic building blocks have been created for the OS, then + * the easiest way to see which parts need to be fixed is by building + * the project and see the error messages. + * + * @subsection new_target_edit_vs_new_file_sec Editing Existing Files vs Creating New File + * + * When you encounter compatibility errors in PJLIB during porting, + * you have three options on how to fix the error: + * - edit the existing *.c file, and give it #ifdef + * switch for the new OS, or + * - edit include/pj/compat/*.h instead, or + * - create a totally new file. + * + * Basicly there is no strict rule on which approach is the best + * to use, however the following guidelines may be used: + * - if the file is expected to be completely different than + * any existing file, then perhaps you should create a completely + * new file. For example, file os_core_xxx.c will + * normally be different for each OS flavour. + * - if the difference can be localized in include/compat + * header file, and existing #ifdef switch is there, + * then preferably you should edit this include/compat + * header file. + * - if the existing *.c file has #ifdef switch, + * then you may add another #elif switch there. This + * normally is used for behaviors that are not totally + * different on each platform. + * - other than that above, use your own judgement on whether + * to edit the file or create new file etc. + */ + +#endif /* __PJ_DOXYGEN_H__ */ + diff --git a/pjlib/include/pj/errno.h b/pjlib/include/pj/errno.h new file mode 100644 index 0000000..98a735a --- /dev/null +++ b/pjlib/include/pj/errno.h @@ -0,0 +1,577 @@ +/* $Id: errno.h 3664 2011-07-19 03:42:28Z nanang $ */ +/* + * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono + * + * 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_ERRNO_H__ +#define __PJ_ERRNO_H__ + +/** + * @file errno.h + * @brief PJLIB Error Subsystem + */ +#include +#include +#include + +PJ_BEGIN_DECL + +/** + * @defgroup pj_errno Error Subsystem + * @{ + * + * The PJLIB Error Subsystem is a framework to unify all error codes + * produced by all components into a single error space, and provide + * uniform set of APIs to access them. With this framework, any error + * codes are encoded as pj_status_t value. The framework is extensible, + * application may register new error spaces to be recognized by + * the framework. + * + * @section pj_errno_retval Return Values + * + * All functions that returns @a pj_status_t returns @a PJ_SUCCESS if the + * operation was completed successfully, or non-zero value to indicate + * error. If the error came from operating system, then the native error + * code is translated/folded into PJLIB's error namespace by using + * #PJ_STATUS_FROM_OS() macro. The function will do this automatically + * before returning the error to caller. + * + * @section err_services Retrieving and Displaying Error Messages + * + * The framework provides the following APIs to retrieve and/or display + * error messages: + * + * - #pj_strerror(): this is the base API to retrieve error string + * description for the specified pj_status_t error code. + * + * - #PJ_PERROR() macro: use this macro similar to PJ_LOG to format + * an error message and display them to the log + * + * - #pj_perror(): this function is similar to PJ_PERROR() but unlike + * #PJ_PERROR(), this function will always be included in the + * link process. Due to this reason, prefer to use #PJ_PERROR() + * if the application is concerned about the executable size. + * + * Application MUST NOT pass native error codes (such as error code from + * functions like GetLastError() or errno) to PJLIB functions expecting + * @a pj_status_t. + * + * @section err_extending Extending the Error Space + * + * Application may register new error space to be recognized by the + * framework by using #pj_register_strerror(). Use the range started + * from PJ_ERRNO_START_USER to avoid conflict with existing error + * spaces. + * + */ + +/** + * Guidelines on error message length. + */ +#define PJ_ERR_MSG_SIZE 80 + +/** + * Buffer for title string of #PJ_PERROR(). + */ +#ifndef PJ_PERROR_TITLE_BUF_SIZE +# define PJ_PERROR_TITLE_BUF_SIZE 120 +#endif + + +/** + * Get the last platform error/status, folded into pj_status_t. + * @return OS dependent error code, folded into pj_status_t. + * @remark This function gets errno, or calls GetLastError() function and + * convert the code into pj_status_t with PJ_STATUS_FROM_OS. Do + * not call this for socket functions! + * @see pj_get_netos_error() + */ +PJ_DECL(pj_status_t) pj_get_os_error(void); + +/** + * Set last error. + * @param code pj_status_t + */ +PJ_DECL(void) pj_set_os_error(pj_status_t code); + +/** + * Get the last error from socket operations. + * @return Last socket error, folded into pj_status_t. + */ +PJ_DECL(pj_status_t) pj_get_netos_error(void); + +/** + * Set error code. + * @param code pj_status_t. + */ +PJ_DECL(void) pj_set_netos_error(pj_status_t code); + + +/** + * Get the error message for the specified error code. The message + * string will be NULL terminated. + * + * @param statcode The error code. + * @param buf Buffer to hold the error message string. + * @param bufsize Size of the buffer. + * + * @return The error message as NULL terminated string, + * wrapped with pj_str_t. + */ +PJ_DECL(pj_str_t) pj_strerror( pj_status_t statcode, + char *buf, pj_size_t bufsize); + +/** + * A utility macro to print error message pertaining to the specified error + * code to the log. This macro will construct the error message title + * according to the 'title_fmt' argument, and add the error string pertaining + * to the error code after the title string. A colon (':') will be added + * automatically between the title and the error string. + * + * This function is similar to pj_perror() function, but has the advantage + * that the function call can be omitted from the link process if the + * log level argument is below PJ_LOG_MAX_LEVEL threshold. + * + * Note that the title string constructed from the title_fmt will be built on + * a string buffer which size is PJ_PERROR_TITLE_BUF_SIZE, which normally is + * allocated from the stack. By default this buffer size is small (around + * 120 characters). Application MUST ensure that the constructed title string + * will not exceed this limit, since not all platforms support truncating + * the string. + * + * @see pj_perror() + * + * @param level The logging verbosity level, valid values are 0-6. Lower + * number indicates higher importance, with level zero + * indicates fatal error. Only numeral argument is + * permitted (e.g. not variable). + * @param arg Enclosed 'printf' like arguments, with the following + * arguments: + * - the sender (NULL terminated string), + * - the error code (pj_status_t) + * - the format string (title_fmt), and + * - optional variable number of arguments suitable for the + * format string. + * + * Sample: + * \verbatim + PJ_PERROR(2, (__FILE__, PJ_EBUSY, "Error making %s", "coffee")); + \endverbatim + * @hideinitializer + */ +#define PJ_PERROR(level,arg) do { \ + pj_perror_wrapper_##level(arg); \ + } while (0) + +/** + * A utility function to print error message pertaining to the specified error + * code to the log. This function will construct the error message title + * according to the 'title_fmt' argument, and add the error string pertaining + * to the error code after the title string. A colon (':') will be added + * automatically between the title and the error string. + * + * Unlike the PJ_PERROR() macro, this function takes the \a log_level argument + * as a normal argument, unlike in PJ_PERROR() where a numeral value must be + * given. However this function will always be linked to the executable, + * unlike PJ_PERROR() which can be omitted when the level is below the + * PJ_LOG_MAX_LEVEL. + * + * Note that the title string constructed from the title_fmt will be built on + * a string buffer which size is PJ_PERROR_TITLE_BUF_SIZE, which normally is + * allocated from the stack. By default this buffer size is small (around + * 120 characters). Application MUST ensure that the constructed title string + * will not exceed this limit, since not all platforms support truncating + * the string. + * + * @see PJ_PERROR() + */ +PJ_DECL(void) pj_perror(int log_level, const char *sender, pj_status_t status, + const char *title_fmt, ...); + + +/** + * Type of callback to be specified in #pj_register_strerror() + * + * @param e The error code to lookup. + * @param msg Buffer to store the error message. + * @param max Length of the buffer. + * + * @return The error string. + */ +typedef pj_str_t (*pj_error_callback)(pj_status_t e, char *msg, pj_size_t max); + + +/** + * Register strerror message handler for the specified error space. + * Application can register its own handler to supply the error message + * for the specified error code range. This handler will be called + * by #pj_strerror(). + * + * @param start_code The starting error code where the handler should + * be called to retrieve the error message. + * @param err_space The size of error space. The error code range then + * will fall in start_code to start_code+err_space-1 + * range. + * @param f The handler to be called when #pj_strerror() is + * supplied with error code that falls into this range. + * + * @return PJ_SUCCESS or the specified error code. The + * registration may fail when the error space has been + * occupied by other handler, or when there are too many + * handlers registered to PJLIB. + */ +PJ_DECL(pj_status_t) pj_register_strerror(pj_status_t start_code, + pj_status_t err_space, + pj_error_callback f); + +/** + * @hideinitializer + * Return platform os error code folded into pj_status_t code. This is + * the macro that is used throughout the library for all PJLIB's functions + * that returns error from operating system. Application may override + * this macro to reduce size (e.g. by defining it to always return + * #PJ_EUNKNOWN). + * + * Note: + * This macro MUST return non-zero value regardless whether zero is + * passed as the argument. The reason is to protect logic error when + * the operating system doesn't report error codes properly. + * + * @param os_code Platform OS error code. This value may be evaluated + * more than once. + * @return The platform os error code folded into pj_status_t. + */ +#ifndef PJ_RETURN_OS_ERROR +# define PJ_RETURN_OS_ERROR(os_code) (os_code ? \ + PJ_STATUS_FROM_OS(os_code) : -1) +#endif + + +/** + * @hideinitializer + * Fold a platform specific error into an pj_status_t code. + * + * @param e The platform os error code. + * @return pj_status_t + * @warning Macro implementation; the syserr argument may be evaluated + * multiple times. + */ +#if PJ_NATIVE_ERR_POSITIVE +# define PJ_STATUS_FROM_OS(e) (e == 0 ? PJ_SUCCESS : e + PJ_ERRNO_START_SYS) +#else +# define PJ_STATUS_FROM_OS(e) (e == 0 ? PJ_SUCCESS : PJ_ERRNO_START_SYS - e) +#endif + +/** + * @hideinitializer + * Fold an pj_status_t code back to the native platform defined error. + * + * @param e The pj_status_t folded platform os error code. + * @return pj_os_err_type + * @warning macro implementation; the statcode argument may be evaluated + * multiple times. If the statcode was not created by + * pj_get_os_error or PJ_STATUS_FROM_OS, the results are undefined. + */ +#if PJ_NATIVE_ERR_POSITIVE +# define PJ_STATUS_TO_OS(e) (e == 0 ? PJ_SUCCESS : e - PJ_ERRNO_START_SYS) +#else +# define PJ_STATUS_TO_OS(e) (e == 0 ? PJ_SUCCESS : PJ_ERRNO_START_SYS - e) +#endif + + +/** + * @defgroup pj_errnum PJLIB's Own Error Codes + * @ingroup pj_errno + * @{ + */ + +/** + * Use this macro to generate error message text for your error code, + * so that they look uniformly as the rest of the libraries. + * + * @param code The error code + * @param msg The error test. + */ +#ifndef PJ_BUILD_ERR +# define PJ_BUILD_ERR(code,msg) { code, msg " (" #code ")" } +#endif + + +/** + * @hideinitializer + * Unknown error has been reported. + */ +#define PJ_EUNKNOWN (PJ_ERRNO_START_STATUS + 1) /* 70001 */ +/** + * @hideinitializer + * The operation is pending and will be completed later. + */ +#define PJ_EPENDING (PJ_ERRNO_START_STATUS + 2) /* 70002 */ +/** + * @hideinitializer + * Too many connecting sockets. + */ +#define PJ_ETOOMANYCONN (PJ_ERRNO_START_STATUS + 3) /* 70003 */ +/** + * @hideinitializer + * Invalid argument. + */ +#define PJ_EINVAL (PJ_ERRNO_START_STATUS + 4) /* 70004 */ +/** + * @hideinitializer + * Name too long (eg. hostname too long). + */ +#define PJ_ENAMETOOLONG (PJ_ERRNO_START_STATUS + 5) /* 70005 */ +/** + * @hideinitializer + * Not found. + */ +#define PJ_ENOTFOUND (PJ_ERRNO_START_STATUS + 6) /* 70006 */ +/** + * @hideinitializer + * Not enough memory. + */ +#define PJ_ENOMEM (PJ_ERRNO_START_STATUS + 7) /* 70007 */ +/** + * @hideinitializer + * Bug detected! + */ +#define PJ_EBUG (PJ_ERRNO_START_STATUS + 8) /* 70008 */ +/** + * @hideinitializer + * Operation timed out. + */ +#define PJ_ETIMEDOUT (PJ_ERRNO_START_STATUS + 9) /* 70009 */ +/** + * @hideinitializer + * Too many objects. + */ +#define PJ_ETOOMANY (PJ_ERRNO_START_STATUS + 10)/* 70010 */ +/** + * @hideinitializer + * Object is busy. + */ +#define PJ_EBUSY (PJ_ERRNO_START_STATUS + 11)/* 70011 */ +/** + * @hideinitializer + * The specified option is not supported. + */ +#define PJ_ENOTSUP (PJ_ERRNO_START_STATUS + 12)/* 70012 */ +/** + * @hideinitializer + * Invalid operation. + */ +#define PJ_EINVALIDOP (PJ_ERRNO_START_STATUS + 13)/* 70013 */ +/** + * @hideinitializer + * Operation is cancelled. + */ +#define PJ_ECANCELLED (PJ_ERRNO_START_STATUS + 14)/* 70014 */ +/** + * @hideinitializer + * Object already exists. + */ +#define PJ_EEXISTS (PJ_ERRNO_START_STATUS + 15)/* 70015 */ +/** + * @hideinitializer + * End of file. + */ +#define PJ_EEOF (PJ_ERRNO_START_STATUS + 16)/* 70016 */ +/** + * @hideinitializer + * Size is too big. + */ +#define PJ_ETOOBIG (PJ_ERRNO_START_STATUS + 17)/* 70017 */ +/** + * @hideinitializer + * Error in gethostbyname(). This is a generic error returned when + * gethostbyname() has returned an error. + */ +#define PJ_ERESOLVE (PJ_ERRNO_START_STATUS + 18)/* 70018 */ +/** + * @hideinitializer + * Size is too small. + */ +#define PJ_ETOOSMALL (PJ_ERRNO_START_STATUS + 19)/* 70019 */ +/** + * @hideinitializer + * Ignored + */ +#define PJ_EIGNORED (PJ_ERRNO_START_STATUS + 20)/* 70020 */ +/** + * @hideinitializer + * IPv6 is not supported + */ +#define PJ_EIPV6NOTSUP (PJ_ERRNO_START_STATUS + 21)/* 70021 */ +/** + * @hideinitializer + * Unsupported address family + */ +#define PJ_EAFNOTSUP (PJ_ERRNO_START_STATUS + 22)/* 70022 */ + +/** @} */ /* pj_errnum */ + +/** @} */ /* pj_errno */ + + +/** + * PJ_ERRNO_START is where PJLIB specific error values start. + */ +#define PJ_ERRNO_START 20000 + +/** + * PJ_ERRNO_SPACE_SIZE is the maximum number of errors in one of + * the error/status range below. + */ +#define PJ_ERRNO_SPACE_SIZE 50000 + +/** + * PJ_ERRNO_START_STATUS is where PJLIB specific status codes start. + * Effectively the error in this class would be 70000 - 119000. + */ +#define PJ_ERRNO_START_STATUS (PJ_ERRNO_START + PJ_ERRNO_SPACE_SIZE) + +/** + * PJ_ERRNO_START_SYS converts platform specific error codes into + * pj_status_t values. + * Effectively the error in this class would be 120000 - 169000. + */ +#define PJ_ERRNO_START_SYS (PJ_ERRNO_START_STATUS + PJ_ERRNO_SPACE_SIZE) + +/** + * PJ_ERRNO_START_USER are reserved for applications that use error + * codes along with PJLIB codes. + * Effectively the error in this class would be 170000 - 219000. + */ +#define PJ_ERRNO_START_USER (PJ_ERRNO_START_SYS + PJ_ERRNO_SPACE_SIZE) + + +/* + * Below are list of error spaces that have been taken so far: + * - PJSIP_ERRNO_START (PJ_ERRNO_START_USER) + * - PJMEDIA_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE) + * - PJSIP_SIMPLE_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*2) + * - PJLIB_UTIL_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*3) + * - PJNATH_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*4) + * - PJMEDIA_AUDIODEV_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*5) + * - PJ_SSL_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*6) + * - PJMEDIA_VIDEODEV_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*7) + */ + +/* Internal */ +void pj_errno_clear_handlers(void); + + +/****** Internal for PJ_PERROR *******/ + +/** + * @def pj_perror_wrapper_1(arg) + * Internal function to write log with verbosity 1. Will evaluate to + * empty expression if PJ_LOG_MAX_LEVEL is below 1. + * @param arg Log expression. + */ +#if PJ_LOG_MAX_LEVEL >= 1 + #define pj_perror_wrapper_1(arg) pj_perror_1 arg + /** Internal function. */ + PJ_DECL(void) pj_perror_1(const char *sender, pj_status_t status, + const char *title_fmt, ...); +#else + #define pj_perror_wrapper_1(arg) +#endif + +/** + * @def pj_perror_wrapper_2(arg) + * Internal function to write log with verbosity 2. Will evaluate to + * empty expression if PJ_LOG_MAX_LEVEL is below 2. + * @param arg Log expression. + */ +#if PJ_LOG_MAX_LEVEL >= 2 + #define pj_perror_wrapper_2(arg) pj_perror_2 arg + /** Internal function. */ + PJ_DECL(void) pj_perror_2(const char *sender, pj_status_t status, + const char *title_fmt, ...); +#else + #define pj_perror_wrapper_2(arg) +#endif + +/** + * @def pj_perror_wrapper_3(arg) + * Internal function to write log with verbosity 3. Will evaluate to + * empty expression if PJ_LOG_MAX_LEVEL is below 3. + * @param arg Log expression. + */ +#if PJ_LOG_MAX_LEVEL >= 3 + #define pj_perror_wrapper_3(arg) pj_perror_3 arg + /** Internal function. */ + PJ_DECL(void) pj_perror_3(const char *sender, pj_status_t status, + const char *title_fmt, ...); +#else + #define pj_perror_wrapper_3(arg) +#endif + +/** + * @def pj_perror_wrapper_4(arg) + * Internal function to write log with verbosity 4. Will evaluate to + * empty expression if PJ_LOG_MAX_LEVEL is below 4. + * @param arg Log expression. + */ +#if PJ_LOG_MAX_LEVEL >= 4 + #define pj_perror_wrapper_4(arg) pj_perror_4 arg + /** Internal function. */ + PJ_DECL(void) pj_perror_4(const char *sender, pj_status_t status, + const char *title_fmt, ...); +#else + #define pj_perror_wrapper_4(arg) +#endif + +/** + * @def pj_perror_wrapper_5(arg) + * Internal function to write log with verbosity 5. Will evaluate to + * empty expression if PJ_LOG_MAX_LEVEL is below 5. + * @param arg Log expression. + */ +#if PJ_LOG_MAX_LEVEL >= 5 + #define pj_perror_wrapper_5(arg) pj_perror_5 arg + /** Internal function. */ + PJ_DECL(void) pj_perror_5(const char *sender, pj_status_t status, + const char *title_fmt, ...); +#else + #define pj_perror_wrapper_5(arg) +#endif + +/** + * @def pj_perror_wrapper_6(arg) + * Internal function to write log with verbosity 6. Will evaluate to + * empty expression if PJ_LOG_MAX_LEVEL is below 6. + * @param arg Log expression. + */ +#if PJ_LOG_MAX_LEVEL >= 6 + #define pj_perror_wrapper_6(arg) pj_perror_6 arg + /** Internal function. */ + PJ_DECL(void) pj_perror_6(const char *sender, pj_status_t status, + const char *title_fmt, ...); +#else + #define pj_perror_wrapper_6(arg) +#endif + + + + +PJ_END_DECL + +#endif /* __PJ_ERRNO_H__ */ + diff --git a/pjlib/include/pj/except.h b/pjlib/include/pj/except.h new file mode 100644 index 0000000..f7681ae --- /dev/null +++ b/pjlib/include/pj/except.h @@ -0,0 +1,421 @@ +/* $Id: except.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 + * + * 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_EXCEPTION_H__ +#define __PJ_EXCEPTION_H__ + +/** + * @file except.h + * @brief Exception Handling in C. + */ + +#include +#include +#include + + +PJ_BEGIN_DECL + + +/** + * @defgroup PJ_EXCEPT Exception Handling + * @ingroup PJ_MISC + * @{ + * + * \section pj_except_sample_sec Quick Example + * + * For the impatient, take a look at some examples: + * - @ref page_pjlib_samples_except_c + * - @ref page_pjlib_exception_test + * + * \section pj_except_except Exception Handling + * + * This module provides exception handling syntactically similar to C++ in + * C language. In Win32 systems, it uses Windows Structured Exception + * Handling (SEH) if macro PJ_EXCEPTION_USE_WIN32_SEH is non-zero. + * Otherwise it will use setjmp() and longjmp(). + * + * On some platforms where setjmp/longjmp is not available, setjmp/longjmp + * implementation is provided. See for compatibility. + * + * The exception handling mechanism is completely thread safe, so the exception + * thrown by one thread will not interfere with other thread. + * + * The exception handling constructs are similar to C++. The blocks will be + * constructed similar to the following sample: + * + * \verbatim + #define NO_MEMORY 1 + #define SYNTAX_ERROR 2 + + int sample1() + { + PJ_USE_EXCEPTION; // declare local exception stack. + + PJ_TRY { + ...// do something.. + } + PJ_CATCH(NO_MEMORY) { + ... // handle exception 1 + } + PJ_END; + } + + int sample2() + { + PJ_USE_EXCEPTION; // declare local exception stack. + + PJ_TRY { + ...// do something.. + } + PJ_CATCH_ANY { + if (PJ_GET_EXCEPTION() == NO_MEMORY) + ...; // handle no memory situation + else if (PJ_GET_EXCEPTION() == SYNTAX_ERROR) + ...; // handle syntax error + } + PJ_END; + } + \endverbatim + * + * The above sample uses hard coded exception ID. It is @b strongly + * recommended that applications request a unique exception ID instead + * of hard coded value like above. + * + * \section pj_except_reg Exception ID Allocation + * + * To ensure that exception ID (number) are used consistently and to + * prevent ID collisions in an application, it is strongly suggested that + * applications allocate an exception ID for each possible exception + * type. As a bonus of this process, the application can identify + * the name of the exception when the particular exception is thrown. + * + * Exception ID management are performed with the following APIs: + * - #pj_exception_id_alloc(). + * - #pj_exception_id_free(). + * - #pj_exception_id_name(). + * + * + * PJLIB itself automatically allocates one exception id, i.e. + * #PJ_NO_MEMORY_EXCEPTION which is declared in . This exception + * ID is raised by default pool policy when it fails to allocate memory. + * + * CAVEATS: + * - unlike C++ exception, the scheme here won't call destructors of local + * objects if exception is thrown. Care must be taken when a function + * hold some resorce such as pool or mutex etc. + * - You CAN NOT make nested exception in one single function without using + * a nested PJ_USE_EXCEPTION. Samples: + \verbatim + void wrong_sample() + { + PJ_USE_EXCEPTION; + + PJ_TRY { + // Do stuffs + ... + } + PJ_CATCH_ANY { + // Do other stuffs + .... + .. + + // The following block is WRONG! You MUST declare + // PJ_USE_EXCEPTION once again in this block. + PJ_TRY { + .. + } + PJ_CATCH_ANY { + .. + } + PJ_END; + } + PJ_END; + } + + \endverbatim + + * - You MUST NOT exit the function inside the PJ_TRY block. The correct way + * is to return from the function after PJ_END block is executed. + * For example, the following code will yield crash not in this code, + * but rather in the subsequent execution of PJ_TRY block: + \verbatim + void wrong_sample() + { + PJ_USE_EXCEPTION; + + PJ_TRY { + // do some stuffs + ... + return; <======= DO NOT DO THIS! + } + PJ_CATCH_ANY { + } + PJ_END; + } + \endverbatim + + * - You can not provide more than PJ_CATCH or PJ_CATCH_ANY nor use PJ_CATCH + * and PJ_CATCH_ANY for a single PJ_TRY. + * - Exceptions will always be caught by the first handler (unlike C++ where + * exception is only caught if the type matches. + + * \section PJ_EX_KEYWORDS Keywords + * + * \subsection PJ_THROW PJ_THROW(expression) + * Throw an exception. The expression thrown is an integer as the result of + * the \a expression. This keyword can be specified anywhere within the + * program. + * + * \subsection PJ_USE_EXCEPTION PJ_USE_EXCEPTION + * Specify this in the variable definition section of the function block + * (or any blocks) to specify that the block has \a PJ_TRY/PJ_CATCH exception + * block. + * Actually, this is just a macro to declare local variable which is used to + * push the exception state to the exception stack. + * Note: you must specify PJ_USE_EXCEPTION as the last statement in the + * local variable declarations, since it may evaluate to nothing. + * + * \subsection PJ_TRY PJ_TRY + * The \a PJ_TRY keyword is typically followed by a block. If an exception is + * thrown in this block, then the execution will resume to the \a PJ_CATCH + * handler. + * + * \subsection PJ_CATCH PJ_CATCH(expression) + * The \a PJ_CATCH is normally followed by a block. This block will be executed + * if the exception being thrown is equal to the expression specified in the + * \a PJ_CATCH. + * + * \subsection PJ_CATCH_ANY PJ_CATCH_ANY + * The \a PJ_CATCH is normally followed by a block. This block will be executed + * if any exception was raised in the TRY block. + * + * \subsection PJ_END PJ_END + * Specify this keyword to mark the end of \a PJ_TRY / \a PJ_CATCH blocks. + * + * \subsection PJ_GET_EXCEPTION PJ_GET_EXCEPTION(void) + * Get the last exception thrown. This macro is normally called inside the + * \a PJ_CATCH or \a PJ_CATCH_ANY block, altough it can be used anywhere where + * the \a PJ_USE_EXCEPTION definition is in scope. + * + * + * \section pj_except_examples_sec Examples + * + * For some examples on how to use the exception construct, please see: + * - @ref page_pjlib_samples_except_c + * - @ref page_pjlib_exception_test + */ + +/** + * Allocate a unique exception id. + * Applications don't have to allocate a unique exception ID before using + * the exception construct. However, by doing so it ensures that there is + * no collisions of exception ID. + * + * As a bonus, when exception number is acquired through this function, + * the library can assign name to the exception (only if + * PJ_HAS_EXCEPTION_NAMES is enabled (default is yes)) and find out the + * exception name when it catches an exception. + * + * @param name Name to be associated with the exception ID. + * @param id Pointer to receive the ID. + * + * @return PJ_SUCCESS on success or PJ_ETOOMANY if the library + * is running out out ids. + */ +PJ_DECL(pj_status_t) pj_exception_id_alloc(const char *name, + pj_exception_id_t *id); + +/** + * Free an exception id. + * + * @param id The exception ID. + * + * @return PJ_SUCCESS or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_exception_id_free(pj_exception_id_t id); + +/** + * Retrieve name associated with the exception id. + * + * @param id The exception ID. + * + * @return The name associated with the specified ID. + */ +PJ_DECL(const char*) pj_exception_id_name(pj_exception_id_t id); + + +/** @} */ + +#if defined(PJ_EXCEPTION_USE_WIN32_SEH) && PJ_EXCEPTION_USE_WIN32_SEH != 0 +/***************************************************************************** + ** + ** IMPLEMENTATION OF EXCEPTION USING WINDOWS SEH + ** + ****************************************************************************/ +#define WIN32_LEAN_AND_MEAN +#include + +PJ_IDECL_NO_RETURN(void) +pj_throw_exception_(pj_exception_id_t id) PJ_ATTR_NORETURN +{ + RaiseException(id,1,0,NULL); +} + +#define PJ_USE_EXCEPTION +#define PJ_TRY __try +#define PJ_CATCH(id) __except(GetExceptionCode()==id ? \ + EXCEPTION_EXECUTE_HANDLER : \ + EXCEPTION_CONTINUE_SEARCH) +#define PJ_CATCH_ANY __except(EXCEPTION_EXECUTE_HANDLER) +#define PJ_END +#define PJ_THROW(id) pj_throw_exception_(id) +#define PJ_GET_EXCEPTION() GetExceptionCode() + + +#elif defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0 +/***************************************************************************** + ** + ** IMPLEMENTATION OF EXCEPTION USING SYMBIAN LEAVE/TRAP FRAMEWORK + ** + ****************************************************************************/ + +/* To include this file, the source file must be compiled as + * C++ code! + */ +#ifdef __cplusplus + +class TPjException +{ +public: + int code_; +}; + +#define PJ_USE_EXCEPTION +#define PJ_TRY try +//#define PJ_CATCH(id) +#define PJ_CATCH_ANY catch (const TPjException & pj_excp_) +#define PJ_END +#define PJ_THROW(x_id) do { TPjException e; e.code_=x_id; throw e;} \ + while (0) +#define PJ_GET_EXCEPTION() pj_excp_.code_ + +#else + +#define PJ_USE_EXCEPTION +#define PJ_TRY +#define PJ_CATCH_ANY if (0) +#define PJ_END +#define PJ_THROW(x_id) do { PJ_LOG(1,("PJ_THROW"," error code = %d",x_id)); } while (0) +#define PJ_GET_EXCEPTION() 0 + +#endif /* __cplusplus */ + +#else +/***************************************************************************** + ** + ** IMPLEMENTATION OF EXCEPTION USING GENERIC SETJMP/LONGJMP + ** + ****************************************************************************/ + +/** + * This structure (which should be invisible to user) manages the TRY handler + * stack. + */ +struct pj_exception_state_t +{ + struct pj_exception_state_t *prev; /**< Previous state in the list. */ + pj_jmp_buf state; /**< jmp_buf. */ +}; + +/** + * Throw exception. + * @param id Exception Id. + */ +PJ_DECL_NO_RETURN(void) +pj_throw_exception_(pj_exception_id_t id) PJ_ATTR_NORETURN; + +/** + * Push exception handler. + */ +PJ_DECL(void) pj_push_exception_handler_(struct pj_exception_state_t *rec); + +/** + * Pop exception handler. + */ +PJ_DECL(void) pj_pop_exception_handler_(struct pj_exception_state_t *rec); + +/** + * Declare that the function will use exception. + * @hideinitializer + */ +#define PJ_USE_EXCEPTION struct pj_exception_state_t pj_x_except__; int pj_x_code__ + +/** + * Start exception specification block. + * @hideinitializer + */ +#define PJ_TRY if (1) { \ + pj_push_exception_handler_(&pj_x_except__); \ + pj_x_code__ = pj_setjmp(pj_x_except__.state); \ + if (pj_x_code__ == 0) +/** + * Catch the specified exception Id. + * @param id The exception number to catch. + * @hideinitializer + */ +#define PJ_CATCH(id) else if (pj_x_code__ == (id)) + +/** + * Catch any exception number. + * @hideinitializer + */ +#define PJ_CATCH_ANY else + +/** + * End of exception specification block. + * @hideinitializer + */ +#define PJ_END pj_pop_exception_handler_(&pj_x_except__); \ + } else {} + +/** + * Throw exception. + * @param exception_id The exception number. + * @hideinitializer + */ +#define PJ_THROW(exception_id) pj_throw_exception_(exception_id) + +/** + * Get current exception. + * @return Current exception code. + * @hideinitializer + */ +#define PJ_GET_EXCEPTION() (pj_x_code__) + +#endif /* PJ_EXCEPTION_USE_WIN32_SEH */ + + +PJ_END_DECL + + + +#endif /* __PJ_EXCEPTION_H__ */ + + diff --git a/pjlib/include/pj/fifobuf.h b/pjlib/include/pj/fifobuf.h new file mode 100644 index 0000000..37002b0 --- /dev/null +++ b/pjlib/include/pj/fifobuf.h @@ -0,0 +1,44 @@ +/* $Id: fifobuf.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 + * + * 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_FIFOBUF_H__ +#define __PJ_FIFOBUF_H__ + +#include + +PJ_BEGIN_DECL + +typedef struct pj_fifobuf_t pj_fifobuf_t; +struct pj_fifobuf_t +{ + char *first, *last; + char *ubegin, *uend; + int full; +}; + +PJ_DECL(void) pj_fifobuf_init (pj_fifobuf_t *fb, void *buffer, unsigned size); +PJ_DECL(unsigned) pj_fifobuf_max_size (pj_fifobuf_t *fb); +PJ_DECL(void*) pj_fifobuf_alloc (pj_fifobuf_t *fb, unsigned size); +PJ_DECL(pj_status_t) pj_fifobuf_unalloc (pj_fifobuf_t *fb, void *buf); +PJ_DECL(pj_status_t) pj_fifobuf_free (pj_fifobuf_t *fb, void *buf); + +PJ_END_DECL + +#endif /* __PJ_FIFOBUF_H__ */ + diff --git a/pjlib/include/pj/file_access.h b/pjlib/include/pj/file_access.h new file mode 100644 index 0000000..09406b1 --- /dev/null +++ b/pjlib/include/pj/file_access.h @@ -0,0 +1,109 @@ +/* $Id: file_access.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 + * + * 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_FILE_ACCESS_H__ +#define __PJ_FILE_ACCESS_H__ + +/** + * @file file_access.h + * @brief File manipulation and access. + */ +#include + +PJ_BEGIN_DECL + +/** + * @defgroup PJ_FILE_ACCESS File Access + * @ingroup PJ_IO + * @{ + * + */ + +/** + * This structure describes file information, to be obtained by + * calling #pj_file_getstat(). The time information in this structure + * is in local time. + */ +typedef struct pj_file_stat +{ + pj_off_t size; /**< Total file size. */ + pj_time_val atime; /**< Time of last access. */ + pj_time_val mtime; /**< Time of last modification. */ + pj_time_val ctime; /**< Time of last creation. */ +} pj_file_stat; + + +/** + * Returns non-zero if the specified file exists. + * + * @param filename The file name. + * + * @return Non-zero if the file exists. + */ +PJ_DECL(pj_bool_t) pj_file_exists(const char *filename); + +/** + * Returns the size of the file. + * + * @param filename The file name. + * + * @return The file size in bytes or -1 on error. + */ +PJ_DECL(pj_off_t) pj_file_size(const char *filename); + +/** + * Delete a file. + * + * @param filename The filename. + * + * @return PJ_SUCCESS on success or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_file_delete(const char *filename); + +/** + * Move a \c oldname to \c newname. If \c newname already exists, + * it will be overwritten. + * + * @param oldname The file to rename. + * @param newname New filename to assign. + * + * @return PJ_SUCCESS on success or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_file_move( const char *oldname, + const char *newname); + + +/** + * Return information about the specified file. The time information in + * the \c stat structure will be in local time. + * + * @param filename The filename. + * @param stat Pointer to variable to receive file information. + * + * @return PJ_SUCCESS on success or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_file_getstat(const char *filename, pj_file_stat *stat); + + +/** @} */ + +PJ_END_DECL + + +#endif /* __PJ_FILE_ACCESS_H__ */ diff --git a/pjlib/include/pj/file_io.h b/pjlib/include/pj/file_io.h new file mode 100644 index 0000000..31b7cb4 --- /dev/null +++ b/pjlib/include/pj/file_io.h @@ -0,0 +1,183 @@ +/* $Id: file_io.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 + * + * 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_FILE_IO_H__ +#define __PJ_FILE_IO_H__ + +/** + * @file file_io.h + * @brief Simple file I/O abstraction. + */ +#include + +PJ_BEGIN_DECL + +/** + * @defgroup PJ_FILE_IO File I/O + * @ingroup PJ_IO + * @{ + * + * This file contains functionalities to perform file I/O. The file + * I/O can be implemented with various back-end, either using native + * file API or ANSI stream. + * + * @section pj_file_size_limit_sec Size Limits + * + * There may be limitation on the size that can be handled by the + * #pj_file_setpos() or #pj_file_getpos() functions. The API itself + * uses 64-bit integer for the file offset/position (where available); + * however some backends (such as ANSI) may only support signed 32-bit + * offset resolution. + * + * Reading and writing operation uses signed 32-bit integer to indicate + * the size. + * + * + */ + +/** + * These enumerations are used when opening file. Values PJ_O_RDONLY, + * PJ_O_WRONLY, and PJ_O_RDWR are mutually exclusive. Value PJ_O_APPEND + * can only be used when the file is opened for writing. + */ +enum pj_file_access +{ + PJ_O_RDONLY = 0x1101, /**< Open file for reading. */ + PJ_O_WRONLY = 0x1102, /**< Open file for writing. */ + PJ_O_RDWR = 0x1103, /**< Open file for reading and writing. + File will be truncated. */ + PJ_O_APPEND = 0x1108 /**< Append to existing file. */ +}; + +/** + * The seek directive when setting the file position with #pj_file_setpos. + */ +enum pj_file_seek_type +{ + PJ_SEEK_SET = 0x1201, /**< Offset from beginning of the file. */ + PJ_SEEK_CUR = 0x1202, /**< Offset from current position. */ + PJ_SEEK_END = 0x1203 /**< Size of the file plus offset. */ +}; + +/** + * Open the file as specified in \c pathname with the specified + * mode, and return the handle in \c fd. All files will be opened + * as binary. + * + * @param pool Pool to allocate memory for the new file descriptor. + * @param pathname The file name to open. + * @param flags Open flags, which is bitmask combination of + * #pj_file_access enum. The flag must be either + * PJ_O_RDONLY, PJ_O_WRONLY, or PJ_O_RDWR. When file + * writing is specified, existing file will be + * truncated unless PJ_O_APPEND is specified. + * @param fd The returned descriptor. + * + * @return PJ_SUCCESS or the appropriate error code on error. + */ +PJ_DECL(pj_status_t) pj_file_open(pj_pool_t *pool, + const char *pathname, + unsigned flags, + pj_oshandle_t *fd); + +/** + * Close an opened file descriptor. + * + * @param fd The file descriptor. + * + * @return PJ_SUCCESS or the appropriate error code on error. + */ +PJ_DECL(pj_status_t) pj_file_close(pj_oshandle_t fd); + +/** + * Write data with the specified size to an opened file. + * + * @param fd The file descriptor. + * @param data Data to be written to the file. + * @param size On input, specifies the size of data to be written. + * On return, it contains the number of data actually + * written to the file. + * + * @return PJ_SUCCESS or the appropriate error code on error. + */ +PJ_DECL(pj_status_t) pj_file_write(pj_oshandle_t fd, + const void *data, + pj_ssize_t *size); + +/** + * Read data from the specified file. When end-of-file condition is set, + * this function will return PJ_SUCCESS but the size will contain zero. + * + * @param fd The file descriptor. + * @param data Pointer to buffer to receive the data. + * @param size On input, specifies the maximum number of data to + * read from the file. On output, it contains the size + * of data actually read from the file. It will contain + * zero when EOF occurs. + * + * @return PJ_SUCCESS or the appropriate error code on error. + * When EOF occurs, the return is PJ_SUCCESS but size + * will report zero. + */ +PJ_DECL(pj_status_t) pj_file_read(pj_oshandle_t fd, + void *data, + pj_ssize_t *size); + +/** + * Set file position to new offset according to directive \c whence. + * + * @param fd The file descriptor. + * @param offset The new file position to set. + * @param whence The directive. + * + * @return PJ_SUCCESS or the appropriate error code on error. + */ +PJ_DECL(pj_status_t) pj_file_setpos(pj_oshandle_t fd, + pj_off_t offset, + enum pj_file_seek_type whence); + +/** + * Get current file position. + * + * @param fd The file descriptor. + * @param pos On return contains the file position as measured + * from the beginning of the file. + * + * @return PJ_SUCCESS or the appropriate error code on error. + */ +PJ_DECL(pj_status_t) pj_file_getpos(pj_oshandle_t fd, + pj_off_t *pos); + +/** + * Flush file buffers. + * + * @param fd The file descriptor. + * + * @return PJ_SUCCESS or the appropriate error code on error. + */ +PJ_DECL(pj_status_t) pj_file_flush(pj_oshandle_t fd); + + +/** @} */ + + +PJ_END_DECL + +#endif /* __PJ_FILE_IO_H__ */ + diff --git a/pjlib/include/pj/guid.h b/pjlib/include/pj/guid.h new file mode 100644 index 0000000..991ce53 --- /dev/null +++ b/pjlib/include/pj/guid.h @@ -0,0 +1,101 @@ +/* $Id: guid.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 + * + * 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_GUID_H__ +#define __PJ_GUID_H__ + + +/** + * @file guid.h + * @brief GUID Globally Unique Identifier. + */ +#include + + +PJ_BEGIN_DECL + + +/** + * @defgroup PJ_DS Data Structure. + */ +/** + * @defgroup PJ_GUID Globally Unique Identifier + * @ingroup PJ_DS + * @{ + * + * This module provides API to create string that is globally unique. + * If application doesn't require that strong requirement, it can just + * use #pj_create_random_string() instead. + */ + + +/** + * PJ_GUID_STRING_LENGTH specifies length of GUID string. The value is + * dependent on the algorithm used internally to generate the GUID string. + * If real GUID generator is used, then the length will be between 32 and + * 36 bytes. Application should not assume which algorithm will + * be used by GUID generator. + * + * Regardless of the actual length of the GUID, it will not exceed + * PJ_GUID_MAX_LENGTH characters. + * + * @see pj_GUID_STRING_LENGTH() + * @see PJ_GUID_MAX_LENGTH + */ +PJ_DECL_DATA(const unsigned) PJ_GUID_STRING_LENGTH; + +/** + * Get #PJ_GUID_STRING_LENGTH constant. + */ +PJ_DECL(unsigned) pj_GUID_STRING_LENGTH(void); + +/** + * PJ_GUID_MAX_LENGTH specifies the maximum length of GUID string, + * regardless of which algorithm to use. + */ +#define PJ_GUID_MAX_LENGTH 36 + +/** + * Create a globally unique string, which length is PJ_GUID_STRING_LENGTH + * characters. Caller is responsible for preallocating the storage used + * in the string. + * + * @param str The string to store the result. + * + * @return The string. + */ +PJ_DECL(pj_str_t*) pj_generate_unique_string(pj_str_t *str); + +/** + * Generate a unique string. + * + * @param pool Pool to allocate memory from. + * @param str The string. + */ +PJ_DECL(void) pj_create_unique_string(pj_pool_t *pool, pj_str_t *str); + + +/** + * @} + */ + +PJ_END_DECL + +#endif/* __PJ_GUID_H__ */ + diff --git a/pjlib/include/pj/hash.h b/pjlib/include/pj/hash.h new file mode 100644 index 0000000..75b46c1 --- /dev/null +++ b/pjlib/include/pj/hash.h @@ -0,0 +1,220 @@ +/* $Id: hash.h 3841 2011-10-24 09:28:13Z ming $ */ +/* + * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono + * + * 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_HASH_H__ +#define __PJ_HASH_H__ + +/** + * @file hash.h + * @brief Hash Table. + */ + +#include + +PJ_BEGIN_DECL + +/** + * @defgroup PJ_HASH Hash Table + * @ingroup PJ_DS + * @{ + * A hash table is a dictionary in which keys are mapped to array positions by + * hash functions. Having the keys of more than one item map to the same + * position is called a collision. In this library, we will chain the nodes + * that have the same key in a list. + */ + +/** + * If this constant is used as keylen, then the key is interpreted as + * NULL terminated string. + */ +#define PJ_HASH_KEY_STRING ((unsigned)-1) + +/** + * This indicates the size of of each hash entry. + */ +#define PJ_HASH_ENTRY_BUF_SIZE (3*sizeof(void*) + 2*sizeof(pj_uint32_t)) + +/** + * Type declaration for entry buffer, used by #pj_hash_set_np() + */ +typedef void *pj_hash_entry_buf[(PJ_HASH_ENTRY_BUF_SIZE+sizeof(void*)-1)/(sizeof(void*))]; + +/** + * This is the function that is used by the hash table to calculate hash value + * of the specified key. + * + * @param hval the initial hash value, or zero. + * @param key the key to calculate. + * @param keylen the length of the key, or PJ_HASH_KEY_STRING to treat + * the key as null terminated string. + * + * @return the hash value. + */ +PJ_DECL(pj_uint32_t) pj_hash_calc(pj_uint32_t hval, + const void *key, unsigned keylen); + + +/** + * Convert the key to lowercase and calculate the hash value. The resulting + * string is stored in \c result. + * + * @param hval The initial hash value, normally zero. + * @param result Buffer to store the result, which must be enough to hold + * the string. + * @param key The input key to be converted and calculated. + * + * @return The hash value. + */ +PJ_DECL(pj_uint32_t) pj_hash_calc_tolower(pj_uint32_t hval, + char *result, + const pj_str_t *key); + +/** + * Create a hash table with the specified 'bucket' size. + * + * @param pool the pool from which the hash table will be allocated from. + * @param size the bucket size, which will be round-up to the nearest 2^n-1 + * + * @return the hash table. + */ +PJ_DECL(pj_hash_table_t*) pj_hash_create(pj_pool_t *pool, unsigned size); + + +/** + * Get the value associated with the specified key. + * + * @param ht the hash table. + * @param key the key to look for. + * @param keylen the length of the key, or PJ_HASH_KEY_STRING to use the + * string length of the key. + * @param hval if this argument is not NULL and the value is not zero, + * the value will be used as the computed hash value. If + * the argument is not NULL and the value is zero, it will + * be filled with the computed hash upon return. + * + * @return the value associated with the key, or NULL if the key is not found. + */ +PJ_DECL(void *) pj_hash_get( pj_hash_table_t *ht, + const void *key, unsigned keylen, + pj_uint32_t *hval ); + + +/** + * Associate/disassociate a value with the specified key. If value is not + * NULL and entry already exists, the entry's value will be overwritten. + * If value is not NULL and entry does not exist, a new one will be created + * with the specified pool. Otherwise if value is NULL, entry will be + * deleted if it exists. + * + * @param pool the pool to allocate the new entry if a new entry has to be + * created. + * @param ht the hash table. + * @param key the key. If pool is not specified, the key MUST point to + * buffer that remains valid for the duration of the entry. + * @param keylen the length of the key, or PJ_HASH_KEY_STRING to use the + * string length of the key. + * @param hval if the value is not zero, then the hash table will use + * this value to search the entry's index, otherwise it will + * compute the key. This value can be obtained when calling + * #pj_hash_get(). + * @param value value to be associated, or NULL to delete the entry with + * the specified key. + */ +PJ_DECL(void) pj_hash_set( pj_pool_t *pool, pj_hash_table_t *ht, + const void *key, unsigned keylen, pj_uint32_t hval, + void *value ); + + +/** + * Associate/disassociate a value with the specified key. This function works + * like #pj_hash_set(), except that it doesn't use pool (hence the np -- no + * pool suffix). If new entry needs to be allocated, it will use the entry_buf. + * + * @param ht the hash table. + * @param key the key. + * @param keylen the length of the key, or PJ_HASH_KEY_STRING to use the + * string length of the key. + * @param hval if the value is not zero, then the hash table will use + * this value to search the entry's index, otherwise it will + * compute the key. This value can be obtained when calling + * #pj_hash_get(). + * @param entry_buf Buffer which will be used for the new entry, when one needs + * to be created. + * @param value value to be associated, or NULL to delete the entry with + * the specified key. + */ +PJ_DECL(void) pj_hash_set_np(pj_hash_table_t *ht, + const void *key, unsigned keylen, + pj_uint32_t hval, pj_hash_entry_buf entry_buf, + void *value); + +/** + * Get the total number of entries in the hash table. + * + * @param ht the hash table. + * + * @return the number of entries in the hash table. + */ +PJ_DECL(unsigned) pj_hash_count( pj_hash_table_t *ht ); + + +/** + * Get the iterator to the first element in the hash table. + * + * @param ht the hash table. + * @param it the iterator for iterating hash elements. + * + * @return the iterator to the hash element, or NULL if no element presents. + */ +PJ_DECL(pj_hash_iterator_t*) pj_hash_first( pj_hash_table_t *ht, + pj_hash_iterator_t *it ); + + +/** + * Get the next element from the iterator. + * + * @param ht the hash table. + * @param it the hash iterator. + * + * @return the next iterator, or NULL if there's no more element. + */ +PJ_DECL(pj_hash_iterator_t*) pj_hash_next( pj_hash_table_t *ht, + pj_hash_iterator_t *it ); + +/** + * Get the value associated with a hash iterator. + * + * @param ht the hash table. + * @param it the hash iterator. + * + * @return the value associated with the current element in iterator. + */ +PJ_DECL(void*) pj_hash_this( pj_hash_table_t *ht, + pj_hash_iterator_t *it ); + + +/** + * @} + */ + +PJ_END_DECL + +#endif + + diff --git a/pjlib/include/pj/ioqueue.h b/pjlib/include/pj/ioqueue.h new file mode 100644 index 0000000..068e7ba --- /dev/null +++ b/pjlib/include/pj/ioqueue.h @@ -0,0 +1,805 @@ +/* $Id: ioqueue.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 + * + * 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_IOQUEUE_H__ +#define __PJ_IOQUEUE_H__ + +/** + * @file ioqueue.h + * @brief I/O Dispatching Mechanism + */ + +#include + +PJ_BEGIN_DECL + +/** + * @defgroup PJ_IO Input/Output + * @brief Input/Output + * @ingroup PJ_OS + * + * This section contains API building blocks to perform network I/O and + * communications. If provides: + * - @ref PJ_SOCK + *\n + * A highly portable socket abstraction, runs on all kind of + * network APIs such as standard BSD socket, Windows socket, Linux + * \b kernel socket, PalmOS networking API, etc. + * + * - @ref pj_addr_resolve + *\n + * Portable address resolution, which implements #pj_gethostbyname(). + * + * - @ref PJ_SOCK_SELECT + *\n + * A portable \a select() like API (#pj_sock_select()) which can be + * implemented with various back-ends. + * + * - @ref PJ_IOQUEUE + *\n + * Framework for dispatching network events. + * + * For more information see the modules below. + */ + +/** + * @defgroup PJ_IOQUEUE IOQueue: I/O Event Dispatching with Proactor Pattern + * @ingroup PJ_IO + * @{ + * + * I/O Queue provides API for performing asynchronous I/O operations. It + * conforms to proactor pattern, which allows application to submit an + * asynchronous operation and to be notified later when the operation has + * completed. + * + * The I/O Queue can work on both socket and file descriptors. For + * asynchronous file operations however, one must make sure that the correct + * file I/O back-end is used, because not all file I/O back-end can be + * used with the ioqueue. Please see \ref PJ_FILE_IO for more details. + * + * The framework works natively in platforms where asynchronous operation API + * exists, such as in Windows NT with IoCompletionPort/IOCP. In other + * platforms, the I/O queue abstracts the operating system's event poll API + * to provide semantics similar to IoCompletionPort with minimal penalties + * (i.e. per ioqueue and per handle mutex protection). + * + * The I/O queue provides more than just unified abstraction. It also: + * - makes sure that the operation uses the most effective way to utilize + * the underlying mechanism, to achieve the maximum theoritical + * throughput possible on a given platform. + * - choose the most efficient mechanism for event polling on a given + * platform. + * + * Currently, the I/O Queue is implemented using: + * - select(), as the common denominator, but the least + * efficient. Also the number of descriptor is limited to + * \c PJ_IOQUEUE_MAX_HANDLES (which by default is 64). + * - /dev/epoll on Linux (user mode and kernel mode), + * a much faster replacement for select() on Linux (and more importantly + * doesn't have limitation on number of descriptors). + * - I/O Completion ports on Windows NT/2000/XP, which is the most + * efficient way to dispatch events in Windows NT based OSes, and most + * importantly, it doesn't have the limit on how many handles to monitor. + * And it works with files (not only sockets) as well. + * + * + * \section pj_ioqueue_concurrency_sec Concurrency Rules + * + * The ioqueue has been fine tuned to allow multiple threads to poll the + * handles simultaneously, to maximize scalability when the application is + * running on multiprocessor systems. When more than one threads are polling + * the ioqueue and there are more than one handles are signaled, more than + * one threads will execute the callback simultaneously to serve the events. + * These parallel executions are completely safe when the events happen for + * two different handles. + * + * However, with multithreading, care must be taken when multiple events + * happen on the same handle, or when event is happening on a handle (and + * the callback is being executed) and application is performing + * unregistration to the handle at the same time. + * + * The treatments of above scenario differ according to the concurrency + * setting that are applied to the handle. + * + * \subsection pj_ioq_concur_set Concurrency Settings for Handles + * + * Concurrency can be set on per handle (key) basis, by using + * #pj_ioqueue_set_concurrency() function. The default key concurrency value + * for the handle is inherited from the key concurrency setting of the ioqueue, + * and the key concurrency setting for the ioqueue can be changed by using + * #pj_ioqueue_set_default_concurrency(). The default key concurrency setting + * for ioqueue itself is controlled by compile time setting + * PJ_IOQUEUE_DEFAULT_ALLOW_CONCURRENCY. + * + * Note that this key concurrency setting only controls whether multiple + * threads are allowed to operate on the same key at the same time. + * The ioqueue itself always allows multiple threads to enter the ioqeuue at + * the same time, and also simultaneous callback calls to differrent + * keys is always allowed regardless to the key concurrency setting. + * + * \subsection pj_ioq_parallel Parallel Callback Executions for the Same Handle + * + * Note that when key concurrency is enabled (i.e. parallel callback calls on + * the same key is allowed; this is the default setting), the ioqueue will only + * perform simultaneous callback executions on the same key when the key has + * invoked multiple pending operations. This could be done for example by + * calling #pj_ioqueue_recvfrom() more than once on the same key, each with + * the same key but different operation key (pj_ioqueue_op_key_t). With this + * scenario, when multiple packets arrive on the key at the same time, more + * than one threads may execute the callback simultaneously, each with the + * same key but different operation key. + * + * When there is only one pending operation on the key (e.g. there is only one + * #pj_ioqueue_recvfrom() invoked on the key), then events occuring to the + * same key will be queued by the ioqueue, thus no simultaneous callback calls + * will be performed. + * + * \subsection pj_ioq_allow_concur Concurrency is Enabled (Default Value) + * + * The default setting for the ioqueue is to allow multiple threads to + * execute callbacks for the same handle/key. This setting is selected to + * promote good performance and scalability for application. + * + * However this setting has a major drawback with regard to synchronization, + * and application MUST carefully follow the following guidelines to ensure + * that parallel access to the key does not cause problems: + * + * - Always note that callback may be called simultaneously for the same + * key. + * - Care must be taken when unregistering a key from the + * ioqueue. Application must take care that when one thread is issuing + * an unregistration, other thread is not simultaneously invoking the + * callback to the same key. + *\n + * This happens because the ioqueue functions are working with a pointer + * to the key, and there is a possible race condition where the pointer + * has been rendered invalid by other threads before the ioqueue has a + * chance to acquire mutex on it. + * + * \subsection pj_ioq_disallow_concur Concurrency is Disabled + * + * Alternatively, application may disable key concurrency to make + * synchronization easier. As noted above, there are three ways to control + * key concurrency setting: + * - by controlling on per handle/key basis, with #pj_ioqueue_set_concurrency(). + * - by changing default key concurrency setting on the ioqueue, with + * #pj_ioqueue_set_default_concurrency(). + * - by changing the default concurrency on compile time, by declaring + * PJ_IOQUEUE_DEFAULT_ALLOW_CONCURRENCY macro to zero in your config_site.h + * + * \section pj_ioqeuue_examples_sec Examples + * + * For some examples on how to use the I/O Queue, please see: + * + * - \ref page_pjlib_ioqueue_tcp_test + * - \ref page_pjlib_ioqueue_udp_test + * - \ref page_pjlib_ioqueue_perf_test + */ + + +/** + * This structure describes operation specific key to be submitted to + * I/O Queue when performing the asynchronous operation. This key will + * be returned to the application when completion callback is called. + * + * Application normally wants to attach it's specific data in the + * \c user_data field so that it can keep track of which operation has + * completed when the callback is called. Alternatively, application can + * also extend this struct to include its data, because the pointer that + * is returned in the completion callback will be exactly the same as + * the pointer supplied when the asynchronous function is called. + */ +typedef struct pj_ioqueue_op_key_t +{ + void *internal__[32]; /**< Internal I/O Queue data. */ + void *activesock_data; /**< Active socket data. */ + void *user_data; /**< Application data. */ +} pj_ioqueue_op_key_t; + +/** + * This structure describes the callbacks to be called when I/O operation + * completes. + */ +typedef struct pj_ioqueue_callback +{ + /** + * This callback is called when #pj_ioqueue_recv or #pj_ioqueue_recvfrom + * completes. + * + * @param key The key. + * @param op_key Operation key. + * @param bytes_read >= 0 to indicate the amount of data read, + * otherwise negative value containing the error + * code. To obtain the pj_status_t error code, use + * (pj_status_t code = -bytes_read). + */ + void (*on_read_complete)(pj_ioqueue_key_t *key, + pj_ioqueue_op_key_t *op_key, + pj_ssize_t bytes_read); + + /** + * This callback is called when #pj_ioqueue_send or #pj_ioqueue_sendto + * completes. + * + * @param key The key. + * @param op_key Operation key. + * @param bytes_sent >= 0 to indicate the amount of data written, + * otherwise negative value containing the error + * code. To obtain the pj_status_t error code, use + * (pj_status_t code = -bytes_sent). + */ + void (*on_write_complete)(pj_ioqueue_key_t *key, + pj_ioqueue_op_key_t *op_key, + pj_ssize_t bytes_sent); + + /** + * This callback is called when #pj_ioqueue_accept completes. + * + * @param key The key. + * @param op_key Operation key. + * @param sock Newly connected socket. + * @param status Zero if the operation completes successfully. + */ + void (*on_accept_complete)(pj_ioqueue_key_t *key, + pj_ioqueue_op_key_t *op_key, + pj_sock_t sock, + pj_status_t status); + + /** + * This callback is called when #pj_ioqueue_connect completes. + * + * @param key The key. + * @param status PJ_SUCCESS if the operation completes successfully. + */ + void (*on_connect_complete)(pj_ioqueue_key_t *key, + pj_status_t status); +} pj_ioqueue_callback; + + +/** + * Types of pending I/O Queue operation. This enumeration is only used + * internally within the ioqueue. + */ +typedef enum pj_ioqueue_operation_e +{ + PJ_IOQUEUE_OP_NONE = 0, /**< No operation. */ + PJ_IOQUEUE_OP_READ = 1, /**< read() operation. */ + PJ_IOQUEUE_OP_RECV = 2, /**< recv() operation. */ + PJ_IOQUEUE_OP_RECV_FROM = 4, /**< recvfrom() operation. */ + PJ_IOQUEUE_OP_WRITE = 8, /**< write() operation. */ + PJ_IOQUEUE_OP_SEND = 16, /**< send() operation. */ + PJ_IOQUEUE_OP_SEND_TO = 32, /**< sendto() operation. */ +#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0 + PJ_IOQUEUE_OP_ACCEPT = 64, /**< accept() operation. */ + PJ_IOQUEUE_OP_CONNECT = 128 /**< connect() operation. */ +#endif /* PJ_HAS_TCP */ +} pj_ioqueue_operation_e; + + +/** + * This macro specifies the maximum number of events that can be + * processed by the ioqueue on a single poll cycle, on implementation + * that supports it. The value is only meaningfull when specified + * during PJLIB build. + */ +#ifndef PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL +# define PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL (16) +#endif + +/** + * When this flag is specified in ioqueue's recv() or send() operations, + * the ioqueue will always mark the operation as asynchronous. + */ +#define PJ_IOQUEUE_ALWAYS_ASYNC ((pj_uint32_t)1 << (pj_uint32_t)31) + +/** + * Return the name of the ioqueue implementation. + * + * @return Implementation name. + */ +PJ_DECL(const char*) pj_ioqueue_name(void); + + +/** + * Create a new I/O Queue framework. + * + * @param pool The pool to allocate the I/O queue structure. + * @param max_fd The maximum number of handles to be supported, which + * should not exceed PJ_IOQUEUE_MAX_HANDLES. + * @param ioqueue Pointer to hold the newly created I/O Queue. + * + * @return PJ_SUCCESS on success. + */ +PJ_DECL(pj_status_t) pj_ioqueue_create( pj_pool_t *pool, + pj_size_t max_fd, + pj_ioqueue_t **ioqueue); + +/** + * Destroy the I/O queue. + * + * @param ioque The I/O Queue to be destroyed. + * + * @return PJ_SUCCESS if success. + */ +PJ_DECL(pj_status_t) pj_ioqueue_destroy( pj_ioqueue_t *ioque ); + +/** + * Set the lock object to be used by the I/O Queue. This function can only + * be called right after the I/O queue is created, before any handle is + * registered to the I/O queue. + * + * Initially the I/O queue is created with non-recursive mutex protection. + * Applications can supply alternative lock to be used by calling this + * function. + * + * @param ioque The ioqueue instance. + * @param lock The lock to be used by the ioqueue. + * @param auto_delete In non-zero, the lock will be deleted by the ioqueue. + * + * @return PJ_SUCCESS or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_ioqueue_set_lock( pj_ioqueue_t *ioque, + pj_lock_t *lock, + pj_bool_t auto_delete ); + +/** + * Set default concurrency policy for this ioqueue. If this function is not + * called, the default concurrency policy for the ioqueue is controlled by + * compile time setting PJ_IOQUEUE_DEFAULT_ALLOW_CONCURRENCY. + * + * Note that changing the concurrency setting to the ioqueue will only affect + * subsequent key registrations. To modify the concurrency setting for + * individual key, use #pj_ioqueue_set_concurrency(). + * + * @param ioqueue The ioqueue instance. + * @param allow Non-zero to allow concurrent callback calls, or + * PJ_FALSE to disallow it. + * + * @return PJ_SUCCESS on success or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_ioqueue_set_default_concurrency(pj_ioqueue_t *ioqueue, + pj_bool_t allow); + +/** + * Register a socket to the I/O queue framework. + * When a socket is registered to the IOQueue, it may be modified to use + * non-blocking IO. If it is modified, there is no guarantee that this + * modification will be restored after the socket is unregistered. + * + * @param pool To allocate the resource for the specified handle, + * which must be valid until the handle/key is unregistered + * from I/O Queue. + * @param ioque The I/O Queue. + * @param sock The socket. + * @param user_data User data to be associated with the key, which can be + * retrieved later. + * @param cb Callback to be called when I/O operation completes. + * @param key Pointer to receive the key to be associated with this + * socket. Subsequent I/O queue operation will need this + * key. + * + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_ioqueue_register_sock( pj_pool_t *pool, + pj_ioqueue_t *ioque, + pj_sock_t sock, + void *user_data, + const pj_ioqueue_callback *cb, + pj_ioqueue_key_t **key ); + +/** + * Unregister from the I/O Queue framework. Caller must make sure that + * the key doesn't have any pending operations before calling this function, + * by calling #pj_ioqueue_is_pending() for all previously submitted + * operations except asynchronous connect, and if necessary call + * #pj_ioqueue_post_completion() to cancel the pending operations. + * + * Note that asynchronous connect operation will automatically be + * cancelled during the unregistration. + * + * Also note that when I/O Completion Port backend is used, application + * MUST close the handle immediately after unregistering the key. This is + * because there is no unregistering API for IOCP. The only way to + * unregister the handle from IOCP is to close the handle. + * + * @param key The key that was previously obtained from registration. + * + * @return PJ_SUCCESS on success or the error code. + * + * @see pj_ioqueue_is_pending + */ +PJ_DECL(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key ); + + +/** + * Get user data associated with an ioqueue key. + * + * @param key The key that was previously obtained from registration. + * + * @return The user data associated with the descriptor, or NULL + * on error or if no data is associated with the key during + * registration. + */ +PJ_DECL(void*) pj_ioqueue_get_user_data( pj_ioqueue_key_t *key ); + +/** + * Set or change the user data to be associated with the file descriptor or + * handle or socket descriptor. + * + * @param key The key that was previously obtained from registration. + * @param user_data User data to be associated with the descriptor. + * @param old_data Optional parameter to retrieve the old user data. + * + * @return PJ_SUCCESS on success or the error code. + */ +PJ_DECL(pj_status_t) pj_ioqueue_set_user_data( pj_ioqueue_key_t *key, + void *user_data, + void **old_data); + +/** + * Configure whether the ioqueue is allowed to call the key's callback + * concurrently/in parallel. The default concurrency setting for the key + * is controlled by ioqueue's default concurrency value, which can be + * changed by calling #pj_ioqueue_set_default_concurrency(). + * + * If concurrency is allowed for the key, it means that if there are more + * than one pending operations complete simultaneously, more than one + * threads may call the key's callback at the same time. This generally + * would promote good scalability for application, at the expense of more + * complexity to manage the concurrent accesses in application's code. + * + * Alternatively application may disable the concurrent access by + * setting the \a allow flag to false. With concurrency disabled, only + * one thread can call the key's callback at one time. + * + * @param key The key that was previously obtained from registration. + * @param allow Set this to non-zero to allow concurrent callback calls + * and zero (PJ_FALSE) to disallow it. + * + * @return PJ_SUCCESS on success or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_ioqueue_set_concurrency(pj_ioqueue_key_t *key, + pj_bool_t allow); + +/** + * Acquire the key's mutex. When the key's concurrency is disabled, + * application may call this function to synchronize its operation + * with the key's callback (i.e. this function will block until the + * key's callback returns). + * + * @param key The key that was previously obtained from registration. + * + * @return PJ_SUCCESS on success or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_ioqueue_lock_key(pj_ioqueue_key_t *key); + +/** + * Release the lock previously acquired with pj_ioqueue_lock_key(). + * + * @param key The key that was previously obtained from registration. + * + * @return PJ_SUCCESS on success or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_ioqueue_unlock_key(pj_ioqueue_key_t *key); + +/** + * Initialize operation key. + * + * @param op_key The operation key to be initialied. + * @param size The size of the operation key. + */ +PJ_DECL(void) pj_ioqueue_op_key_init( pj_ioqueue_op_key_t *op_key, + pj_size_t size ); + +/** + * Check if operation is pending on the specified operation key. + * The \c op_key must have been initialized with #pj_ioqueue_op_key_init() + * or submitted as pending operation before, or otherwise the result + * is undefined. + * + * @param key The key. + * @param op_key The operation key, previously submitted to any of + * the I/O functions and has returned PJ_EPENDING. + * + * @return Non-zero if operation is still pending. + */ +PJ_DECL(pj_bool_t) pj_ioqueue_is_pending( pj_ioqueue_key_t *key, + pj_ioqueue_op_key_t *op_key ); + + +/** + * Post completion status to the specified operation key and call the + * appropriate callback. When the callback is called, the number of bytes + * received in read/write callback or the status in accept/connect callback + * will be set from the \c bytes_status parameter. + * + * @param key The key. + * @param op_key Pending operation key. + * @param bytes_status Number of bytes or status to be set. A good value + * to put here is -PJ_ECANCELLED. + * + * @return PJ_SUCCESS if completion status has been successfully + * sent. + */ +PJ_DECL(pj_status_t) pj_ioqueue_post_completion( pj_ioqueue_key_t *key, + pj_ioqueue_op_key_t *op_key, + pj_ssize_t bytes_status ); + + + +#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0 +/** + * Instruct I/O Queue to accept incoming connection on the specified + * listening socket. This function will return immediately (i.e. non-blocking) + * regardless whether a connection is immediately available. If the function + * can't complete immediately, the caller will be notified about the incoming + * connection when it calls pj_ioqueue_poll(). If a new connection is + * immediately available, the function returns PJ_SUCCESS with the new + * connection; in this case, the callback WILL NOT be called. + * + * @param key The key which registered to the server socket. + * @param op_key An operation specific key to be associated with the + * pending operation, so that application can keep track of + * which operation has been completed when the callback is + * called. + * @param new_sock Argument which contain pointer to receive the new socket + * for the incoming connection. + * @param local Optional argument which contain pointer to variable to + * receive local address. + * @param remote Optional argument which contain pointer to variable to + * receive the remote address. + * @param addrlen On input, contains the length of the buffer for the + * address, and on output, contains the actual length of the + * address. This argument is optional. + * @return + * - PJ_SUCCESS When connection is available immediately, and the + * parameters will be updated to contain information about + * the new connection. In this case, a completion callback + * WILL NOT be called. + * - PJ_EPENDING If no connection is available immediately. When a new + * connection arrives, the callback will be called. + * - non-zero which indicates the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_ioqueue_accept( pj_ioqueue_key_t *key, + pj_ioqueue_op_key_t *op_key, + pj_sock_t *new_sock, + pj_sockaddr_t *local, + pj_sockaddr_t *remote, + int *addrlen ); + +/** + * Initiate non-blocking socket connect. If the socket can NOT be connected + * immediately, asynchronous connect() will be scheduled and caller will be + * notified via completion callback when it calls pj_ioqueue_poll(). If + * socket is connected immediately, the function returns PJ_SUCCESS and + * completion callback WILL NOT be called. + * + * @param key The key associated with TCP socket + * @param addr The remote address. + * @param addrlen The remote address length. + * + * @return + * - PJ_SUCCESS If socket is connected immediately. In this case, the + * completion callback WILL NOT be called. + * - PJ_EPENDING If operation is queued, or + * - non-zero Indicates the error code. + */ +PJ_DECL(pj_status_t) pj_ioqueue_connect( pj_ioqueue_key_t *key, + const pj_sockaddr_t *addr, + int addrlen ); + +#endif /* PJ_HAS_TCP */ + +/** + * Poll the I/O Queue for completed events. + * + * Note: polling the ioqueue is not necessary in Symbian. Please see + * @ref PJ_SYMBIAN_OS for more info. + * + * @param ioque the I/O Queue. + * @param timeout polling timeout, or NULL if the thread wishes to wait + * indefinetely for the event. + * + * @return + * - zero if timed out (no event). + * - (<0) if error occured during polling. Callback will NOT be called. + * - (>1) to indicate numbers of events. Callbacks have been called. + */ +PJ_DECL(int) pj_ioqueue_poll( pj_ioqueue_t *ioque, + const pj_time_val *timeout); + + +/** + * Instruct the I/O Queue to read from the specified handle. This function + * returns immediately (i.e. non-blocking) regardless whether some data has + * been transfered. If the operation can't complete immediately, caller will + * be notified about the completion when it calls pj_ioqueue_poll(). If data + * is immediately available, the function will return PJ_SUCCESS and the + * callback WILL NOT be called. + * + * @param key The key that uniquely identifies the handle. + * @param op_key An operation specific key to be associated with the + * pending operation, so that application can keep track of + * which operation has been completed when the callback is + * called. Caller must make sure that this key remains + * valid until the function completes. + * @param buffer The buffer to hold the read data. The caller MUST make sure + * that this buffer remain valid until the framework completes + * reading the handle. + * @param length On input, it specifies the size of the buffer. If data is + * available to be read immediately, the function returns + * PJ_SUCCESS and this argument will be filled with the + * amount of data read. If the function is pending, caller + * will be notified about the amount of data read in the + * callback. This parameter can point to local variable in + * caller's stack and doesn't have to remain valid for the + * duration of pending operation. + * @param flags Recv flag. If flags has PJ_IOQUEUE_ALWAYS_ASYNC then + * the function will never return PJ_SUCCESS. + * + * @return + * - PJ_SUCCESS If immediate data has been received in the buffer. In this + * case, the callback WILL NOT be called. + * - PJ_EPENDING If the operation has been queued, and the callback will be + * called when data has been received. + * - non-zero The return value indicates the error code. + */ +PJ_DECL(pj_status_t) pj_ioqueue_recv( pj_ioqueue_key_t *key, + pj_ioqueue_op_key_t *op_key, + void *buffer, + pj_ssize_t *length, + pj_uint32_t flags ); + +/** + * This function behaves similarly as #pj_ioqueue_recv(), except that it is + * normally called for socket, and the remote address will also be returned + * along with the data. Caller MUST make sure that both buffer and addr + * remain valid until the framework completes reading the data. + * + * @param key The key that uniquely identifies the handle. + * @param op_key An operation specific key to be associated with the + * pending operation, so that application can keep track of + * which operation has been completed when the callback is + * called. + * @param buffer The buffer to hold the read data. The caller MUST make sure + * that this buffer remain valid until the framework completes + * reading the handle. + * @param length On input, it specifies the size of the buffer. If data is + * available to be read immediately, the function returns + * PJ_SUCCESS and this argument will be filled with the + * amount of data read. If the function is pending, caller + * will be notified about the amount of data read in the + * callback. This parameter can point to local variable in + * caller's stack and doesn't have to remain valid for the + * duration of pending operation. + * @param flags Recv flag. If flags has PJ_IOQUEUE_ALWAYS_ASYNC then + * the function will never return PJ_SUCCESS. + * @param addr Optional Pointer to buffer to receive the address. + * @param addrlen On input, specifies the length of the address buffer. + * On output, it will be filled with the actual length of + * the address. This argument can be NULL if \c addr is not + * specified. + * + * @return + * - PJ_SUCCESS If immediate data has been received. In this case, the + * callback must have been called before this function + * returns, and no pending operation is scheduled. + * - PJ_EPENDING If the operation has been queued. + * - non-zero The return value indicates the error code. + */ +PJ_DECL(pj_status_t) pj_ioqueue_recvfrom( pj_ioqueue_key_t *key, + pj_ioqueue_op_key_t *op_key, + void *buffer, + pj_ssize_t *length, + pj_uint32_t flags, + pj_sockaddr_t *addr, + int *addrlen); + +/** + * Instruct the I/O Queue to write to the handle. This function will return + * immediately (i.e. non-blocking) regardless whether some data has been + * transfered. If the function can't complete immediately, the caller will + * be notified about the completion when it calls pj_ioqueue_poll(). If + * operation completes immediately and data has been transfered, the function + * returns PJ_SUCCESS and the callback will NOT be called. + * + * @param key The key that identifies the handle. + * @param op_key An operation specific key to be associated with the + * pending operation, so that application can keep track of + * which operation has been completed when the callback is + * called. + * @param data The data to send. Caller MUST make sure that this buffer + * remains valid until the write operation completes. + * @param length On input, it specifies the length of data to send. When + * data was sent immediately, this function returns PJ_SUCCESS + * and this parameter contains the length of data sent. If + * data can not be sent immediately, an asynchronous operation + * is scheduled and caller will be notified via callback the + * number of bytes sent. This parameter can point to local + * variable on caller's stack and doesn't have to remain + * valid until the operation has completed. + * @param flags Send flags. If flags has PJ_IOQUEUE_ALWAYS_ASYNC then + * the function will never return PJ_SUCCESS. + * + * @return + * - PJ_SUCCESS If data was immediately transfered. In this case, no + * pending operation has been scheduled and the callback + * WILL NOT be called. + * - PJ_EPENDING If the operation has been queued. Once data base been + * transfered, the callback will be called. + * - non-zero The return value indicates the error code. + */ +PJ_DECL(pj_status_t) pj_ioqueue_send( pj_ioqueue_key_t *key, + pj_ioqueue_op_key_t *op_key, + const void *data, + pj_ssize_t *length, + pj_uint32_t flags ); + + +/** + * Instruct the I/O Queue to write to the handle. This function will return + * immediately (i.e. non-blocking) regardless whether some data has been + * transfered. If the function can't complete immediately, the caller will + * be notified about the completion when it calls pj_ioqueue_poll(). If + * operation completes immediately and data has been transfered, the function + * returns PJ_SUCCESS and the callback will NOT be called. + * + * @param key the key that identifies the handle. + * @param op_key An operation specific key to be associated with the + * pending operation, so that application can keep track of + * which operation has been completed when the callback is + * called. + * @param data the data to send. Caller MUST make sure that this buffer + * remains valid until the write operation completes. + * @param length On input, it specifies the length of data to send. When + * data was sent immediately, this function returns PJ_SUCCESS + * and this parameter contains the length of data sent. If + * data can not be sent immediately, an asynchronous operation + * is scheduled and caller will be notified via callback the + * number of bytes sent. This parameter can point to local + * variable on caller's stack and doesn't have to remain + * valid until the operation has completed. + * @param flags send flags. If flags has PJ_IOQUEUE_ALWAYS_ASYNC then + * the function will never return PJ_SUCCESS. + * @param addr Optional remote address. + * @param addrlen Remote address length, \c addr is specified. + * + * @return + * - PJ_SUCCESS If data was immediately written. + * - PJ_EPENDING If the operation has been queued. + * - non-zero The return value indicates the error code. + */ +PJ_DECL(pj_status_t) pj_ioqueue_sendto( pj_ioqueue_key_t *key, + pj_ioqueue_op_key_t *op_key, + const void *data, + pj_ssize_t *length, + pj_uint32_t flags, + const pj_sockaddr_t *addr, + int addrlen); + + +/** + * !} + */ + +PJ_END_DECL + +#endif /* __PJ_IOQUEUE_H__ */ + diff --git a/pjlib/include/pj/ip_helper.h b/pjlib/include/pj/ip_helper.h new file mode 100644 index 0000000..02441d3 --- /dev/null +++ b/pjlib/include/pj/ip_helper.h @@ -0,0 +1,97 @@ +/* $Id: ip_helper.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 + * + * 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_IP_ROUTE_H__ +#define __PJ_IP_ROUTE_H__ + +/** + * @file ip_helper.h + * @brief IP helper API + */ + +#include + +PJ_BEGIN_DECL + +/** + * @defgroup pj_ip_helper IP Interface and Routing Helper + * @ingroup PJ_IO + * @{ + * + * This module provides functions to query local host's IP interface and + * routing table. + */ + +/** + * This structure describes IP routing entry. + */ +typedef union pj_ip_route_entry +{ + /** IP routing entry for IP version 4 routing */ + struct + { + pj_in_addr if_addr; /**< Local interface IP address. */ + pj_in_addr dst_addr; /**< Destination IP address. */ + pj_in_addr mask; /**< Destination mask. */ + } ipv4; +} pj_ip_route_entry; + + +/** + * Enumerate the local IP interfaces currently active in the host. + * + * @param af Family of the address to be retrieved. Application + * may specify pj_AF_UNSPEC() to retrieve all addresses, + * or pj_AF_INET() or pj_AF_INET6() to retrieve interfaces + * with specific address family. + * @param count On input, specify the number of entries. On output, + * it will be filled with the actual number of entries. + * @param ifs Array of socket addresses, which address part will + * be filled with the interface address. The address + * family part will be initialized with the address + * family of the IP address. + * + * @return PJ_SUCCESS on success, or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_enum_ip_interface(int af, + unsigned *count, + pj_sockaddr ifs[]); + + +/** + * Enumerate the IP routing table for this host. + * + * @param count On input, specify the number of routes entries. On output, + * it will be filled with the actual number of route entries. + * @param routes Array of IP routing entries. + * + * @return PJ_SUCCESS on success, or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_enum_ip_route(unsigned *count, + pj_ip_route_entry routes[]); + + + +/** @} */ + +PJ_END_DECL + + +#endif /* __PJ_IP_ROUTE_H__ */ + diff --git a/pjlib/include/pj/list.h b/pjlib/include/pj/list.h new file mode 100644 index 0000000..d64c2bf --- /dev/null +++ b/pjlib/include/pj/list.h @@ -0,0 +1,273 @@ +/* $Id: list.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 + * + * 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_LIST_H__ +#define __PJ_LIST_H__ + +/** + * @file list.h + * @brief Linked List data structure. + */ + +#include + +PJ_BEGIN_DECL + +/* + * @defgroup PJ_DS Data Structure. + */ + +/** + * @defgroup PJ_LIST Linked List + * @ingroup PJ_DS + * @{ + * + * List in PJLIB is implemented as doubly-linked list, and it won't require + * dynamic memory allocation (just as all PJLIB data structures). The list here + * should be viewed more like a low level C list instead of high level C++ list + * (which normally are easier to use but require dynamic memory allocations), + * therefore all caveats with C list apply here too (such as you can NOT put + * a node in more than one lists). + * + * \section pj_list_example_sec Examples + * + * See below for examples on how to manipulate linked list: + * - @ref page_pjlib_samples_list_c + * - @ref page_pjlib_list_test + */ + + +/** + * Use this macro in the start of the structure declaration to declare that + * the structure can be used in the linked list operation. This macro simply + * declares additional member @a prev and @a next to the structure. + * @hideinitializer + */ +#define PJ_DECL_LIST_MEMBER(type) \ + /** List @a prev. */ \ + type *prev; \ + /** List @a next. */ \ + type *next + + +/** + * This structure describes generic list node and list. The owner of this list + * must initialize the 'value' member to an appropriate value (typically the + * owner itself). + */ +struct pj_list +{ + PJ_DECL_LIST_MEMBER(void); +}; + + +/** + * Initialize the list. + * Initially, the list will have no member, and function pj_list_empty() will + * always return nonzero (which indicates TRUE) for the newly initialized + * list. + * + * @param node The list head. + */ +PJ_INLINE(void) pj_list_init(pj_list_type * node) +{ + ((pj_list*)node)->next = ((pj_list*)node)->prev = node; +} + + +/** + * Check that the list is empty. + * + * @param node The list head. + * + * @return Non-zero if the list is empty, or zero if it is not empty. + * + */ +PJ_INLINE(int) pj_list_empty(const pj_list_type * node) +{ + return ((pj_list*)node)->next == node; +} + + +/** + * Insert the node to the list before the specified element position. + * + * @param pos The element to which the node will be inserted before. + * @param node The element to be inserted. + * + * @return void. + */ +PJ_IDECL(void) pj_list_insert_before(pj_list_type *pos, pj_list_type *node); + + +/** + * Insert the node to the back of the list. This is just an alias for + * #pj_list_insert_before(). + * + * @param list The list. + * @param node The element to be inserted. + */ +PJ_INLINE(void) pj_list_push_back(pj_list_type *list, pj_list_type *node) +{ + pj_list_insert_before(list, node); +} + + +/** + * Inserts all nodes in \a nodes to the target list. + * + * @param lst The target list. + * @param nodes Nodes list. + */ +PJ_IDECL(void) pj_list_insert_nodes_before(pj_list_type *lst, + pj_list_type *nodes); + +/** + * Insert a node to the list after the specified element position. + * + * @param pos The element in the list which will precede the inserted + * element. + * @param node The element to be inserted after the position element. + * + * @return void. + */ +PJ_IDECL(void) pj_list_insert_after(pj_list_type *pos, pj_list_type *node); + + +/** + * Insert the node to the front of the list. This is just an alias for + * #pj_list_insert_after(). + * + * @param list The list. + * @param node The element to be inserted. + */ +PJ_INLINE(void) pj_list_push_front(pj_list_type *list, pj_list_type *node) +{ + pj_list_insert_after(list, node); +} + + +/** + * Insert all nodes in \a nodes to the target list. + * + * @param lst The target list. + * @param nodes Nodes list. + */ +PJ_IDECL(void) pj_list_insert_nodes_after(pj_list_type *lst, + pj_list_type *nodes); + + +/** + * Remove elements from the source list, and insert them to the destination + * list. The elements of the source list will occupy the + * front elements of the target list. Note that the node pointed by \a list2 + * itself is not considered as a node, but rather as the list descriptor, so + * it will not be inserted to the \a list1. The elements to be inserted starts + * at \a list2->next. If \a list2 is to be included in the operation, use + * \a pj_list_insert_nodes_before. + * + * @param list1 The destination list. + * @param list2 The source list. + * + * @return void. + */ +PJ_IDECL(void) pj_list_merge_first(pj_list_type *list1, pj_list_type *list2); + + +/** + * Remove elements from the second list argument, and insert them to the list + * in the first argument. The elements from the second list will be appended + * to the first list. Note that the node pointed by \a list2 + * itself is not considered as a node, but rather as the list descriptor, so + * it will not be inserted to the \a list1. The elements to be inserted starts + * at \a list2->next. If \a list2 is to be included in the operation, use + * \a pj_list_insert_nodes_before. + * + * @param list1 The element in the list which will precede the inserted + * element. + * @param list2 The element in the list to be inserted. + * + * @return void. + */ +PJ_IDECL(void) pj_list_merge_last( pj_list_type *list1, pj_list_type *list2); + + +/** + * Erase the node from the list it currently belongs. + * + * @param node The element to be erased. + */ +PJ_IDECL(void) pj_list_erase(pj_list_type *node); + + +/** + * Find node in the list. + * + * @param list The list head. + * @param node The node element to be searched. + * + * @return The node itself if it is found in the list, or NULL if it is not + * found in the list. + */ +PJ_IDECL(pj_list_type*) pj_list_find_node(pj_list_type *list, + pj_list_type *node); + + +/** + * Search the list for the specified value, using the specified comparison + * function. This function iterates on nodes in the list, started with the + * first node, and call the user supplied comparison function until the + * comparison function returns ZERO. + * + * @param list The list head. + * @param value The user defined value to be passed in the comparison + * function + * @param comp The comparison function, which should return ZERO to + * indicate that the searched value is found. + * + * @return The first node that matched, or NULL if it is not found. + */ +PJ_IDECL(pj_list_type*) pj_list_search(pj_list_type *list, void *value, + int (*comp)(void *value, + const pj_list_type *node) + ); + + +/** + * Traverse the list to get the number of elements in the list. + * + * @param list The list head. + * + * @return Number of elements. + */ +PJ_IDECL(pj_size_t) pj_list_size(const pj_list_type *list); + + +/** + * @} + */ + +#if PJ_FUNCTIONS_ARE_INLINED +# include "list_i.h" +#endif + +PJ_END_DECL + +#endif /* __PJ_LIST_H__ */ + diff --git a/pjlib/include/pj/list_i.h b/pjlib/include/pj/list_i.h new file mode 100644 index 0000000..1ae8da8 --- /dev/null +++ b/pjlib/include/pj/list_i.h @@ -0,0 +1,121 @@ +/* $Id: list_i.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 + * + * 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 + */ + + +/* Internal */ +PJ_INLINE(void) pj_link_node(pj_list_type *prev, pj_list_type *next) +{ + ((pj_list*)prev)->next = next; + ((pj_list*)next)->prev = prev; +} + +PJ_IDEF(void) pj_list_insert_after(pj_list_type *pos, pj_list_type *node) +{ + ((pj_list*)node)->prev = pos; + ((pj_list*)node)->next = ((pj_list*)pos)->next; + ((pj_list*) ((pj_list*)pos)->next) ->prev = node; + ((pj_list*)pos)->next = node; +} + + +PJ_IDEF(void) pj_list_insert_before(pj_list_type *pos, pj_list_type *node) +{ + pj_list_insert_after(((pj_list*)pos)->prev, node); +} + + +PJ_IDEF(void) pj_list_insert_nodes_after(pj_list_type *pos, pj_list_type *lst) +{ + pj_list *lst_last = (pj_list *) ((pj_list*)lst)->prev; + pj_list *pos_next = (pj_list *) ((pj_list*)pos)->next; + + pj_link_node(pos, lst); + pj_link_node(lst_last, pos_next); +} + +PJ_IDEF(void) pj_list_insert_nodes_before(pj_list_type *pos, pj_list_type *lst) +{ + pj_list_insert_nodes_after(((pj_list*)pos)->prev, lst); +} + +PJ_IDEF(void) pj_list_merge_last(pj_list_type *lst1, pj_list_type *lst2) +{ + if (!pj_list_empty(lst2)) { + pj_link_node(((pj_list*)lst1)->prev, ((pj_list*)lst2)->next); + pj_link_node(((pj_list*)lst2)->prev, lst1); + pj_list_init(lst2); + } +} + +PJ_IDEF(void) pj_list_merge_first(pj_list_type *lst1, pj_list_type *lst2) +{ + if (!pj_list_empty(lst2)) { + pj_link_node(((pj_list*)lst2)->prev, ((pj_list*)lst1)->next); + pj_link_node(((pj_list*)lst1), ((pj_list*)lst2)->next); + pj_list_init(lst2); + } +} + +PJ_IDEF(void) pj_list_erase(pj_list_type *node) +{ + pj_link_node( ((pj_list*)node)->prev, ((pj_list*)node)->next); + + /* It'll be safer to init the next/prev fields to itself, to + * prevent multiple erase() from corrupting the list. See + * ticket #520 for one sample bug. + */ + pj_list_init(node); +} + + +PJ_IDEF(pj_list_type*) pj_list_find_node(pj_list_type *list, pj_list_type *node) +{ + pj_list *p = (pj_list *) ((pj_list*)list)->next; + while (p != list && p != node) + p = (pj_list *) p->next; + + return p==node ? p : NULL; +} + + +PJ_IDEF(pj_list_type*) pj_list_search(pj_list_type *list, void *value, + int (*comp)(void *value, const pj_list_type *node)) +{ + pj_list *p = (pj_list *) ((pj_list*)list)->next; + while (p != list && (*comp)(value, p) != 0) + p = (pj_list *) p->next; + + return p==list ? NULL : p; +} + + +PJ_IDEF(pj_size_t) pj_list_size(const pj_list_type *list) +{ + const pj_list *node = (const pj_list*) ((const pj_list*)list)->next; + pj_size_t count = 0; + + while (node != list) { + ++count; + node = (pj_list*)node->next; + } + + return count; +} + diff --git a/pjlib/include/pj/lock.h b/pjlib/include/pj/lock.h new file mode 100644 index 0000000..f0d3bc5 --- /dev/null +++ b/pjlib/include/pj/lock.h @@ -0,0 +1,154 @@ +/* $Id: lock.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 + * + * 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_LOCK_H__ +#define __PJ_LOCK_H__ + +/** + * @file lock.h + * @brief Higher abstraction for locking objects. + */ +#include + +PJ_BEGIN_DECL + +/** + * @defgroup PJ_LOCK Lock Objects + * @ingroup PJ_OS + * @{ + * + * Lock Objects are higher abstraction for different lock mechanisms. + * It offers the same API for manipulating different lock types (e.g. + * @ref PJ_MUTEX "mutex", @ref PJ_SEM "semaphores", or null locks). + * Because Lock Objects have the same API for different types of lock + * implementation, it can be passed around in function arguments. As the + * result, it can be used to control locking policy for a particular + * feature. + */ + + +/** + * Create simple, non recursive mutex lock object. + * + * @param pool Memory pool. + * @param name Lock object's name. + * @param lock Pointer to store the returned handle. + * + * @return PJ_SUCCESS or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_lock_create_simple_mutex( pj_pool_t *pool, + const char *name, + pj_lock_t **lock ); + +/** + * Create recursive mutex lock object. + * + * @param pool Memory pool. + * @param name Lock object's name. + * @param lock Pointer to store the returned handle. + * + * @return PJ_SUCCESS or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_lock_create_recursive_mutex( pj_pool_t *pool, + const char *name, + pj_lock_t **lock ); + + +/** + * Create NULL mutex. A NULL mutex doesn't actually have any synchronization + * object attached to it. + * + * @param pool Memory pool. + * @param name Lock object's name. + * @param lock Pointer to store the returned handle. + * + * @return PJ_SUCCESS or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_lock_create_null_mutex( pj_pool_t *pool, + const char *name, + pj_lock_t **lock ); + + +#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0 +/** + * Create semaphore lock object. + * + * @param pool Memory pool. + * @param name Lock object's name. + * @param initial Initial value of the semaphore. + * @param max Maximum value of the semaphore. + * @param lock Pointer to store the returned handle. + * + * @return PJ_SUCCESS or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_lock_create_semaphore( pj_pool_t *pool, + const char *name, + unsigned initial, + unsigned max, + pj_lock_t **lock ); + +#endif /* PJ_HAS_SEMAPHORE */ + +/** + * Acquire lock on the specified lock object. + * + * @param lock The lock object. + * + * @return PJ_SUCCESS or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_lock_acquire( pj_lock_t *lock ); + + +/** + * Try to acquire lock on the specified lock object. + * + * @param lock The lock object. + * + * @return PJ_SUCCESS or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_lock_tryacquire( pj_lock_t *lock ); + + +/** + * Release lock on the specified lock object. + * + * @param lock The lock object. + * + * @return PJ_SUCCESS or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_lock_release( pj_lock_t *lock ); + + +/** + * Destroy the lock object. + * + * @param lock The lock object. + * + * @return PJ_SUCCESS or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_lock_destroy( pj_lock_t *lock ); + + +/** @} */ + +PJ_END_DECL + + +#endif /* __PJ_LOCK_H__ */ + diff --git a/pjlib/include/pj/log.h b/pjlib/include/pj/log.h new file mode 100644 index 0000000..335a988 --- /dev/null +++ b/pjlib/include/pj/log.h @@ -0,0 +1,423 @@ +/* $Id: log.h 3752 2011-09-18 14:38:46Z bennylp $ */ +/* + * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono + * + * 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_LOG_H__ +#define __PJ_LOG_H__ + +/** + * @file log.h + * @brief Logging Utility. + */ + +#include +#include + +PJ_BEGIN_DECL + +/** + * @defgroup PJ_MISC Miscelaneous + */ + +/** + * @defgroup PJ_LOG Logging Facility + * @ingroup PJ_MISC + * @{ + * + * The PJLIB logging facility is a configurable, flexible, and convenient + * way to write logging or trace information. + * + * To write to the log, one uses construct like below: + * + *
+ *   ...
+ *   PJ_LOG(3, ("main.c", "Starting hello..."));
+ *   ...
+ *   PJ_LOG(3, ("main.c", "Hello world from process %d", pj_getpid()));
+ *   ...
+ * 
+ * + * In the above example, the number @b 3 controls the verbosity level of + * the information (which means "information", by convention). The string + * "main.c" specifies the source or sender of the message. + * + * + * \section pj_log_quick_sample_sec Examples + * + * For examples, see: + * - @ref page_pjlib_samples_log_c. + * + */ + +/** + * Log decoration flag, to be specified with #pj_log_set_decor(). + */ +enum pj_log_decoration +{ + PJ_LOG_HAS_DAY_NAME = 1, /**< Include day name [default: no] */ + PJ_LOG_HAS_YEAR = 2, /**< Include year digit [no] */ + PJ_LOG_HAS_MONTH = 4, /**< Include month [no] */ + PJ_LOG_HAS_DAY_OF_MON = 8, /**< Include day of month [no] */ + PJ_LOG_HAS_TIME = 16, /**< Include time [yes] */ + PJ_LOG_HAS_MICRO_SEC = 32, /**< Include microseconds [yes] */ + PJ_LOG_HAS_SENDER = 64, /**< Include sender in the log [yes] */ + PJ_LOG_HAS_NEWLINE = 128, /**< Terminate each call with newline [yes] */ + PJ_LOG_HAS_CR = 256, /**< Include carriage return [no] */ + PJ_LOG_HAS_SPACE = 512, /**< Include two spaces before log [yes] */ + PJ_LOG_HAS_COLOR = 1024, /**< Colorize logs [yes on win32] */ + PJ_LOG_HAS_LEVEL_TEXT = 2048, /**< Include level text string [no] */ + PJ_LOG_HAS_THREAD_ID = 4096, /**< Include thread identification [no] */ + PJ_LOG_HAS_THREAD_SWC = 8192, /**< Add mark when thread has switched [yes]*/ + PJ_LOG_HAS_INDENT =16384 /**< Indentation. Say yes! [yes] */ +}; + +/** + * Write log message. + * This is the main macro used to write text to the logging backend. + * + * @param level The logging verbosity level. Lower number indicates higher + * importance, with level zero indicates fatal error. Only + * numeral argument is permitted (e.g. not variable). + * @param arg Enclosed 'printf' like arguments, with the first + * argument is the sender, the second argument is format + * string and the following arguments are variable number of + * arguments suitable for the format string. + * + * Sample: + * \verbatim + PJ_LOG(2, (__FILE__, "current value is %d", value)); + \endverbatim + * @hideinitializer + */ +#define PJ_LOG(level,arg) do { \ + if (level <= pj_log_get_level()) \ + pj_log_wrapper_##level(arg); \ + } while (0) + +/** + * Signature for function to be registered to the logging subsystem to + * write the actual log message to some output device. + * + * @param level Log level. + * @param data Log message, which will be NULL terminated. + * @param len Message length. + */ +typedef void pj_log_func(int level, const char *data, int len); + +/** + * Default logging writer function used by front end logger function. + * This function will print the log message to stdout only. + * Application normally should NOT need to call this function, but + * rather use the PJ_LOG macro. + * + * @param level Log level. + * @param buffer Log message. + * @param len Message length. + */ +PJ_DECL(void) pj_log_write(int level, const char *buffer, int len); + + +#if PJ_LOG_MAX_LEVEL >= 1 + +/** + * Write to log. + * + * @param sender Source of the message. + * @param level Verbosity level. + * @param format Format. + * @param marker Marker. + */ +PJ_DECL(void) pj_log(const char *sender, int level, + const char *format, va_list marker); + +/** + * Change log output function. The front-end logging functions will call + * this function to write the actual message to the desired device. + * By default, the front-end functions use pj_log_write() to write + * the messages, unless it's changed by calling this function. + * + * @param func The function that will be called to write the log + * messages to the desired device. + */ +PJ_DECL(void) pj_log_set_log_func( pj_log_func *func ); + +/** + * Get the current log output function that is used to write log messages. + * + * @return Current log output function. + */ +PJ_DECL(pj_log_func*) pj_log_get_log_func(void); + +/** + * Set maximum log level. Application can call this function to set + * the desired level of verbosity of the logging messages. The bigger the + * value, the more verbose the logging messages will be printed. However, + * the maximum level of verbosity can not exceed compile time value of + * PJ_LOG_MAX_LEVEL. + * + * @param level The maximum level of verbosity of the logging + * messages (6=very detailed..1=error only, 0=disabled) + */ +PJ_DECL(void) pj_log_set_level(int level); + +/** + * Get current maximum log verbositylevel. + * + * @return Current log maximum level. + */ +#if 1 +PJ_DECL(int) pj_log_get_level(void); +#else +PJ_DECL_DATA(int) pj_log_max_level; +#define pj_log_get_level() pj_log_max_level +#endif + +/** + * Set log decoration. The log decoration flag controls what are printed + * to output device alongside the actual message. For example, application + * can specify that date/time information should be displayed with each + * log message. + * + * @param decor Bitmask combination of #pj_log_decoration to control + * the layout of the log message. + */ +PJ_DECL(void) pj_log_set_decor(unsigned decor); + +/** + * Get current log decoration flag. + * + * @return Log decoration flag. + */ +PJ_DECL(unsigned) pj_log_get_decor(void); + +/** + * Add indentation to log message. Indentation will add PJ_LOG_INDENT_CHAR + * before the message, and is useful to show the depth of function calls. + * + * @param indent The indentation to add or substract. Positive value + * adds current indent, negative value subtracts current + * indent. + */ +PJ_DECL(void) pj_log_add_indent(int indent); + +/** + * Push indentation to the right by default value (PJ_LOG_INDENT). + */ +PJ_DECL(void) pj_log_push_indent(void); + +/** + * Pop indentation (to the left) by default value (PJ_LOG_INDENT). + */ +PJ_DECL(void) pj_log_pop_indent(void); + +/** + * Set color of log messages. + * + * @param level Log level which color will be changed. + * @param color Desired color. + */ +PJ_DECL(void) pj_log_set_color(int level, pj_color_t color); + +/** + * Get color of log messages. + * + * @param level Log level which color will be returned. + * @return Log color. + */ +PJ_DECL(pj_color_t) pj_log_get_color(int level); + +/** + * Internal function to be called by pj_init() + */ +pj_status_t pj_log_init(void); + +#else /* #if PJ_LOG_MAX_LEVEL >= 1 */ + +/** + * Change log output function. The front-end logging functions will call + * this function to write the actual message to the desired device. + * By default, the front-end functions use pj_log_write() to write + * the messages, unless it's changed by calling this function. + * + * @param func The function that will be called to write the log + * messages to the desired device. + */ +# define pj_log_set_log_func(func) + +/** + * Set maximum log level. Application can call this function to set + * the desired level of verbosity of the logging messages. The bigger the + * value, the more verbose the logging messages will be printed. However, + * the maximum level of verbosity can not exceed compile time value of + * PJ_LOG_MAX_LEVEL. + * + * @param level The maximum level of verbosity of the logging + * messages (6=very detailed..1=error only, 0=disabled) + */ +# define pj_log_set_level(level) + +/** + * Set log decoration. The log decoration flag controls what are printed + * to output device alongside the actual message. For example, application + * can specify that date/time information should be displayed with each + * log message. + * + * @param decor Bitmask combination of #pj_log_decoration to control + * the layout of the log message. + */ +# define pj_log_set_decor(decor) + +/** + * Set color of log messages. + * + * @param level Log level which color will be changed. + * @param color Desired color. + */ +# define pj_log_set_color(level, color) + +/** + * Get current maximum log verbositylevel. + * + * @return Current log maximum level. + */ +# define pj_log_get_level() 0 + +/** + * Get current log decoration flag. + * + * @return Log decoration flag. + */ +# define pj_log_get_decor() 0 + +/** + * Get color of log messages. + * + * @param level Log level which color will be returned. + * @return Log color. + */ +# define pj_log_get_color(level) 0 + + +/** + * Internal. + */ +# define pj_log_init() PJ_SUCCESS + +#endif /* #if PJ_LOG_MAX_LEVEL >= 1 */ + +/** + * @} + */ + +/* **************************************************************************/ +/* + * Log functions implementation prototypes. + * These functions are called by PJ_LOG macros according to verbosity + * level specified when calling the macro. Applications should not normally + * need to call these functions directly. + */ + +/** + * @def pj_log_wrapper_1(arg) + * Internal function to write log with verbosity 1. Will evaluate to + * empty expression if PJ_LOG_MAX_LEVEL is below 1. + * @param arg Log expression. + */ +#if PJ_LOG_MAX_LEVEL >= 1 + #define pj_log_wrapper_1(arg) pj_log_1 arg + /** Internal function. */ + PJ_DECL(void) pj_log_1(const char *src, const char *format, ...); +#else + #define pj_log_wrapper_1(arg) +#endif + +/** + * @def pj_log_wrapper_2(arg) + * Internal function to write log with verbosity 2. Will evaluate to + * empty expression if PJ_LOG_MAX_LEVEL is below 2. + * @param arg Log expression. + */ +#if PJ_LOG_MAX_LEVEL >= 2 + #define pj_log_wrapper_2(arg) pj_log_2 arg + /** Internal function. */ + PJ_DECL(void) pj_log_2(const char *src, const char *format, ...); +#else + #define pj_log_wrapper_2(arg) +#endif + +/** + * @def pj_log_wrapper_3(arg) + * Internal function to write log with verbosity 3. Will evaluate to + * empty expression if PJ_LOG_MAX_LEVEL is below 3. + * @param arg Log expression. + */ +#if PJ_LOG_MAX_LEVEL >= 3 + #define pj_log_wrapper_3(arg) pj_log_3 arg + /** Internal function. */ + PJ_DECL(void) pj_log_3(const char *src, const char *format, ...); +#else + #define pj_log_wrapper_3(arg) +#endif + +/** + * @def pj_log_wrapper_4(arg) + * Internal function to write log with verbosity 4. Will evaluate to + * empty expression if PJ_LOG_MAX_LEVEL is below 4. + * @param arg Log expression. + */ +#if PJ_LOG_MAX_LEVEL >= 4 + #define pj_log_wrapper_4(arg) pj_log_4 arg + /** Internal function. */ + PJ_DECL(void) pj_log_4(const char *src, const char *format, ...); +#else + #define pj_log_wrapper_4(arg) +#endif + +/** + * @def pj_log_wrapper_5(arg) + * Internal function to write log with verbosity 5. Will evaluate to + * empty expression if PJ_LOG_MAX_LEVEL is below 5. + * @param arg Log expression. + */ +#if PJ_LOG_MAX_LEVEL >= 5 + #define pj_log_wrapper_5(arg) pj_log_5 arg + /** Internal function. */ + PJ_DECL(void) pj_log_5(const char *src, const char *format, ...); +#else + #define pj_log_wrapper_5(arg) +#endif + +/** + * @def pj_log_wrapper_6(arg) + * Internal function to write log with verbosity 6. Will evaluate to + * empty expression if PJ_LOG_MAX_LEVEL is below 6. + * @param arg Log expression. + */ +#if PJ_LOG_MAX_LEVEL >= 6 + #define pj_log_wrapper_6(arg) pj_log_6 arg + /** Internal function. */ + PJ_DECL(void) pj_log_6(const char *src, const char *format, ...); +#else + #define pj_log_wrapper_6(arg) +#endif + + +PJ_END_DECL + +#endif /* __PJ_LOG_H__ */ + diff --git a/pjlib/include/pj/math.h b/pjlib/include/pj/math.h new file mode 100644 index 0000000..22f3e4d --- /dev/null +++ b/pjlib/include/pj/math.h @@ -0,0 +1,197 @@ +/* $Id: math.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 + * + * 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_MATH_H__ +#define __PJ_MATH_H__ + +/** + * @file math.h + * @brief Mathematics and Statistics. + */ + +#include +#include + +PJ_BEGIN_DECL + +/** + * @defgroup pj_math Mathematics and Statistics + * @ingroup PJ_MISC + * @{ + * + * Provides common mathematics constants and operations, and also standard + * statistics calculation (min, max, mean, standard deviation). Statistics + * calculation is done in realtime (statistics state is updated on time each + * new sample comes). + */ + +/** + * Mathematical constants + */ +#define PJ_PI 3.14159265358979323846 /* pi */ +#define PJ_1_PI 0.318309886183790671538 /* 1/pi */ + +/** + * Mathematical macro + */ +#define PJ_ABS(x) ((x) > 0 ? (x) : -(x)) +#define PJ_MAX(x, y) ((x) > (y)? (x) : (y)) +#define PJ_MIN(x, y) ((x) < (y)? (x) : (y)) + +/** + * This structure describes statistics state. + */ +typedef struct pj_math_stat +{ + int n; /* number of samples */ + int max; /* maximum value */ + int min; /* minimum value */ + int last; /* last value */ + int mean; /* mean */ + + /* Private members */ +#if PJ_HAS_FLOATING_POINT + float fmean_; /* mean(floating point) */ +#else + int mean_res_; /* mean residu */ +#endif + pj_highprec_t m2_; /* variance * n */ +} pj_math_stat; + +/** + * Calculate integer square root of an integer. + * + * @param i Integer to be calculated. + * + * @return Square root result. + */ +PJ_INLINE(unsigned) pj_isqrt(unsigned i) +{ + unsigned res = 1, prev; + + /* Rough guess, calculate half bit of input */ + prev = i >> 2; + while (prev) { + prev >>= 2; + res <<= 1; + } + + /* Babilonian method */ + do { + prev = res; + res = (prev + i/prev) >> 1; + } while ((prev+res)>>1 != res); + + return res; +} + +/** + * Initialize statistics state. + * + * @param stat Statistic state. + */ +PJ_INLINE(void) pj_math_stat_init(pj_math_stat *stat) +{ + pj_bzero(stat, sizeof(pj_math_stat)); +} + +/** + * Update statistics state as a new sample comes. + * + * @param stat Statistic state. + * @param val The new sample data. + */ +PJ_INLINE(void) pj_math_stat_update(pj_math_stat *stat, int val) +{ +#if PJ_HAS_FLOATING_POINT + float delta; +#else + int delta; +#endif + + stat->last = val; + + if (stat->n++) { + if (stat->min > val) + stat->min = val; + if (stat->max < val) + stat->max = val; + } else { + stat->min = stat->max = val; + } + +#if PJ_HAS_FLOATING_POINT + delta = val - stat->fmean_; + stat->fmean_ += delta/stat->n; + + /* Return mean value with 'rounding' */ + stat->mean = (int) (stat->fmean_ + 0.5); + + stat->m2_ += (int)(delta * (val-stat->fmean_)); +#else + delta = val - stat->mean; + stat->mean += delta/stat->n; + stat->mean_res_ += delta % stat->n; + if (stat->mean_res_ >= stat->n) { + ++stat->mean; + stat->mean_res_ -= stat->n; + } else if (stat->mean_res_ <= -stat->n) { + --stat->mean; + stat->mean_res_ += stat->n; + } + + stat->m2_ += delta * (val-stat->mean); +#endif +} + +/** + * Get the standard deviation of specified statistics state. + * + * @param stat Statistic state. + * + * @return The standard deviation. + */ +PJ_INLINE(unsigned) pj_math_stat_get_stddev(const pj_math_stat *stat) +{ + if (stat->n == 0) return 0; + return (pj_isqrt((unsigned)(stat->m2_/stat->n))); +} + +/** + * Set the standard deviation of statistics state. This is useful when + * the statistic state is operated in 'read-only' mode as a storage of + * statistical data. + * + * @param stat Statistic state. + * + * @param dev The standard deviation. + */ +PJ_INLINE(void) pj_math_stat_set_stddev(pj_math_stat *stat, unsigned dev) +{ + if (stat->n == 0) + stat->n = 1; + stat->m2_ = dev*dev*stat->n; +} + +/** @} */ + +PJ_END_DECL + +#endif /* __PJ_MATH_H__ */ diff --git a/pjlib/include/pj/os.h b/pjlib/include/pj/os.h new file mode 100644 index 0000000..9733bb9 --- /dev/null +++ b/pjlib/include/pj/os.h @@ -0,0 +1,1476 @@ +/* $Id: os.h 3664 2011-07-19 03:42:28Z nanang $ */ +/* + * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono + * + * 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_OS_H__ +#define __PJ_OS_H__ + +/** + * @file os.h + * @brief OS dependent functions + */ +#include + +PJ_BEGIN_DECL + +/** + * @defgroup PJ_OS Operating System Dependent Functionality. + */ + + +/* **************************************************************************/ +/** + * @defgroup PJ_SYS_INFO System Information + * @ingroup PJ_OS + * @{ + */ + +/** + * These enumeration contains constants to indicate support of miscellaneous + * system features. These will go in "flags" field of #pj_sys_info structure. + */ +typedef enum pj_sys_info_flag +{ + /** + * Support for Apple iOS background feature. + */ + PJ_SYS_HAS_IOS_BG = 1 + +} pj_sys_info_flag; + + +/** + * This structure contains information about the system. Use #pj_get_sys_info() + * to obtain the system information. + */ +typedef struct pj_sys_info +{ + /** + * Null terminated string containing processor information (e.g. "i386", + * "x86_64"). It may contain empty string if the value cannot be obtained. + */ + pj_str_t machine; + + /** + * Null terminated string identifying the system operation (e.g. "Linux", + * "win32", "wince"). It may contain empty string if the value cannot be + * obtained. + */ + pj_str_t os_name; + + /** + * A number containing the operating system version number. By convention, + * this field is divided into four bytes, where the highest order byte + * contains the most major version of the OS, the next less significant + * byte contains the less major version, and so on. How the OS version + * number is mapped into these four bytes would be specific for each OS. + * For example, Linux-2.6.32-28 would yield "os_ver" value of 0x0206201c, + * while for Windows 7 it will be 0x06010000 (because dwMajorVersion is + * 6 and dwMinorVersion is 1 for Windows 7). + * + * This field may contain zero if the OS version cannot be obtained. + */ + pj_uint32_t os_ver; + + /** + * Null terminated string identifying the SDK name that is used to build + * the library (e.g. "glibc", "uclibc", "msvc", "wince"). It may contain + * empty string if the value cannot eb obtained. + */ + pj_str_t sdk_name; + + /** + * A number containing the SDK version, using the numbering convention as + * the "os_ver" field. The value will be zero if the version cannot be + * obtained. + */ + pj_uint32_t sdk_ver; + + /** + * A longer null terminated string identifying the underlying system with + * as much information as possible. + */ + pj_str_t info; + + /** + * Other flags containing system specific information. The value is + * bitmask of #pj_sys_info_flag constants. + */ + pj_uint32_t flags; + +} pj_sys_info; + + +/** + * Obtain the system information. + * + * @return System information structure. + */ +PJ_DECL(const pj_sys_info*) pj_get_sys_info(void); + +/* + * @} + */ + +/* **************************************************************************/ +/** + * @defgroup PJ_THREAD Threads + * @ingroup PJ_OS + * @{ + * This module provides multithreading API. + * + * \section pj_thread_examples_sec Examples + * + * For examples, please see: + * - \ref page_pjlib_thread_test + * - \ref page_pjlib_sleep_test + * + */ + +/** + * Thread creation flags: + * - PJ_THREAD_SUSPENDED: specify that the thread should be created suspended. + */ +typedef enum pj_thread_create_flags +{ + PJ_THREAD_SUSPENDED = 1 +} pj_thread_create_flags; + + +/** + * Type of thread entry function. + */ +typedef int (PJ_THREAD_FUNC pj_thread_proc)(void*); + +/** + * Size of thread struct. + */ +#if !defined(PJ_THREAD_DESC_SIZE) +# define PJ_THREAD_DESC_SIZE (64) +#endif + +/** + * Thread structure, to thread's state when the thread is created by external + * or native API. + */ +typedef long pj_thread_desc[PJ_THREAD_DESC_SIZE]; + +/** + * Get process ID. + * @return process ID. + */ +PJ_DECL(pj_uint32_t) pj_getpid(void); + +/** + * Create a new thread. + * + * @param pool The memory pool from which the thread record + * will be allocated from. + * @param thread_name The optional name to be assigned to the thread. + * @param proc Thread entry function. + * @param arg Argument to be passed to the thread entry function. + * @param stack_size The size of the stack for the new thread, or ZERO or + * PJ_THREAD_DEFAULT_STACK_SIZE to let the + * library choose the reasonable size for the stack. + * For some systems, the stack will be allocated from + * the pool, so the pool must have suitable capacity. + * @param flags Flags for thread creation, which is bitmask combination + * from enum pj_thread_create_flags. + * @param thread Pointer to hold the newly created thread. + * + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_thread_create( pj_pool_t *pool, + const char *thread_name, + pj_thread_proc *proc, + void *arg, + pj_size_t stack_size, + unsigned flags, + pj_thread_t **thread ); + +/** + * Register a thread that was created by external or native API to PJLIB. + * This function must be called in the context of the thread being registered. + * When the thread is created by external function or API call, + * it must be 'registered' to PJLIB using pj_thread_register(), so that it can + * cooperate with PJLIB's framework. During registration, some data needs to + * be maintained, and this data must remain available during the thread's + * lifetime. + * + * @param thread_name The optional name to be assigned to the thread. + * @param desc Thread descriptor, which must be available throughout + * the lifetime of the thread. + * @param thread Pointer to hold the created thread handle. + * + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_thread_register ( const char *thread_name, + pj_thread_desc desc, + pj_thread_t **thread); + +/** + * Check if this thread has been registered to PJLIB. + * + * @return Non-zero if it is registered. + */ +PJ_DECL(pj_bool_t) pj_thread_is_registered(void); + + +/** + * Get thread priority value for the thread. + * + * @param thread Thread handle. + * + * @return Thread priority value, or -1 on error. + */ +PJ_DECL(int) pj_thread_get_prio(pj_thread_t *thread); + + +/** + * Set the thread priority. The priority value must be in the priority + * value range, which can be retrieved with #pj_thread_get_prio_min() and + * #pj_thread_get_prio_max() functions. + * + * @param thread Thread handle. + * @param prio New priority to be set to the thread. + * + * @return PJ_SUCCESS on success or the error code. + */ +PJ_DECL(pj_status_t) pj_thread_set_prio(pj_thread_t *thread, int prio); + +/** + * Get the lowest priority value available for this thread. + * + * @param thread Thread handle. + * @return Minimum thread priority value, or -1 on error. + */ +PJ_DECL(int) pj_thread_get_prio_min(pj_thread_t *thread); + + +/** + * Get the highest priority value available for this thread. + * + * @param thread Thread handle. + * @return Minimum thread priority value, or -1 on error. + */ +PJ_DECL(int) pj_thread_get_prio_max(pj_thread_t *thread); + + +/** + * Return native handle from pj_thread_t for manipulation using native + * OS APIs. + * + * @param thread PJLIB thread descriptor. + * + * @return Native thread handle. For example, when the + * backend thread uses pthread, this function will + * return pointer to pthread_t, and on Windows, + * this function will return HANDLE. + */ +PJ_DECL(void*) pj_thread_get_os_handle(pj_thread_t *thread); + +/** + * Get thread name. + * + * @param thread The thread handle. + * + * @return Thread name as null terminated string. + */ +PJ_DECL(const char*) pj_thread_get_name(pj_thread_t *thread); + +/** + * Resume a suspended thread. + * + * @param thread The thread handle. + * + * @return zero on success. + */ +PJ_DECL(pj_status_t) pj_thread_resume(pj_thread_t *thread); + +/** + * Get the current thread. + * + * @return Thread handle of current thread. + */ +PJ_DECL(pj_thread_t*) pj_thread_this(void); + +/** + * Join thread, and block the caller thread until the specified thread exits. + * If the specified thread has already been dead, or it does not exist, + * the function will return immediately with successfull status. + * + * @param thread The thread handle. + * + * @return PJ_SUCCESS on success. + */ +PJ_DECL(pj_status_t) pj_thread_join(pj_thread_t *thread); + + +/** + * Destroy thread and release resources allocated for the thread. + * However, the memory allocated for the pj_thread_t itself will only be released + * when the pool used to create the thread is destroyed. + * + * @param thread The thread handle. + * + * @return zero on success. + */ +PJ_DECL(pj_status_t) pj_thread_destroy(pj_thread_t *thread); + + +/** + * Put the current thread to sleep for the specified miliseconds. + * + * @param msec Miliseconds delay. + * + * @return zero if successfull. + */ +PJ_DECL(pj_status_t) pj_thread_sleep(unsigned msec); + +/** + * @def PJ_CHECK_STACK() + * PJ_CHECK_STACK() macro is used to check the sanity of the stack. + * The OS implementation may check that no stack overflow occurs, and + * it also may collect statistic about stack usage. + */ +#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0 + +# define PJ_CHECK_STACK() pj_thread_check_stack(__FILE__, __LINE__) + +/** @internal + * The implementation of stack checking. + */ +PJ_DECL(void) pj_thread_check_stack(const char *file, int line); + +/** @internal + * Get maximum stack usage statistic. + */ +PJ_DECL(pj_uint32_t) pj_thread_get_stack_max_usage(pj_thread_t *thread); + +/** @internal + * Dump thread stack status. + */ +PJ_DECL(pj_status_t) pj_thread_get_stack_info(pj_thread_t *thread, + const char **file, + int *line); +#else + +# define PJ_CHECK_STACK() +/** pj_thread_get_stack_max_usage() for the thread */ +# define pj_thread_get_stack_max_usage(thread) 0 +/** pj_thread_get_stack_info() for the thread */ +# define pj_thread_get_stack_info(thread,f,l) (*(f)="",*(l)=0) +#endif /* PJ_OS_HAS_CHECK_STACK */ + +/** + * @} + */ + +/* **************************************************************************/ +/** + * @defgroup PJ_SYMBIAN_OS Symbian OS Specific + * @ingroup PJ_OS + * @{ + * Functionalities specific to Symbian OS. + * + * Symbian OS strongly discourages the use of polling since this wastes + * CPU power, and instead provides Active Object and Active Scheduler + * pattern to allow application (in this case, PJLIB) to register asynchronous + * tasks. PJLIB port for Symbian complies to this recommended behavior. + * As the result, few things have been changed in PJLIB for Symbian: + * - the timer heap (see @ref PJ_TIMER) is implemented with active + * object framework, and each timer entry registered to the timer + * heap will register an Active Object to the Active Scheduler. + * Because of this, polling the timer heap with pj_timer_heap_poll() + * is no longer necessary, and this function will just evaluate + * to nothing. + * - the ioqueue (see @ref PJ_IOQUEUE) is also implemented with + * active object framework, with each asynchronous operation will + * register an Active Object to the Active Scheduler. Because of + * this, polling the ioqueue with pj_ioqueue_poll() is no longer + * necessary, and this function will just evaluate to nothing. + * + * Since timer heap and ioqueue polling are no longer necessary, Symbian + * application can now poll for all events by calling + * \a User::WaitForAnyRequest() and \a CActiveScheduler::RunIfReady(). + * PJLIB provides a thin wrapper which calls these two functions, + * called pj_symbianos_poll(). + */ + +/** + * Wait the completion of any Symbian active objects. When the timeout + * value is not specified (the \a ms_timeout argument is -1), this + * function is a thin wrapper which calls \a User::WaitForAnyRequest() + * and \a CActiveScheduler::RunIfReady(). If the timeout value is + * specified, this function will schedule a timer entry to the timer + * heap (which is an Active Object), to limit the wait time for event + * occurences. Scheduling a timer entry is an expensive operation, + * therefore application should only specify a timeout value when it's + * really necessary (for example, when it's not sure there are other + * Active Objects currently running in the application). + * + * @param priority The minimum priority of the Active Objects to + * poll, which values are from CActive::TPriority + * constants. If -1 is given, CActive::EPriorityStandard. + * priority will be used. + * @param ms_timeout Optional timeout to wait. Application should + * specify -1 to let the function wait indefinitely + * for any events. + * + * @return PJ_TRUE if there have been any events executed + * during the polling. This function will only return + * PJ_FALSE if \a ms_timeout argument is specified + * (i.e. the value is not -1) and there was no event + * executed when the timeout timer elapsed. + */ +PJ_DECL(pj_bool_t) pj_symbianos_poll(int priority, int ms_timeout); + + +/** + * This structure declares Symbian OS specific parameters that can be + * specified when calling #pj_symbianos_set_params(). + */ +typedef struct pj_symbianos_params +{ + /** + * Optional RSocketServ instance to be used by PJLIB. If this + * value is NULL, PJLIB will create a new RSocketServ instance + * when pj_init() is called. + */ + void *rsocketserv; + + /** + * Optional RConnection instance to be used by PJLIB when creating + * sockets. If this value is NULL, no RConnection will be + * specified when creating sockets. + */ + void *rconnection; + + /** + * Optional RHostResolver instance to be used by PJLIB. If this value + * is NULL, a new RHostResolver instance will be created when + * pj_init() is called. + */ + void *rhostresolver; + + /** + * Optional RHostResolver for IPv6 instance to be used by PJLIB. + * If this value is NULL, a new RHostResolver instance will be created + * when pj_init() is called. + */ + void *rhostresolver6; + +} pj_symbianos_params; + +/** + * Specify Symbian OS parameters to be used by PJLIB. This function MUST + * be called before #pj_init() is called. + * + * @param prm Symbian specific parameters. + * + * @return PJ_SUCCESS if the parameters can be applied + * successfully. + */ +PJ_DECL(pj_status_t) pj_symbianos_set_params(pj_symbianos_params *prm); + +/** + * Notify PJLIB that the access point connection has been down or unusable + * and PJLIB should not try to access the Symbian socket API (especially ones + * that send packets). Sending packet when RConnection is reconnected to + * different access point may cause the WaitForRequest() for the function to + * block indefinitely. + * + * @param up If set to PJ_FALSE it will cause PJLIB to not try + * to access socket API, and error will be returned + * immediately instead. + */ +PJ_DECL(void) pj_symbianos_set_connection_status(pj_bool_t up); + +/** + * @} + */ + +/* **************************************************************************/ +/** + * @defgroup PJ_TLS Thread Local Storage. + * @ingroup PJ_OS + * @{ + */ + +/** + * Allocate thread local storage index. The initial value of the variable at + * the index is zero. + * + * @param index Pointer to hold the return value. + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_thread_local_alloc(long *index); + +/** + * Deallocate thread local variable. + * + * @param index The variable index. + */ +PJ_DECL(void) pj_thread_local_free(long index); + +/** + * Set the value of thread local variable. + * + * @param index The index of the variable. + * @param value The value. + */ +PJ_DECL(pj_status_t) pj_thread_local_set(long index, void *value); + +/** + * Get the value of thread local variable. + * + * @param index The index of the variable. + * @return The value. + */ +PJ_DECL(void*) pj_thread_local_get(long index); + + +/** + * @} + */ + + +/* **************************************************************************/ +/** + * @defgroup PJ_ATOMIC Atomic Variables + * @ingroup PJ_OS + * @{ + * + * This module provides API to manipulate atomic variables. + * + * \section pj_atomic_examples_sec Examples + * + * For some example codes, please see: + * - @ref page_pjlib_atomic_test + */ + + +/** + * Create atomic variable. + * + * @param pool The pool. + * @param initial The initial value of the atomic variable. + * @param atomic Pointer to hold the atomic variable upon return. + * + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_atomic_create( pj_pool_t *pool, + pj_atomic_value_t initial, + pj_atomic_t **atomic ); + +/** + * Destroy atomic variable. + * + * @param atomic_var the atomic variable. + * + * @return PJ_SUCCESS if success. + */ +PJ_DECL(pj_status_t) pj_atomic_destroy( pj_atomic_t *atomic_var ); + +/** + * Set the value of an atomic type, and return the previous value. + * + * @param atomic_var the atomic variable. + * @param value value to be set to the variable. + */ +PJ_DECL(void) pj_atomic_set( pj_atomic_t *atomic_var, + pj_atomic_value_t value); + +/** + * Get the value of an atomic type. + * + * @param atomic_var the atomic variable. + * + * @return the value of the atomic variable. + */ +PJ_DECL(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *atomic_var); + +/** + * Increment the value of an atomic type. + * + * @param atomic_var the atomic variable. + */ +PJ_DECL(void) pj_atomic_inc(pj_atomic_t *atomic_var); + +/** + * Increment the value of an atomic type and get the result. + * + * @param atomic_var the atomic variable. + * + * @return The incremented value. + */ +PJ_DECL(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var); + +/** + * Decrement the value of an atomic type. + * + * @param atomic_var the atomic variable. + */ +PJ_DECL(void) pj_atomic_dec(pj_atomic_t *atomic_var); + +/** + * Decrement the value of an atomic type and get the result. + * + * @param atomic_var the atomic variable. + * + * @return The decremented value. + */ +PJ_DECL(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var); + +/** + * Add a value to an atomic type. + * + * @param atomic_var The atomic variable. + * @param value Value to be added. + */ +PJ_DECL(void) pj_atomic_add( pj_atomic_t *atomic_var, + pj_atomic_value_t value); + +/** + * Add a value to an atomic type and get the result. + * + * @param atomic_var The atomic variable. + * @param value Value to be added. + * + * @return The result after the addition. + */ +PJ_DECL(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var, + pj_atomic_value_t value); + +/** + * @} + */ + +/* **************************************************************************/ +/** + * @defgroup PJ_MUTEX Mutexes. + * @ingroup PJ_OS + * @{ + * + * Mutex manipulation. Alternatively, application can use higher abstraction + * for lock objects, which provides uniform API for all kinds of lock + * mechanisms, including mutex. See @ref PJ_LOCK for more information. + */ + +/** + * Mutex types: + * - PJ_MUTEX_DEFAULT: default mutex type, which is system dependent. + * - PJ_MUTEX_SIMPLE: non-recursive mutex. + * - PJ_MUTEX_RECURSE: recursive mutex. + */ +typedef enum pj_mutex_type_e +{ + PJ_MUTEX_DEFAULT, + PJ_MUTEX_SIMPLE, + PJ_MUTEX_RECURSE +} pj_mutex_type_e; + + +/** + * Create mutex of the specified type. + * + * @param pool The pool. + * @param name Name to be associated with the mutex (for debugging). + * @param type The type of the mutex, of type #pj_mutex_type_e. + * @param mutex Pointer to hold the returned mutex instance. + * + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_mutex_create(pj_pool_t *pool, + const char *name, + int type, + pj_mutex_t **mutex); + +/** + * Create simple, non-recursive mutex. + * This function is a simple wrapper for #pj_mutex_create to create + * non-recursive mutex. + * + * @param pool The pool. + * @param name Mutex name. + * @param mutex Pointer to hold the returned mutex instance. + * + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool, const char *name, + pj_mutex_t **mutex ); + +/** + * Create recursive mutex. + * This function is a simple wrapper for #pj_mutex_create to create + * recursive mutex. + * + * @param pool The pool. + * @param name Mutex name. + * @param mutex Pointer to hold the returned mutex instance. + * + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool, + const char *name, + pj_mutex_t **mutex ); + +/** + * Acquire mutex lock. + * + * @param mutex The mutex. + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex); + +/** + * Release mutex lock. + * + * @param mutex The mutex. + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex); + +/** + * Try to acquire mutex lock. + * + * @param mutex The mutex. + * @return PJ_SUCCESS on success, or the error code if the + * lock couldn't be acquired. + */ +PJ_DECL(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex); + +/** + * Destroy mutex. + * + * @param mutex Te mutex. + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex); + +/** + * Determine whether calling thread is owning the mutex (only available when + * PJ_DEBUG is set). + * @param mutex The mutex. + * @return Non-zero if yes. + */ +PJ_DECL(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex); + +/** + * @} + */ + +/* **************************************************************************/ +/** + * @defgroup PJ_RW_MUTEX Reader/Writer Mutex + * @ingroup PJ_OS + * @{ + * Reader/writer mutex is a classic synchronization object where multiple + * readers can acquire the mutex, but only a single writer can acquire the + * mutex. + */ + +/** + * Opaque declaration for reader/writer mutex. + * Reader/writer mutex is a classic synchronization object where multiple + * readers can acquire the mutex, but only a single writer can acquire the + * mutex. + */ +typedef struct pj_rwmutex_t pj_rwmutex_t; + +/** + * Create reader/writer mutex. + * + * @param pool Pool to allocate memory for the mutex. + * @param name Name to be assigned to the mutex. + * @param mutex Pointer to receive the newly created mutex. + * + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_rwmutex_create(pj_pool_t *pool, const char *name, + pj_rwmutex_t **mutex); + +/** + * Lock the mutex for reading. + * + * @param mutex The mutex. + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_rwmutex_lock_read(pj_rwmutex_t *mutex); + +/** + * Lock the mutex for writing. + * + * @param mutex The mutex. + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_rwmutex_lock_write(pj_rwmutex_t *mutex); + +/** + * Release read lock. + * + * @param mutex The mutex. + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_rwmutex_unlock_read(pj_rwmutex_t *mutex); + +/** + * Release write lock. + * + * @param mutex The mutex. + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_rwmutex_unlock_write(pj_rwmutex_t *mutex); + +/** + * Destroy reader/writer mutex. + * + * @param mutex The mutex. + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_rwmutex_destroy(pj_rwmutex_t *mutex); + + +/** + * @} + */ + + +/* **************************************************************************/ +/** + * @defgroup PJ_CRIT_SEC Critical sections. + * @ingroup PJ_OS + * @{ + * Critical section protection can be used to protect regions where: + * - mutual exclusion protection is needed. + * - it's rather too expensive to create a mutex. + * - the time spent in the region is very very brief. + * + * Critical section is a global object, and it prevents any threads from + * entering any regions that are protected by critical section once a thread + * is already in the section. + * + * Critial section is \a not recursive! + * + * Application MUST NOT call any functions that may cause current + * thread to block (such as allocating memory, performing I/O, locking mutex, + * etc.) while holding the critical section. + */ +/** + * Enter critical section. + */ +PJ_DECL(void) pj_enter_critical_section(void); + +/** + * Leave critical section. + */ +PJ_DECL(void) pj_leave_critical_section(void); + +/** + * @} + */ + +/* **************************************************************************/ +#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0 +/** + * @defgroup PJ_SEM Semaphores. + * @ingroup PJ_OS + * @{ + * + * This module provides abstraction for semaphores, where available. + */ + +/** + * Create semaphore. + * + * @param pool The pool. + * @param name Name to be assigned to the semaphore (for logging purpose) + * @param initial The initial count of the semaphore. + * @param max The maximum count of the semaphore. + * @param sem Pointer to hold the semaphore created. + * + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_sem_create( pj_pool_t *pool, + const char *name, + unsigned initial, + unsigned max, + pj_sem_t **sem); + +/** + * Wait for semaphore. + * + * @param sem The semaphore. + * + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_sem_wait(pj_sem_t *sem); + +/** + * Try wait for semaphore. + * + * @param sem The semaphore. + * + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_sem_trywait(pj_sem_t *sem); + +/** + * Release semaphore. + * + * @param sem The semaphore. + * + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_sem_post(pj_sem_t *sem); + +/** + * Destroy semaphore. + * + * @param sem The semaphore. + * + * @return PJ_SUCCESS on success, or the error code. + */ +PJ_DECL(pj_status_t) pj_sem_destroy(pj_sem_t *sem); + +/** + * @} + */ +#endif /* PJ_HAS_SEMAPHORE */ + + +/* **************************************************************************/ +#if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0 +/** + * @defgroup PJ_EVENT Event Object. + * @ingroup PJ_OS + * @{ + * + * This module provides abstraction to event object (e.g. Win32 Event) where + * available. Event objects can be used for synchronization among threads. + */ + +/** + * Create event object. + * + * @param pool The pool. + * @param name The name of the event object (for logging purpose). + * @param manual_reset Specify whether the event is manual-reset + * @param initial Specify the initial state of the event object. + * @param event Pointer to hold the returned event object. + * + * @return event handle, or NULL if failed. + */ +PJ_DECL(pj_status_t) pj_event_create(pj_pool_t *pool, const char *name, + pj_bool_t manual_reset, pj_bool_t initial, + pj_event_t **event); + +/** + * Wait for event to be signaled. + * + * @param event The event object. + * + * @return zero if successfull. + */ +PJ_DECL(pj_status_t) pj_event_wait(pj_event_t *event); + +/** + * Try wait for event object to be signalled. + * + * @param event The event object. + * + * @return zero if successfull. + */ +PJ_DECL(pj_status_t) pj_event_trywait(pj_event_t *event); + +/** + * Set the event object state to signaled. For auto-reset event, this + * will only release the first thread that are waiting on the event. For + * manual reset event, the state remains signaled until the event is reset. + * If there is no thread waiting on the event, the event object state + * remains signaled. + * + * @param event The event object. + * + * @return zero if successfull. + */ +PJ_DECL(pj_status_t) pj_event_set(pj_event_t *event); + +/** + * Set the event object to signaled state to release appropriate number of + * waiting threads and then reset the event object to non-signaled. For + * manual-reset event, this function will release all waiting threads. For + * auto-reset event, this function will only release one waiting thread. + * + * @param event The event object. + * + * @return zero if successfull. + */ +PJ_DECL(pj_status_t) pj_event_pulse(pj_event_t *event); + +/** + * Set the event object state to non-signaled. + * + * @param event The event object. + * + * @return zero if successfull. + */ +PJ_DECL(pj_status_t) pj_event_reset(pj_event_t *event); + +/** + * Destroy the event object. + * + * @param event The event object. + * + * @return zero if successfull. + */ +PJ_DECL(pj_status_t) pj_event_destroy(pj_event_t *event); + +/** + * @} + */ +#endif /* PJ_HAS_EVENT_OBJ */ + +/* **************************************************************************/ +/** + * @addtogroup PJ_TIME Time Data Type and Manipulation. + * @ingroup PJ_OS + * @{ + * This module provides API for manipulating time. + * + * \section pj_time_examples_sec Examples + * + * For examples, please see: + * - \ref page_pjlib_sleep_test + */ + +/** + * Get current time of day in local representation. + * + * @param tv Variable to store the result. + * + * @return zero if successfull. + */ +PJ_DECL(pj_status_t) pj_gettimeofday(pj_time_val *tv); + + +/** + * Parse time value into date/time representation. + * + * @param tv The time. + * @param pt Variable to store the date time result. + * + * @return zero if successfull. + */ +PJ_DECL(pj_status_t) pj_time_decode(const pj_time_val *tv, pj_parsed_time *pt); + +/** + * Encode date/time to time value. + * + * @param pt The date/time. + * @param tv Variable to store time value result. + * + * @return zero if successfull. + */ +PJ_DECL(pj_status_t) pj_time_encode(const pj_parsed_time *pt, pj_time_val *tv); + +/** + * Convert local time to GMT. + * + * @param tv Time to convert. + * + * @return zero if successfull. + */ +PJ_DECL(pj_status_t) pj_time_local_to_gmt(pj_time_val *tv); + +/** + * Convert GMT to local time. + * + * @param tv Time to convert. + * + * @return zero if successfull. + */ +PJ_DECL(pj_status_t) pj_time_gmt_to_local(pj_time_val *tv); + +/** + * @} + */ + +/* **************************************************************************/ +#if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0 + +/** + * @defgroup PJ_TERM Terminal + * @ingroup PJ_OS + * @{ + */ + +/** + * Set current terminal color. + * + * @param color The RGB color. + * + * @return zero on success. + */ +PJ_DECL(pj_status_t) pj_term_set_color(pj_color_t color); + +/** + * Get current terminal foreground color. + * + * @return RGB color. + */ +PJ_DECL(pj_color_t) pj_term_get_color(void); + +/** + * @} + */ + +#endif /* PJ_TERM_HAS_COLOR */ + +/* **************************************************************************/ +/** + * @defgroup PJ_TIMESTAMP High Resolution Timestamp + * @ingroup PJ_OS + * @{ + * + * PJLIB provides High Resolution Timestamp API to access highest + * resolution timestamp value provided by the platform. The API is usefull + * to measure precise elapsed time, and can be used in applications such + * as profiling. + * + * The timestamp value is represented in cycles, and can be related to + * normal time (in seconds or sub-seconds) using various functions provided. + * + * \section pj_timestamp_examples_sec Examples + * + * For examples, please see: + * - \ref page_pjlib_sleep_test + * - \ref page_pjlib_timestamp_test + */ + +/* + * High resolution timer. + */ +#if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0 + +/** + * Get monotonic time since some unspecified starting point. + * + * @param tv Variable to store the result. + * + * @return PJ_SUCCESS if successful. + */ +PJ_DECL(pj_status_t) pj_gettickcount(pj_time_val *tv); + +/** + * Acquire high resolution timer value. The time value are stored + * in cycles. + * + * @param ts High resolution timer value. + * @return PJ_SUCCESS or the appropriate error code. + * + * @see pj_get_timestamp_freq(). + */ +PJ_DECL(pj_status_t) pj_get_timestamp(pj_timestamp *ts); + +/** + * Get high resolution timer frequency, in cycles per second. + * + * @param freq Timer frequency, in cycles per second. + * @return PJ_SUCCESS or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq); + +/** + * Set timestamp from 32bit values. + * @param t The timestamp to be set. + * @param hi The high 32bit part. + * @param lo The low 32bit part. + */ +PJ_INLINE(void) pj_set_timestamp32(pj_timestamp *t, pj_uint32_t hi, + pj_uint32_t lo) +{ + t->u32.hi = hi; + t->u32.lo = lo; +} + + +/** + * Compare timestamp t1 and t2. + * @param t1 t1. + * @param t2 t2. + * @return -1 if (t1 < t2), 1 if (t1 > t2), or 0 if (t1 == t2) + */ +PJ_INLINE(int) pj_cmp_timestamp(const pj_timestamp *t1, const pj_timestamp *t2) +{ +#if PJ_HAS_INT64 + if (t1->u64 < t2->u64) + return -1; + else if (t1->u64 > t2->u64) + return 1; + else + return 0; +#else + if (t1->u32.hi < t2->u32.hi || + (t1->u32.hi == t2->u32.hi && t1->u32.lo < t2->u32.lo)) + return -1; + else if (t1->u32.hi > t2->u32.hi || + (t1->u32.hi == t2->u32.hi && t1->u32.lo > t2->u32.lo)) + return 1; + else + return 0; +#endif +} + + +/** + * Add timestamp t2 to t1. + * @param t1 t1. + * @param t2 t2. + */ +PJ_INLINE(void) pj_add_timestamp(pj_timestamp *t1, const pj_timestamp *t2) +{ +#if PJ_HAS_INT64 + t1->u64 += t2->u64; +#else + pj_uint32_t old = t1->u32.lo; + t1->u32.hi += t2->u32.hi; + t1->u32.lo += t2->u32.lo; + if (t1->u32.lo < old) + ++t1->u32.hi; +#endif +} + +/** + * Add timestamp t2 to t1. + * @param t1 t1. + * @param t2 t2. + */ +PJ_INLINE(void) pj_add_timestamp32(pj_timestamp *t1, pj_uint32_t t2) +{ +#if PJ_HAS_INT64 + t1->u64 += t2; +#else + pj_uint32_t old = t1->u32.lo; + t1->u32.lo += t2; + if (t1->u32.lo < old) + ++t1->u32.hi; +#endif +} + +/** + * Substract timestamp t2 from t1. + * @param t1 t1. + * @param t2 t2. + */ +PJ_INLINE(void) pj_sub_timestamp(pj_timestamp *t1, const pj_timestamp *t2) +{ +#if PJ_HAS_INT64 + t1->u64 -= t2->u64; +#else + t1->u32.hi -= t2->u32.hi; + if (t1->u32.lo >= t2->u32.lo) + t1->u32.lo -= t2->u32.lo; + else { + t1->u32.lo -= t2->u32.lo; + --t1->u32.hi; + } +#endif +} + +/** + * Substract timestamp t2 from t1. + * @param t1 t1. + * @param t2 t2. + */ +PJ_INLINE(void) pj_sub_timestamp32(pj_timestamp *t1, pj_uint32_t t2) +{ +#if PJ_HAS_INT64 + t1->u64 -= t2; +#else + if (t1->u32.lo >= t2) + t1->u32.lo -= t2; + else { + t1->u32.lo -= t2; + --t1->u32.hi; + } +#endif +} + +/** + * Get the timestamp difference between t2 and t1 (that is t2 minus t1), + * and return a 32bit signed integer difference. + */ +PJ_INLINE(pj_int32_t) pj_timestamp_diff32(const pj_timestamp *t1, + const pj_timestamp *t2) +{ + /* Be careful with the signess (I think!) */ +#if PJ_HAS_INT64 + pj_int64_t diff = t2->u64 - t1->u64; + return (pj_int32_t) diff; +#else + pj_int32 diff = t2->u32.lo - t1->u32.lo; + return diff; +#endif +} + + +/** + * Calculate the elapsed time, and store it in pj_time_val. + * This function calculates the elapsed time using highest precision + * calculation that is available for current platform, considering + * whether floating point or 64-bit precision arithmetic is available. + * For maximum portability, application should prefer to use this function + * rather than calculating the elapsed time by itself. + * + * @param start The starting timestamp. + * @param stop The end timestamp. + * + * @return Elapsed time as #pj_time_val. + * + * @see pj_elapsed_usec(), pj_elapsed_cycle(), pj_elapsed_nanosec() + */ +PJ_DECL(pj_time_val) pj_elapsed_time( const pj_timestamp *start, + const pj_timestamp *stop ); + +/** + * Calculate the elapsed time as 32-bit miliseconds. + * This function calculates the elapsed time using highest precision + * calculation that is available for current platform, considering + * whether floating point or 64-bit precision arithmetic is available. + * For maximum portability, application should prefer to use this function + * rather than calculating the elapsed time by itself. + * + * @param start The starting timestamp. + * @param stop The end timestamp. + * + * @return Elapsed time in milisecond. + * + * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec() + */ +PJ_DECL(pj_uint32_t) pj_elapsed_msec( const pj_timestamp *start, + const pj_timestamp *stop ); + +/** + * Variant of #pj_elapsed_msec() which returns 64bit value. + */ +PJ_DECL(pj_uint64_t) pj_elapsed_msec64(const pj_timestamp *start, + const pj_timestamp *stop ); + +/** + * Calculate the elapsed time in 32-bit microseconds. + * This function calculates the elapsed time using highest precision + * calculation that is available for current platform, considering + * whether floating point or 64-bit precision arithmetic is available. + * For maximum portability, application should prefer to use this function + * rather than calculating the elapsed time by itself. + * + * @param start The starting timestamp. + * @param stop The end timestamp. + * + * @return Elapsed time in microsecond. + * + * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec() + */ +PJ_DECL(pj_uint32_t) pj_elapsed_usec( const pj_timestamp *start, + const pj_timestamp *stop ); + +/** + * Calculate the elapsed time in 32-bit nanoseconds. + * This function calculates the elapsed time using highest precision + * calculation that is available for current platform, considering + * whether floating point or 64-bit precision arithmetic is available. + * For maximum portability, application should prefer to use this function + * rather than calculating the elapsed time by itself. + * + * @param start The starting timestamp. + * @param stop The end timestamp. + * + * @return Elapsed time in nanoseconds. + * + * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_usec() + */ +PJ_DECL(pj_uint32_t) pj_elapsed_nanosec( const pj_timestamp *start, + const pj_timestamp *stop ); + +/** + * Calculate the elapsed time in 32-bit cycles. + * This function calculates the elapsed time using highest precision + * calculation that is available for current platform, considering + * whether floating point or 64-bit precision arithmetic is available. + * For maximum portability, application should prefer to use this function + * rather than calculating the elapsed time by itself. + * + * @param start The starting timestamp. + * @param stop The end timestamp. + * + * @return Elapsed time in cycles. + * + * @see pj_elapsed_usec(), pj_elapsed_time(), pj_elapsed_nanosec() + */ +PJ_DECL(pj_uint32_t) pj_elapsed_cycle( const pj_timestamp *start, + const pj_timestamp *stop ); + + +#endif /* PJ_HAS_HIGH_RES_TIMER */ + +/** @} */ + + +/* **************************************************************************/ +/** + * @defgroup PJ_APP_OS Application execution + * @ingroup PJ_OS + * @{ + */ + +/* Type for main function. */ +typedef int (*pj_main_func_ptr)(int argc, char *argv[]); + +/** + * Run the application. This function has to be called in the main thread + * and after doing the necessary initialization according to the flags + * provided, it will call main_func() function. + * + * @param main_func Application's main function. + * @param argc Number of arguments from the main() function, which + * will be passed to main_func() function. + * @param argv The arguments from the main() function, which will + * be passed to main_func() function. + * @param flags Flags for application execution, currently must be 0. + * + * @return main_func()'s return value. + */ +int pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[], + unsigned flags); + +/** @} */ + + +/* **************************************************************************/ +/** + * Internal PJLIB function to initialize the threading subsystem. + * @return PJ_SUCCESS or the appropriate error code. + */ +pj_status_t pj_thread_init(void); + + +PJ_END_DECL + +#endif /* __PJ_OS_H__ */ + diff --git a/pjlib/include/pj/pool.h b/pjlib/include/pj/pool.h new file mode 100644 index 0000000..5738d4f --- /dev/null +++ b/pjlib/include/pj/pool.h @@ -0,0 +1,903 @@ +/* $Id: pool.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 + * + * 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 + */ + +#include + +/* See if we use pool's alternate API. + * The alternate API is used e.g. to implement pool debugging. + */ +#if PJ_HAS_POOL_ALT_API +# include +#endif + + +#ifndef __PJ_POOL_H__ +#define __PJ_POOL_H__ + +/** + * @file pool.h + * @brief Memory Pool. + */ + +PJ_BEGIN_DECL + +/** + * @defgroup PJ_POOL_GROUP Fast Memory Pool + * @brief + * Memory pools allow dynamic memory allocation comparable to malloc or the + * new in operator C++. Those implementations are not desirable for very + * high performance applications or real-time systems, because of the + * performance bottlenecks and it suffers from fragmentation issue. + * + * \section PJ_POOL_INTRO_SEC PJLIB's Memory Pool + * \subsection PJ_POOL_ADVANTAGE_SUBSEC Advantages + * + * PJLIB's pool has many advantages over traditional malloc/new operator and + * over other memory pool implementations, because: + * - unlike other memory pool implementation, it allows allocation of + * memory chunks of different sizes, + * - it's very very fast. + * \n + * Memory chunk allocation is not only an O(1) + * operation, but it's also very simple (just + * few pointer arithmetic operations) and it doesn't require locking + * any mutex, + * - it's memory efficient. + * \n + * Pool doesn't keep track individual memory chunks allocated by + * applications, so there is no additional overhead needed for each + * memory allocation (other than possible additional of few bytes, up to + * PJ_POOL_ALIGNMENT-1, for aligning the memory). + * But see the @ref PJ_POOL_CAVEATS_SUBSEC below. + * - it prevents memory leaks. + * \n + * Memory pool inherently has garbage collection functionality. In fact, + * there is no need to free the chunks allocated from the memory pool. + * All chunks previously allocated from the pool will be freed once the + * pool itself is destroyed. This would prevent memory leaks that haunt + * programmers for decades, and it provides additional performance + * advantage over traditional malloc/new operator. + * + * Even more, PJLIB's memory pool provides some additional usability and + * flexibility for applications: + * - memory leaks are easily traceable, since memory pool is assigned name, + * and application can inspect what pools currently active in the system. + * - by design, memory allocation from a pool is not thread safe. We assumed + * that a pool will be owned by a higher level object, and thread safety + * should be handled by that object. This enables very fast pool operations + * and prevents unnecessary locking operations, + * - by default, the memory pool API behaves more like C++ new operator, + * in that it will throw PJ_NO_MEMORY_EXCEPTION exception (see + * @ref PJ_EXCEPT) when memory chunk allocation fails. This enables failure + * handling to be done on more high level function (instead of checking + * the result of pj_pool_alloc() everytime). If application doesn't like + * this, the default behavior can be changed on global basis by supplying + * different policy to the pool factory. + * - any memory allocation backend allocator/deallocator may be used. By + * default, the policy uses malloc() and free() to manage the pool's block, + * but application may use different strategy, for example to allocate + * memory blocks from a globally static memory location. + * + * + * \subsection PJ_POOL_PERFORMANCE_SUBSEC Performance + * + * The result of PJLIB's memory design and careful implementation is a + * memory allocation strategy that can speed-up the memory allocations + * and deallocations by up to 30 times compared to standard + * malloc()/free() (more than 150 million allocations per second on a + * P4/3.0GHz Linux machine). + * + * (Note: your mileage may vary, of course. You can see how much PJLIB's + * pool improves the performance over malloc()/free() in your target + * system by running pjlib-test application). + * + * + * \subsection PJ_POOL_CAVEATS_SUBSEC Caveats + * + * There are some caveats though! + * + * When creating pool, PJLIB requires applications to specify the initial + * pool size, and as soon as the pool is created, PJLIB allocates memory + * from the system by that size. Application designers MUST choose the + * initial pool size carefully, since choosing too big value will result in + * wasting system's memory. + * + * But the pool can grow. Application designer can specify how the + * pool will grow in size, by specifying the size increment when creating + * the pool. + * + * The pool, however, cannot shrink! Since there is no + * function to deallocate memory chunks, there is no way for the pool to + * release back unused memory to the system. + * Application designers must be aware that constant memory allocations + * from pool that has infinite life-time may cause the memory usage of + * the application to grow over time. + * + * + * \section PJ_POOL_USING_SEC Using Memory Pool + * + * This section describes how to use PJLIB's memory pool framework. + * As we hope the readers will witness, PJLIB's memory pool API is quite + * straightforward. + * + * \subsection PJ_POOL_USING_F Create Pool Factory + * First, application needs to initialize a pool factory (this normally + * only needs to be done once in one application). PJLIB provides + * a pool factory implementation called caching pool (see @ref + * PJ_CACHING_POOL), and it is initialized by calling #pj_caching_pool_init(). + * + * \subsection PJ_POOL_USING_P Create The Pool + * Then application creates the pool object itself with #pj_pool_create(), + * specifying among other thing the pool factory where the pool should + * be created from, the pool name, initial size, and increment/expansion + * size. + * + * \subsection PJ_POOL_USING_M Allocate Memory as Required + * Then whenever application needs to allocate dynamic memory, it would + * call #pj_pool_alloc(), #pj_pool_calloc(), or #pj_pool_zalloc() to + * allocate memory chunks from the pool. + * + * \subsection PJ_POOL_USING_DP Destroy the Pool + * When application has finished with the pool, it should call + * #pj_pool_release() to release the pool object back to the factory. + * Depending on the types of the factory, this may release the memory back + * to the operating system. + * + * \subsection PJ_POOL_USING_Dc Destroy the Pool Factory + * And finally, before application quites, it should deinitialize the + * pool factory, to make sure that all memory blocks allocated by the + * factory are released back to the operating system. After this, of + * course no more memory pool allocation can be requested. + * + * \subsection PJ_POOL_USING_EX Example + * Below is a sample complete program that utilizes PJLIB's memory pool. + * + * \code + + #include + + #define THIS_FILE "pool_sample.c" + + static void my_perror(const char *title, pj_status_t status) + { + char errmsg[PJ_ERR_MSG_SIZE]; + + pj_strerror(status, errmsg, sizeof(errmsg)); + PJ_LOG(1,(THIS_FILE, "%s: %s [status=%d]", title, errmsg, status)); + } + + static void pool_demo_1(pj_pool_factory *pfactory) + { + unsigned i; + pj_pool_t *pool; + + // Must create pool before we can allocate anything + pool = pj_pool_create(pfactory, // the factory + "pool1", // pool's name + 4000, // initial size + 4000, // increment size + NULL); // use default callback. + if (pool == NULL) { + my_perror("Error creating pool", PJ_ENOMEM); + return; + } + + // Demo: allocate some memory chunks + for (i=0; i<1000; ++i) { + void *p; + + p = pj_pool_alloc(pool, (pj_rand()+1) % 512); + + // Do something with p + ... + + // Look! No need to free p!! + } + + // Done with silly demo, must free pool to release all memory. + pj_pool_release(pool); + } + + int main() + { + pj_caching_pool cp; + pj_status_t status; + + // Must init PJLIB before anything else + status = pj_init(); + if (status != PJ_SUCCESS) { + my_perror("Error initializing PJLIB", status); + return 1; + } + + // Create the pool factory, in this case, a caching pool, + // using default pool policy. + pj_caching_pool_init(&cp, NULL, 1024*1024 ); + + // Do a demo + pool_demo_1(&cp.factory); + + // Done with demos, destroy caching pool before exiting app. + pj_caching_pool_destroy(&cp); + + return 0; + } + + \endcode + * + * More information about pool factory, the pool object, and caching pool + * can be found on the Module Links below. + */ + + +/** + * @defgroup PJ_POOL Memory Pool Object + * @ingroup PJ_POOL_GROUP + * @brief + * The memory pool is an opaque object created by pool factory. + * Application uses this object to request a memory chunk, by calling + * #pj_pool_alloc(), #pj_pool_calloc(), or #pj_pool_zalloc(). + * When the application has finished using + * the pool, it must call #pj_pool_release() to free all the chunks previously + * allocated and release the pool back to the factory. + * + * A memory pool is initialized with an initial amount of memory, which is + * called a block. Pool can be configured to dynamically allocate more memory + * blocks when it runs out of memory. + * + * The pool doesn't keep track of individual memory allocations + * by user, and the user doesn't have to free these indidual allocations. This + * makes memory allocation simple and very fast. All the memory allocated from + * the pool will be destroyed when the pool itself is destroyed. + * + * \section PJ_POOL_THREADING_SEC More on Threading Policies + * - By design, memory allocation from a pool is not thread safe. We assumed + * that a pool will be owned by an object, and thread safety should be + * handled by that object. Thus these functions are not thread safe: + * - #pj_pool_alloc, + * - #pj_pool_calloc, + * - and other pool statistic functions. + * - Threading in the pool factory is decided by the policy set for the + * factory when it was created. + * + * \section PJ_POOL_EXAMPLES_SEC Examples + * + * For some sample codes on how to use the pool, please see: + * - @ref page_pjlib_pool_test + * + * @{ + */ + +/** + * The type for function to receive callback from the pool when it is unable + * to allocate memory. The elegant way to handle this condition is to throw + * exception, and this is what is expected by most of this library + * components. + */ +typedef void pj_pool_callback(pj_pool_t *pool, pj_size_t size); + +/** + * This class, which is used internally by the pool, describes a single + * block of memory from which user memory allocations will be allocated from. + */ +typedef struct pj_pool_block +{ + PJ_DECL_LIST_MEMBER(struct pj_pool_block); /**< List's prev and next. */ + unsigned char *buf; /**< Start of buffer. */ + unsigned char *cur; /**< Current alloc ptr. */ + unsigned char *end; /**< End of buffer. */ +} pj_pool_block; + + +/** + * This structure describes the memory pool. Only implementors of pool factory + * need to care about the contents of this structure. + */ +struct pj_pool_t +{ + PJ_DECL_LIST_MEMBER(struct pj_pool_t); /**< Standard list elements. */ + + /** Pool name */ + char obj_name[PJ_MAX_OBJ_NAME]; + + /** Pool factory. */ + pj_pool_factory *factory; + + /** Data put by factory */ + void *factory_data; + + /** Current capacity allocated by the pool. */ + pj_size_t capacity; + + /** Size of memory block to be allocated when the pool runs out of memory */ + pj_size_t increment_size; + + /** List of memory blocks allcoated by the pool. */ + pj_pool_block block_list; + + /** The callback to be called when the pool is unable to allocate memory. */ + pj_pool_callback *callback; + +}; + + +/** + * Guidance on how much memory required for initial pool administrative data. + */ +#define PJ_POOL_SIZE (sizeof(struct pj_pool_t)) + +/** + * Pool memory alignment (must be power of 2). + */ +#ifndef PJ_POOL_ALIGNMENT +# define PJ_POOL_ALIGNMENT 4 +#endif + +/** + * Create a new pool from the pool factory. This wrapper will call create_pool + * member of the pool factory. + * + * @param factory The pool factory. + * @param name The name to be assigned to the pool. The name should + * not be longer than PJ_MAX_OBJ_NAME (32 chars), or + * otherwise it will be truncated. + * @param initial_size The size of initial memory blocks taken by the pool. + * Note that the pool will take 68+20 bytes for + * administrative area from this block. + * @param increment_size the size of each additional blocks to be allocated + * when the pool is running out of memory. If user + * requests memory which is larger than this size, then + * an error occurs. + * Note that each time a pool allocates additional block, + * it needs PJ_POOL_SIZE more to store some + * administrative info. + * @param callback Callback to be called when error occurs in the pool. + * If this value is NULL, then the callback from pool + * factory policy will be used. + * Note that when an error occurs during pool creation, + * the callback itself is not called. Instead, NULL + * will be returned. + * + * @return The memory pool, or NULL. + */ +PJ_IDECL(pj_pool_t*) pj_pool_create(pj_pool_factory *factory, + const char *name, + pj_size_t initial_size, + pj_size_t increment_size, + pj_pool_callback *callback); + +/** + * Release the pool back to pool factory. + * + * @param pool Memory pool. + */ +PJ_IDECL(void) pj_pool_release( pj_pool_t *pool ); + +/** + * Get pool object name. + * + * @param pool the pool. + * + * @return pool name as NULL terminated string. + */ +PJ_IDECL(const char *) pj_pool_getobjname( const pj_pool_t *pool ); + +/** + * Reset the pool to its state when it was initialized. + * This means that if additional blocks have been allocated during runtime, + * then they will be freed. Only the original block allocated during + * initialization is retained. This function will also reset the internal + * counters, such as pool capacity and used size. + * + * @param pool the pool. + */ +PJ_DECL(void) pj_pool_reset( pj_pool_t *pool ); + + +/** + * Get the pool capacity, that is, the system storage that have been allocated + * by the pool, and have been used/will be used to allocate user requests. + * There's no guarantee that the returned value represent a single + * contiguous block, because the capacity may be spread in several blocks. + * + * @param pool the pool. + * + * @return the capacity. + */ +PJ_IDECL(pj_size_t) pj_pool_get_capacity( pj_pool_t *pool ); + +/** + * Get the total size of user allocation request. + * + * @param pool the pool. + * + * @return the total size. + */ +PJ_IDECL(pj_size_t) pj_pool_get_used_size( pj_pool_t *pool ); + +/** + * Allocate storage with the specified size from the pool. + * If there's no storage available in the pool, then the pool can allocate more + * blocks if the increment size is larger than the requested size. + * + * @param pool the pool. + * @param size the requested size. + * + * @return pointer to the allocated memory. + * + * @see PJ_POOL_ALLOC_T + */ +PJ_IDECL(void*) pj_pool_alloc( pj_pool_t *pool, pj_size_t size); + +/** + * Allocate storage from the pool, and initialize it to zero. + * This function behaves like pj_pool_alloc(), except that the storage will + * be initialized to zero. + * + * @param pool the pool. + * @param count the number of elements in the array. + * @param elem the size of individual element. + * + * @return pointer to the allocated memory. + */ +PJ_IDECL(void*) pj_pool_calloc( pj_pool_t *pool, pj_size_t count, + pj_size_t elem); + + +/** + * Allocate storage from the pool and initialize it to zero. + * + * @param pool The pool. + * @param size The size to be allocated. + * + * @return Pointer to the allocated memory. + * + * @see PJ_POOL_ZALLOC_T + */ +PJ_INLINE(void*) pj_pool_zalloc(pj_pool_t *pool, pj_size_t size) +{ + return pj_pool_calloc(pool, 1, size); +} + + +/** + * This macro allocates memory from the pool and returns the instance of + * the specified type. It provides a stricker type safety than pj_pool_alloc() + * since the return value of this macro will be type-casted to the specified + * type. + * + * @param pool The pool + * @param type The type of object to be allocated + * + * @return Memory buffer of the specified type. + */ +#define PJ_POOL_ALLOC_T(pool,type) \ + ((type*)pj_pool_alloc(pool, sizeof(type))) + +/** + * This macro allocates memory from the pool, zeroes the buffer, and + * returns the instance of the specified type. It provides a stricker type + * safety than pj_pool_zalloc() since the return value of this macro will be + * type-casted to the specified type. + * + * @param pool The pool + * @param type The type of object to be allocated + * + * @return Memory buffer of the specified type. + */ +#define PJ_POOL_ZALLOC_T(pool,type) \ + ((type*)pj_pool_zalloc(pool, sizeof(type))) + +/* + * Internal functions + */ +PJ_IDECL(void*) pj_pool_alloc_from_block(pj_pool_block *block, pj_size_t size); +PJ_DECL(void*) pj_pool_allocate_find(pj_pool_t *pool, unsigned size); + + + +/** + * @} // PJ_POOL + */ + +/* **************************************************************************/ +/** + * @defgroup PJ_POOL_FACTORY Pool Factory and Policy + * @ingroup PJ_POOL_GROUP + * @brief + * A pool object must be created through a factory. A factory not only provides + * generic interface functions to create and release pool, but also provides + * strategy to manage the life time of pools. One sample implementation, + * \a pj_caching_pool, can be set to keep the pools released by application for + * future use as long as the total memory is below the limit. + * + * The pool factory interface declared in PJLIB is designed to be extensible. + * Application can define its own strategy by creating it's own pool factory + * implementation, and this strategy can be used even by existing library + * without recompilation. + * + * \section PJ_POOL_FACTORY_ITF Pool Factory Interface + * The pool factory defines the following interface: + * - \a policy: the memory pool factory policy. + * - \a create_pool(): create a new memory pool. + * - \a release_pool(): release memory pool back to factory. + * + * \section PJ_POOL_FACTORY_POL Pool Factory Policy. + * + * A pool factory only defines functions to create and release pool and how + * to manage pools, but the rest of the functionalities are controlled by + * policy. A pool policy defines: + * - how memory block is allocated and deallocated (the default implementation + * allocates and deallocate memory by calling malloc() and free()). + * - callback to be called when memory allocation inside a pool fails (the + * default implementation will throw PJ_NO_MEMORY_EXCEPTION exception). + * - concurrency when creating and releasing pool from/to the factory. + * + * A pool factory can be given different policy during creation to make + * it behave differently. For example, caching pool factory can be configured + * to allocate and deallocate from a static/contiguous/preallocated memory + * instead of using malloc()/free(). + * + * What strategy/factory and what policy to use is not defined by PJLIB, but + * instead is left to application to make use whichever is most efficient for + * itself. + * + * The pool factory policy controls the behaviour of memory factories, and + * defines the following interface: + * - \a block_alloc(): allocate memory block from backend memory mgmt/system. + * - \a block_free(): free memory block back to backend memory mgmt/system. + * @{ + */ + +/* We unfortunately don't have support for factory policy options as now, + so we keep this commented at the moment. +enum PJ_POOL_FACTORY_OPTION +{ + PJ_POOL_FACTORY_SERIALIZE = 1 +}; +*/ + +/** + * This structure declares pool factory interface. + */ +typedef struct pj_pool_factory_policy +{ + /** + * Allocate memory block (for use by pool). This function is called + * by memory pool to allocate memory block. + * + * @param factory Pool factory. + * @param size The size of memory block to allocate. + * + * @return Memory block. + */ + void* (*block_alloc)(pj_pool_factory *factory, pj_size_t size); + + /** + * Free memory block. + * + * @param factory Pool factory. + * @param mem Memory block previously allocated by block_alloc(). + * @param size The size of memory block. + */ + void (*block_free)(pj_pool_factory *factory, void *mem, pj_size_t size); + + /** + * Default callback to be called when memory allocation fails. + */ + pj_pool_callback *callback; + + /** + * Option flags. + */ + unsigned flags; + +} pj_pool_factory_policy; + +/** + * \def PJ_NO_MEMORY_EXCEPTION + * This constant denotes the exception number that will be thrown by default + * memory factory policy when memory allocation fails. + * + * @see pj_NO_MEMORY_EXCEPTION() + */ +PJ_DECL_DATA(int) PJ_NO_MEMORY_EXCEPTION; + +/** + * Get #PJ_NO_MEMORY_EXCEPTION constant. + */ +PJ_DECL(int) pj_NO_MEMORY_EXCEPTION(void); + +/** + * This global variable points to default memory pool factory policy. + * The behaviour of the default policy is: + * - block allocation and deallocation use malloc() and free(). + * - callback will raise PJ_NO_MEMORY_EXCEPTION exception. + * - access to pool factory is not serialized (i.e. not thread safe). + * + * @see pj_pool_factory_get_default_policy + */ +PJ_DECL_DATA(pj_pool_factory_policy) pj_pool_factory_default_policy; + + +/** + * Get the default pool factory policy. + * + * @return the pool policy. + */ +PJ_DECL(const pj_pool_factory_policy*) pj_pool_factory_get_default_policy(void); + + +/** + * This structure contains the declaration for pool factory interface. + */ +struct pj_pool_factory +{ + /** + * Memory pool policy. + */ + pj_pool_factory_policy policy; + + /** + * Create a new pool from the pool factory. + * + * @param factory The pool factory. + * @param name the name to be assigned to the pool. The name should + * not be longer than PJ_MAX_OBJ_NAME (32 chars), or + * otherwise it will be truncated. + * @param initial_size the size of initial memory blocks taken by the pool. + * Note that the pool will take 68+20 bytes for + * administrative area from this block. + * @param increment_size the size of each additional blocks to be allocated + * when the pool is running out of memory. If user + * requests memory which is larger than this size, then + * an error occurs. + * Note that each time a pool allocates additional block, + * it needs 20 bytes (equal to sizeof(pj_pool_block)) to + * store some administrative info. + * @param callback Cllback to be called when error occurs in the pool. + * Note that when an error occurs during pool creation, + * the callback itself is not called. Instead, NULL + * will be returned. + * + * @return the memory pool, or NULL. + */ + pj_pool_t* (*create_pool)( pj_pool_factory *factory, + const char *name, + pj_size_t initial_size, + pj_size_t increment_size, + pj_pool_callback *callback); + + /** + * Release the pool to the pool factory. + * + * @param factory The pool factory. + * @param pool The pool to be released. + */ + void (*release_pool)( pj_pool_factory *factory, pj_pool_t *pool ); + + /** + * Dump pool status to log. + * + * @param factory The pool factory. + */ + void (*dump_status)( pj_pool_factory *factory, pj_bool_t detail ); + + /** + * This is optional callback to be called by allocation policy when + * it allocates a new memory block. The factory may use this callback + * for example to keep track of the total number of memory blocks + * currently allocated by applications. + * + * @param factory The pool factory. + * @param size Size requested by application. + * + * @return MUST return PJ_TRUE, otherwise the block + * allocation is cancelled. + */ + pj_bool_t (*on_block_alloc)(pj_pool_factory *factory, pj_size_t size); + + /** + * This is optional callback to be called by allocation policy when + * it frees memory block. The factory may use this callback + * for example to keep track of the total number of memory blocks + * currently allocated by applications. + * + * @param factory The pool factory. + * @param size Size freed. + */ + void (*on_block_free)(pj_pool_factory *factory, pj_size_t size); + +}; + +/** + * This function is intended to be used by pool factory implementors. + * @param factory Pool factory. + * @param name Pool name. + * @param initial_size Initial size. + * @param increment_size Increment size. + * @param callback Callback. + * @return The pool object, or NULL. + */ +PJ_DECL(pj_pool_t*) pj_pool_create_int( pj_pool_factory *factory, + const char *name, + pj_size_t initial_size, + pj_size_t increment_size, + pj_pool_callback *callback); + +/** + * This function is intended to be used by pool factory implementors. + * @param pool The pool. + * @param name Pool name. + * @param increment_size Increment size. + * @param callback Callback function. + */ +PJ_DECL(void) pj_pool_init_int( pj_pool_t *pool, + const char *name, + pj_size_t increment_size, + pj_pool_callback *callback); + +/** + * This function is intended to be used by pool factory implementors. + * @param pool The memory pool. + */ +PJ_DECL(void) pj_pool_destroy_int( pj_pool_t *pool ); + + +/** + * Dump pool factory state. + * @param pf The pool factory. + * @param detail Detail state required. + */ +PJ_INLINE(void) pj_pool_factory_dump( pj_pool_factory *pf, + pj_bool_t detail ) +{ + (*pf->dump_status)(pf, detail); +} + +/** + * @} // PJ_POOL_FACTORY + */ + +/* **************************************************************************/ + +/** + * @defgroup PJ_CACHING_POOL Caching Pool Factory + * @ingroup PJ_POOL_GROUP + * @brief + * Caching pool is one sample implementation of pool factory where the + * factory can reuse memory to create a pool. Application defines what the + * maximum memory the factory can hold, and when a pool is released the + * factory decides whether to destroy the pool or to keep it for future use. + * If the total amount of memory in the internal cache is still within the + * limit, the factory will keep the pool in the internal cache, otherwise the + * pool will be destroyed, thus releasing the memory back to the system. + * + * @{ + */ + +/** + * Number of unique sizes, to be used as index to the free list. + * Each pool in the free list is organized by it's size. + */ +#define PJ_CACHING_POOL_ARRAY_SIZE 16 + +/** + * Declaration for caching pool. Application doesn't normally need to + * care about the contents of this struct, it is only provided here because + * application need to define an instance of this struct (we can not allocate + * the struct from a pool since there is no pool factory yet!). + */ +struct pj_caching_pool +{ + /** Pool factory interface, must be declared first. */ + pj_pool_factory factory; + + /** Current factory's capacity, i.e. number of bytes that are allocated + * and available for application in this factory. The factory's + * capacity represents the size of all pools kept by this factory + * in it's free list, which will be returned to application when it + * requests to create a new pool. + */ + pj_size_t capacity; + + /** Maximum size that can be held by this factory. Once the capacity + * has exceeded @a max_capacity, further #pj_pool_release() will + * flush the pool. If the capacity is still below the @a max_capacity, + * #pj_pool_release() will save the pool to the factory's free list. + */ + pj_size_t max_capacity; + + /** + * Number of pools currently held by applications. This number gets + * incremented everytime #pj_pool_create() is called, and gets + * decremented when #pj_pool_release() is called. + */ + pj_size_t used_count; + + /** + * Total size of memory currently used by application. + */ + pj_size_t used_size; + + /** + * The maximum size of memory used by application throughout the life + * of the caching pool. + */ + pj_size_t peak_used_size; + + /** + * Lists of pools in the cache, indexed by pool size. + */ + pj_list free_list[PJ_CACHING_POOL_ARRAY_SIZE]; + + /** + * List of pools currently allocated by applications. + */ + pj_list used_list; + + /** + * Internal pool. + */ + char pool_buf[256 * (sizeof(long) / 4)]; + + /** + * Mutex. + */ + pj_lock_t *lock; +}; + + + +/** + * Initialize caching pool. + * + * @param ch_pool The caching pool factory to be initialized. + * @param policy Pool factory policy. + * @param max_capacity The total capacity to be retained in the cache. When + * the pool is returned to the cache, it will be kept in + * recycling list if the total capacity of pools in this + * list plus the capacity of the pool is still below this + * value. + */ +PJ_DECL(void) pj_caching_pool_init( pj_caching_pool *ch_pool, + const pj_pool_factory_policy *policy, + pj_size_t max_capacity); + + +/** + * Destroy caching pool, and release all the pools in the recycling list. + * + * @param ch_pool The caching pool. + */ +PJ_DECL(void) pj_caching_pool_destroy( pj_caching_pool *ch_pool ); + +/** + * @} // PJ_CACHING_POOL + */ + +# if PJ_FUNCTIONS_ARE_INLINED +# include "pool_i.h" +# endif + +PJ_END_DECL + +#endif /* __PJ_POOL_H__ */ + diff --git a/pjlib/include/pj/pool_alt.h b/pjlib/include/pj/pool_alt.h new file mode 100644 index 0000000..713e825 --- /dev/null +++ b/pjlib/include/pj/pool_alt.h @@ -0,0 +1,198 @@ +/* $Id: pool_alt.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 + * + * 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_POOL_ALT_H__ +#define __PJ_POOL_ALT_H__ + +#define __PJ_POOL_H__ + + +/** + * The type for function to receive callback from the pool when it is unable + * to allocate memory. The elegant way to handle this condition is to throw + * exception, and this is what is expected by most of this library + * components. + */ +typedef void pj_pool_callback(pj_pool_t *pool, pj_size_t size); + +struct pj_pool_mem +{ + struct pj_pool_mem *next; + + /* data follows immediately */ +}; + + +struct pj_pool_t +{ + struct pj_pool_mem *first_mem; + pj_pool_factory *factory; + char obj_name[32]; + pj_size_t used_size; + pj_pool_callback *cb; +}; + + +#define PJ_POOL_SIZE (sizeof(struct pj_pool_t)) + +/** + * This constant denotes the exception number that will be thrown by default + * memory factory policy when memory allocation fails. + */ +extern int PJ_NO_MEMORY_EXCEPTION; + + + +/* + * Declare all pool API as macro that calls the implementation + * function. + */ +#define pj_pool_create(fc,nm,init,inc,cb) \ + pj_pool_create_imp(__FILE__, __LINE__, fc, nm, init, inc, cb) + +#define pj_pool_release(pool) pj_pool_release_imp(pool) +#define pj_pool_getobjname(pool) pj_pool_getobjname_imp(pool) +#define pj_pool_reset(pool) pj_pool_reset_imp(pool) +#define pj_pool_get_capacity(pool) pj_pool_get_capacity_imp(pool) +#define pj_pool_get_used_size(pool) pj_pool_get_used_size_imp(pool) +#define pj_pool_alloc(pool,sz) \ + pj_pool_alloc_imp(__FILE__, __LINE__, pool, sz) + +#define pj_pool_calloc(pool,cnt,elem) \ + pj_pool_calloc_imp(__FILE__, __LINE__, pool, cnt, elem) + +#define pj_pool_zalloc(pool,sz) \ + pj_pool_zalloc_imp(__FILE__, __LINE__, pool, sz) + + + +/* + * Declare prototypes for pool implementation API. + */ + +/* Create pool */ +PJ_DECL(pj_pool_t*) pj_pool_create_imp(const char *file, int line, + void *factory, + const char *name, + pj_size_t initial_size, + pj_size_t increment_size, + pj_pool_callback *callback); + +/* Release pool */ +PJ_DECL(void) pj_pool_release_imp(pj_pool_t *pool); + +/* Get pool name */ +PJ_DECL(const char*) pj_pool_getobjname_imp(pj_pool_t *pool); + +/* Reset pool */ +PJ_DECL(void) pj_pool_reset_imp(pj_pool_t *pool); + +/* Get capacity */ +PJ_DECL(pj_size_t) pj_pool_get_capacity_imp(pj_pool_t *pool); + +/* Get total used size */ +PJ_DECL(pj_size_t) pj_pool_get_used_size_imp(pj_pool_t *pool); + +/* Allocate memory from the pool */ +PJ_DECL(void*) pj_pool_alloc_imp(const char *file, int line, + pj_pool_t *pool, pj_size_t sz); + +/* Allocate memory from the pool and zero the memory */ +PJ_DECL(void*) pj_pool_calloc_imp(const char *file, int line, + pj_pool_t *pool, unsigned cnt, + unsigned elemsz); + +/* Allocate memory from the pool and zero the memory */ +PJ_DECL(void*) pj_pool_zalloc_imp(const char *file, int line, + pj_pool_t *pool, pj_size_t sz); + + +#define PJ_POOL_ZALLOC_T(pool,type) \ + ((type*)pj_pool_zalloc(pool, sizeof(type))) +#define PJ_POOL_ALLOC_T(pool,type) \ + ((type*)pj_pool_alloc(pool, sizeof(type))) +#ifndef PJ_POOL_ALIGNMENT +# define PJ_POOL_ALIGNMENT 4 +#endif + +/** + * This structure declares pool factory interface. + */ +typedef struct pj_pool_factory_policy +{ + /** + * Allocate memory block (for use by pool). This function is called + * by memory pool to allocate memory block. + * + * @param factory Pool factory. + * @param size The size of memory block to allocate. + * + * @return Memory block. + */ + void* (*block_alloc)(pj_pool_factory *factory, pj_size_t size); + + /** + * Free memory block. + * + * @param factory Pool factory. + * @param mem Memory block previously allocated by block_alloc(). + * @param size The size of memory block. + */ + void (*block_free)(pj_pool_factory *factory, void *mem, pj_size_t size); + + /** + * Default callback to be called when memory allocation fails. + */ + pj_pool_callback *callback; + + /** + * Option flags. + */ + unsigned flags; + +} pj_pool_factory_policy; + +struct pj_pool_factory +{ + pj_pool_factory_policy policy; + int dummy; +}; + +struct pj_caching_pool +{ + pj_pool_factory factory; + + /* just to make it compilable */ + unsigned used_count; + unsigned used_size; + unsigned peak_used_size; +}; + +/* just to make it compilable */ +typedef struct pj_pool_block +{ + int dummy; +} pj_pool_block; + +#define pj_caching_pool_init( cp, pol, mac) +#define pj_caching_pool_destroy(cp) +#define pj_pool_factory_dump(pf, detail) + +#endif /* __PJ_POOL_ALT_H__ */ + diff --git a/pjlib/include/pj/pool_buf.h b/pjlib/include/pj/pool_buf.h new file mode 100644 index 0000000..28734a7 --- /dev/null +++ b/pjlib/include/pj/pool_buf.h @@ -0,0 +1,105 @@ +/* $Id: pool_buf.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 + * + * 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 __POOL_STACK_H__ +#define __POOL_STACK_H__ + +#include + +/** + * @defgroup PJ_POOL_BUFFER Stack/Buffer Based Memory Pool Allocator + * @ingroup PJ_POOL_GROUP + * @brief Stack/buffer based pool. + * + * This section describes an implementation of memory pool which uses + * memory allocated from the stack. Application creates this pool + * by specifying a buffer (which can be allocated from static memory or + * stack variable), and then use normal pool API to access/use the pool. + * + * If the buffer specified during pool creation is a buffer located in the + * stack, the pool will be invalidated (or implicitly destroyed) when the + * execution leaves the enclosing block containing the buffer. Note + * that application must make sure that any objects allocated from this + * pool (such as mutexes) have been destroyed before the pool gets + * invalidated. + * + * Sample usage: + * + * \code + #include + + static void test() + { + char buffer[500]; + pj_pool_t *pool; + void *p; + + pool = pj_pool_create_on_buf("thepool", buffer, sizeof(buffer)); + + // Use the pool as usual + p = pj_pool_alloc(pool, ...); + ... + + // No need to release the pool + } + + int main() + { + pj_init(); + test(); + return 0; + } + + \endcode + * + * @{ + */ + +PJ_BEGIN_DECL + +/** + * Create the pool using the specified buffer as the pool's memory. + * Subsequent allocations made from the pool will use the memory from + * this buffer. + * + * If the buffer specified in the parameter is a buffer located in the + * stack, the pool will be invalid (or implicitly destroyed) when the + * execution leaves the enclosing block containing the buffer. Note + * that application must make sure that any objects allocated from this + * pool (such as mutexes) have been destroyed before the pool gets + * invalidated. + * + * @param name Optional pool name. + * @param buf Buffer to be used by the pool. + * @param size The size of the buffer. + * + * @return The memory pool instance. + */ +PJ_DECL(pj_pool_t*) pj_pool_create_on_buf(const char *name, + void *buf, + pj_size_t size); + +PJ_END_DECL + +/** + * @} + */ + +#endif /* __POOL_STACK_H__ */ + diff --git a/pjlib/include/pj/pool_i.h b/pjlib/include/pj/pool_i.h new file mode 100644 index 0000000..ea4fa2d --- /dev/null +++ b/pjlib/include/pj/pool_i.h @@ -0,0 +1,94 @@ +/* $Id: pool_i.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 + * + * 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 + */ + + +#include + + +PJ_IDEF(pj_size_t) pj_pool_get_capacity( pj_pool_t *pool ) +{ + return pool->capacity; +} + +PJ_IDEF(pj_size_t) pj_pool_get_used_size( pj_pool_t *pool ) +{ + pj_pool_block *b = pool->block_list.next; + pj_size_t used_size = sizeof(pj_pool_t); + while (b != &pool->block_list) { + used_size += (b->cur - b->buf) + sizeof(pj_pool_block); + b = b->next; + } + return used_size; +} + +PJ_IDEF(void*) pj_pool_alloc_from_block( pj_pool_block *block, pj_size_t size ) +{ + /* The operation below is valid for size==0. + * When size==0, the function will return the pointer to the pool + * memory address, but no memory will be allocated. + */ + if (size & (PJ_POOL_ALIGNMENT-1)) { + size = (size + PJ_POOL_ALIGNMENT) & ~(PJ_POOL_ALIGNMENT-1); + } + if ((unsigned)(block->end - block->cur) >= size) { + void *ptr = block->cur; + block->cur += size; + return ptr; + } + return NULL; +} + +PJ_IDEF(void*) pj_pool_alloc( pj_pool_t *pool, pj_size_t size) +{ + void *ptr = pj_pool_alloc_from_block(pool->block_list.next, size); + if (!ptr) + ptr = pj_pool_allocate_find(pool, size); + return ptr; +} + + +PJ_IDEF(void*) pj_pool_calloc( pj_pool_t *pool, pj_size_t count, pj_size_t size) +{ + void *buf = pj_pool_alloc( pool, size*count); + if (buf) + pj_bzero(buf, size * count); + return buf; +} + +PJ_IDEF(const char *) pj_pool_getobjname( const pj_pool_t *pool ) +{ + return pool->obj_name; +} + +PJ_IDEF(pj_pool_t*) pj_pool_create( pj_pool_factory *f, + const char *name, + pj_size_t initial_size, + pj_size_t increment_size, + pj_pool_callback *callback) +{ + return (*f->create_pool)(f, name, initial_size, increment_size, callback); +} + +PJ_IDEF(void) pj_pool_release( pj_pool_t *pool ) +{ + if (pool->factory->release_pool) + (*pool->factory->release_pool)(pool->factory, pool); +} + diff --git a/pjlib/include/pj/rand.h b/pjlib/include/pj/rand.h new file mode 100644 index 0000000..8c8eb7e --- /dev/null +++ b/pjlib/include/pj/rand.h @@ -0,0 +1,66 @@ +/* $Id: rand.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 + * + * 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_RAND_H__ +#define __PJ_RAND_H__ + +/** + * @file rand.h + * @brief Random Number Generator. + */ + +#include + +PJ_BEGIN_DECL + + +/** + * @defgroup PJ_RAND Random Number Generator + * @ingroup PJ_MISC + * @{ + * This module contains functions for generating random numbers. + * This abstraction is needed not only because not all platforms have + * \a rand() and \a srand(), but also on some platforms \a rand() + * only has 16-bit randomness, which is not good enough. + */ + +/** + * Put in seed to random number generator. + * + * @param seed Seed value. + */ +PJ_DECL(void) pj_srand(unsigned int seed); + + +/** + * Generate random integer with 32bit randomness. + * + * @return a random integer. + */ +PJ_DECL(int) pj_rand(void); + + +/** @} */ + + +PJ_END_DECL + + +#endif /* __PJ_RAND_H__ */ + diff --git a/pjlib/include/pj/rbtree.h b/pjlib/include/pj/rbtree.h new file mode 100644 index 0000000..2f92285 --- /dev/null +++ b/pjlib/include/pj/rbtree.h @@ -0,0 +1,210 @@ +/* $Id: rbtree.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 + * + * 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_RBTREE_H__ +#define __PJ_RBTREE_H__ + +/** + * @file rbtree.h + * @brief Red/Black Tree + */ + +#include + +PJ_BEGIN_DECL + +/** + * @defgroup PJ_RBTREE Red/Black Balanced Tree + * @ingroup PJ_DS + * @brief + * Red/Black tree is the variant of balanced tree, where the search, insert, + * and delete operation is \b guaranteed to take at most \a O( lg(n) ). + * @{ + */ +/** + * Color type for Red-Black tree. + */ +typedef enum pj_rbcolor_t +{ + PJ_RBCOLOR_BLACK, + PJ_RBCOLOR_RED +} pj_rbcolor_t; + +/** + * The type of the node of the R/B Tree. + */ +typedef struct pj_rbtree_node +{ + /** Pointers to the node's parent, and left and right siblings. */ + struct pj_rbtree_node *parent, *left, *right; + + /** Key associated with the node. */ + const void *key; + + /** User data associated with the node. */ + void *user_data; + + /** The R/B Tree node color. */ + pj_rbcolor_t color; + +} pj_rbtree_node; + + +/** + * The type of function use to compare key value of tree node. + * @return + * 0 if the keys are equal + * <0 if key1 is lower than key2 + * >0 if key1 is greater than key2. + */ +typedef int pj_rbtree_comp(const void *key1, const void *key2); + + +/** + * Declaration of a red-black tree. All elements in the tree must have UNIQUE + * key. + * A red black tree always maintains the balance of the tree, so that the + * tree height will not be greater than lg(N). Insert, search, and delete + * operation will take lg(N) on the worst case. But for insert and delete, + * there is additional time needed to maintain the balance of the tree. + */ +typedef struct pj_rbtree +{ + pj_rbtree_node null_node; /**< Constant to indicate NULL node. */ + pj_rbtree_node *null; /**< Constant to indicate NULL node. */ + pj_rbtree_node *root; /**< Root tree node. */ + unsigned size; /**< Number of elements in the tree. */ + pj_rbtree_comp *comp; /**< Key comparison function. */ +} pj_rbtree; + + +/** + * Guidance on how much memory required for each of the node. + */ +#define PJ_RBTREE_NODE_SIZE (sizeof(pj_rbtree_node)) + + +/** + * Guidance on memory required for the tree. + */ +#define PJ_RBTREE_SIZE (sizeof(pj_rbtree)) + + +/** + * Initialize the tree. + * @param tree the tree to be initialized. + * @param comp key comparison function to be used for this tree. + */ +PJ_DECL(void) pj_rbtree_init( pj_rbtree *tree, pj_rbtree_comp *comp); + +/** + * Get the first element in the tree. + * The first element always has the least value for the key, according to + * the comparison function. + * @param tree the tree. + * @return the tree node, or NULL if the tree has no element. + */ +PJ_DECL(pj_rbtree_node*) pj_rbtree_first( pj_rbtree *tree ); + +/** + * Get the last element in the tree. + * The last element always has the greatest key value, according to the + * comparison function defined for the tree. + * @param tree the tree. + * @return the tree node, or NULL if the tree has no element. + */ +PJ_DECL(pj_rbtree_node*) pj_rbtree_last( pj_rbtree *tree ); + +/** + * Get the successive element for the specified node. + * The successive element is an element with greater key value. + * @param tree the tree. + * @param node the node. + * @return the successive node, or NULL if the node has no successor. + */ +PJ_DECL(pj_rbtree_node*) pj_rbtree_next( pj_rbtree *tree, + pj_rbtree_node *node ); + +/** + * The the previous node for the specified node. + * The previous node is an element with less key value. + * @param tree the tree. + * @param node the node. + * @return the previous node, or NULL if the node has no previous node. + */ +PJ_DECL(pj_rbtree_node*) pj_rbtree_prev( pj_rbtree *tree, + pj_rbtree_node *node ); + +/** + * Insert a new node. + * The node will be inserted at sorted location. The key of the node must + * be UNIQUE, i.e. it hasn't existed in the tree. + * @param tree the tree. + * @param node the node to be inserted. + * @return zero on success, or -1 if the key already exist. + */ +PJ_DECL(int) pj_rbtree_insert( pj_rbtree *tree, + pj_rbtree_node *node ); + +/** + * Find a node which has the specified key. + * @param tree the tree. + * @param key the key to search. + * @return the tree node with the specified key, or NULL if the key can not + * be found. + */ +PJ_DECL(pj_rbtree_node*) pj_rbtree_find( pj_rbtree *tree, + const void *key ); + +/** + * Erase a node from the tree. + * @param tree the tree. + * @param node the node to be erased. + * @return the tree node itself. + */ +PJ_DECL(pj_rbtree_node*) pj_rbtree_erase( pj_rbtree *tree, + pj_rbtree_node *node ); + +/** + * Get the maximum tree height from the specified node. + * @param tree the tree. + * @param node the node, or NULL to get the root of the tree. + * @return the maximum height, which should be at most lg(N) + */ +PJ_DECL(unsigned) pj_rbtree_max_height( pj_rbtree *tree, + pj_rbtree_node *node ); + +/** + * Get the minumum tree height from the specified node. + * @param tree the tree. + * @param node the node, or NULL to get the root of the tree. + * @return the height + */ +PJ_DECL(unsigned) pj_rbtree_min_height( pj_rbtree *tree, + pj_rbtree_node *node ); + + +/** + * @} + */ + +PJ_END_DECL + +#endif /* __PJ_RBTREE_H__ */ + diff --git a/pjlib/include/pj/sock.h b/pjlib/include/pj/sock.h new file mode 100644 index 0000000..2fcd896 --- /dev/null +++ b/pjlib/include/pj/sock.h @@ -0,0 +1,1393 @@ +/* $Id: sock.h 3841 2011-10-24 09:28:13Z ming $ */ +/* + * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono + * + * 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_SOCK_H__ +#define __PJ_SOCK_H__ + +/** + * @file sock.h + * @brief Socket Abstraction. + */ + +#include + +PJ_BEGIN_DECL + + +/** + * @defgroup PJ_SOCK Socket Abstraction + * @ingroup PJ_IO + * @{ + * + * The PJLIB socket abstraction layer is a thin and very portable abstraction + * for socket API. It provides API similar to BSD socket API. The abstraction + * is needed because BSD socket API is not always available on all platforms, + * therefore it wouldn't be possible to create a trully portable network + * programs unless we provide such abstraction. + * + * Applications can use this API directly in their application, just + * as they would when using traditional BSD socket API, provided they + * call #pj_init() first. + * + * \section pj_sock_examples_sec Examples + * + * For some examples on how to use the socket API, please see: + * + * - \ref page_pjlib_sock_test + * - \ref page_pjlib_select_test + * - \ref page_pjlib_sock_perf_test + */ + + +/** + * Supported address families. + * APPLICATION MUST USE THESE VALUES INSTEAD OF NORMAL AF_*, BECAUSE + * THE LIBRARY WILL DO TRANSLATION TO THE NATIVE VALUE. + */ + +/** Address family is unspecified. @see pj_AF_UNSPEC() */ +extern const pj_uint16_t PJ_AF_UNSPEC; + +/** Unix domain socket. @see pj_AF_UNIX() */ +extern const pj_uint16_t PJ_AF_UNIX; + +/** POSIX name for AF_UNIX */ +#define PJ_AF_LOCAL PJ_AF_UNIX; + +/** Internet IP protocol. @see pj_AF_INET() */ +extern const pj_uint16_t PJ_AF_INET; + +/** IP version 6. @see pj_AF_INET6() */ +extern const pj_uint16_t PJ_AF_INET6; + +/** Packet family. @see pj_AF_PACKET() */ +extern const pj_uint16_t PJ_AF_PACKET; + +/** IRDA sockets. @see pj_AF_IRDA() */ +extern const pj_uint16_t PJ_AF_IRDA; + +/* + * Accessor functions for various address family constants. These + * functions are provided because Symbian doesn't allow exporting + * global variables from a DLL. + */ + +#if defined(PJ_DLL) + /** Get #PJ_AF_UNSPEC value */ + PJ_DECL(pj_uint16_t) pj_AF_UNSPEC(void); + /** Get #PJ_AF_UNIX value. */ + PJ_DECL(pj_uint16_t) pj_AF_UNIX(void); + /** Get #PJ_AF_INET value. */ + PJ_DECL(pj_uint16_t) pj_AF_INET(void); + /** Get #PJ_AF_INET6 value. */ + PJ_DECL(pj_uint16_t) pj_AF_INET6(void); + /** Get #PJ_AF_PACKET value. */ + PJ_DECL(pj_uint16_t) pj_AF_PACKET(void); + /** Get #PJ_AF_IRDA value. */ + PJ_DECL(pj_uint16_t) pj_AF_IRDA(void); +#else + /* When pjlib is not built as DLL, these accessor functions are + * simply a macro to get their constants + */ + /** Get #PJ_AF_UNSPEC value */ +# define pj_AF_UNSPEC() PJ_AF_UNSPEC + /** Get #PJ_AF_UNIX value. */ +# define pj_AF_UNIX() PJ_AF_UNIX + /** Get #PJ_AF_INET value. */ +# define pj_AF_INET() PJ_AF_INET + /** Get #PJ_AF_INET6 value. */ +# define pj_AF_INET6() PJ_AF_INET6 + /** Get #PJ_AF_PACKET value. */ +# define pj_AF_PACKET() PJ_AF_PACKET + /** Get #PJ_AF_IRDA value. */ +# define pj_AF_IRDA() PJ_AF_IRDA +#endif + + +/** + * Supported types of sockets. + * APPLICATION MUST USE THESE VALUES INSTEAD OF NORMAL SOCK_*, BECAUSE + * THE LIBRARY WILL TRANSLATE THE VALUE TO THE NATIVE VALUE. + */ + +/** Sequenced, reliable, connection-based byte streams. + * @see pj_SOCK_STREAM() */ +extern const pj_uint16_t PJ_SOCK_STREAM; + +/** Connectionless, unreliable datagrams of fixed maximum lengths. + * @see pj_SOCK_DGRAM() */ +extern const pj_uint16_t PJ_SOCK_DGRAM; + +/** Raw protocol interface. @see pj_SOCK_RAW() */ +extern const pj_uint16_t PJ_SOCK_RAW; + +/** Reliably-delivered messages. @see pj_SOCK_RDM() */ +extern const pj_uint16_t PJ_SOCK_RDM; + + +/* + * Accessor functions for various constants. These functions are provided + * because Symbian doesn't allow exporting global variables from a DLL. + */ + +#if defined(PJ_DLL) + /** Get #PJ_SOCK_STREAM constant */ + PJ_DECL(int) pj_SOCK_STREAM(void); + /** Get #PJ_SOCK_DGRAM constant */ + PJ_DECL(int) pj_SOCK_DGRAM(void); + /** Get #PJ_SOCK_RAW constant */ + PJ_DECL(int) pj_SOCK_RAW(void); + /** Get #PJ_SOCK_RDM constant */ + PJ_DECL(int) pj_SOCK_RDM(void); +#else + /** Get #PJ_SOCK_STREAM constant */ +# define pj_SOCK_STREAM() PJ_SOCK_STREAM + /** Get #PJ_SOCK_DGRAM constant */ +# define pj_SOCK_DGRAM() PJ_SOCK_DGRAM + /** Get #PJ_SOCK_RAW constant */ +# define pj_SOCK_RAW() PJ_SOCK_RAW + /** Get #PJ_SOCK_RDM constant */ +# define pj_SOCK_RDM() PJ_SOCK_RDM +#endif + + +/** + * Socket level specified in #pj_sock_setsockopt() or #pj_sock_getsockopt(). + * APPLICATION MUST USE THESE VALUES INSTEAD OF NORMAL SOL_*, BECAUSE + * THE LIBRARY WILL TRANSLATE THE VALUE TO THE NATIVE VALUE. + */ +/** Socket level. @see pj_SOL_SOCKET() */ +extern const pj_uint16_t PJ_SOL_SOCKET; +/** IP level. @see pj_SOL_IP() */ +extern const pj_uint16_t PJ_SOL_IP; +/** TCP level. @see pj_SOL_TCP() */ +extern const pj_uint16_t PJ_SOL_TCP; +/** UDP level. @see pj_SOL_UDP() */ +extern const pj_uint16_t PJ_SOL_UDP; +/** IP version 6. @see pj_SOL_IPV6() */ +extern const pj_uint16_t PJ_SOL_IPV6; + +/* + * Accessor functions for various constants. These functions are provided + * because Symbian doesn't allow exporting global variables from a DLL. + */ + +#if defined(PJ_DLL) + /** Get #PJ_SOL_SOCKET constant */ + PJ_DECL(pj_uint16_t) pj_SOL_SOCKET(void); + /** Get #PJ_SOL_IP constant */ + PJ_DECL(pj_uint16_t) pj_SOL_IP(void); + /** Get #PJ_SOL_TCP constant */ + PJ_DECL(pj_uint16_t) pj_SOL_TCP(void); + /** Get #PJ_SOL_UDP constant */ + PJ_DECL(pj_uint16_t) pj_SOL_UDP(void); + /** Get #PJ_SOL_IPV6 constant */ + PJ_DECL(pj_uint16_t) pj_SOL_IPV6(void); +#else + /** Get #PJ_SOL_SOCKET constant */ +# define pj_SOL_SOCKET() PJ_SOL_SOCKET + /** Get #PJ_SOL_IP constant */ +# define pj_SOL_IP() PJ_SOL_IP + /** Get #PJ_SOL_TCP constant */ +# define pj_SOL_TCP() PJ_SOL_TCP + /** Get #PJ_SOL_UDP constant */ +# define pj_SOL_UDP() PJ_SOL_UDP + /** Get #PJ_SOL_IPV6 constant */ +# define pj_SOL_IPV6() PJ_SOL_IPV6 +#endif + + +/* IP_TOS + * + * Note: + * TOS CURRENTLY DOES NOT WORK IN Windows 2000 and above! + * See http://support.microsoft.com/kb/248611 + */ +/** IP_TOS optname in setsockopt(). @see pj_IP_TOS() */ +extern const pj_uint16_t PJ_IP_TOS; + +/* + * IP TOS related constats. + * + * Note: + * TOS CURRENTLY DOES NOT WORK IN Windows 2000 and above! + * See http://support.microsoft.com/kb/248611 + */ +/** Minimize delays. @see pj_IPTOS_LOWDELAY() */ +extern const pj_uint16_t PJ_IPTOS_LOWDELAY; + +/** Optimize throughput. @see pj_IPTOS_THROUGHPUT() */ +extern const pj_uint16_t PJ_IPTOS_THROUGHPUT; + +/** Optimize for reliability. @see pj_IPTOS_RELIABILITY() */ +extern const pj_uint16_t PJ_IPTOS_RELIABILITY; + +/** "filler data" where slow transmission does't matter. + * @see pj_IPTOS_MINCOST() */ +extern const pj_uint16_t PJ_IPTOS_MINCOST; + + +#if defined(PJ_DLL) + /** Get #PJ_IP_TOS constant */ + PJ_DECL(int) pj_IP_TOS(void); + + /** Get #PJ_IPTOS_LOWDELAY constant */ + PJ_DECL(int) pj_IPTOS_LOWDELAY(void); + + /** Get #PJ_IPTOS_THROUGHPUT constant */ + PJ_DECL(int) pj_IPTOS_THROUGHPUT(void); + + /** Get #PJ_IPTOS_RELIABILITY constant */ + PJ_DECL(int) pj_IPTOS_RELIABILITY(void); + + /** Get #PJ_IPTOS_MINCOST constant */ + PJ_DECL(int) pj_IPTOS_MINCOST(void); +#else + /** Get #PJ_IP_TOS constant */ +# define pj_IP_TOS() PJ_IP_TOS + + /** Get #PJ_IPTOS_LOWDELAY constant */ +# define pj_IPTOS_LOWDELAY() PJ_IP_TOS_LOWDELAY + + /** Get #PJ_IPTOS_THROUGHPUT constant */ +# define pj_IPTOS_THROUGHPUT() PJ_IP_TOS_THROUGHPUT + + /** Get #PJ_IPTOS_RELIABILITY constant */ +# define pj_IPTOS_RELIABILITY() PJ_IP_TOS_RELIABILITY + + /** Get #PJ_IPTOS_MINCOST constant */ +# define pj_IPTOS_MINCOST() PJ_IP_TOS_MINCOST +#endif + + +/** + * Values to be specified as \c optname when calling #pj_sock_setsockopt() + * or #pj_sock_getsockopt(). + */ + +/** Socket type. @see pj_SO_TYPE() */ +extern const pj_uint16_t PJ_SO_TYPE; + +/** Buffer size for receive. @see pj_SO_RCVBUF() */ +extern const pj_uint16_t PJ_SO_RCVBUF; + +/** Buffer size for send. @see pj_SO_SNDBUF() */ +extern const pj_uint16_t PJ_SO_SNDBUF; + +/** Disables the Nagle algorithm for send coalescing. @see pj_TCP_NODELAY */ +extern const pj_uint16_t PJ_TCP_NODELAY; + +/** Allows the socket to be bound to an address that is already in use. + * @see pj_SO_REUSEADDR */ +extern const pj_uint16_t PJ_SO_REUSEADDR; + +/** Do not generate SIGPIPE. @see pj_SO_NOSIGPIPE */ +extern const pj_uint16_t PJ_SO_NOSIGPIPE; + +/** Set the protocol-defined priority for all packets to be sent on socket. + */ +extern const pj_uint16_t PJ_SO_PRIORITY; + +/** IP multicast interface. @see pj_IP_MULTICAST_IF() */ +extern const pj_uint16_t PJ_IP_MULTICAST_IF; + +/** IP multicast ttl. @see pj_IP_MULTICAST_TTL() */ +extern const pj_uint16_t PJ_IP_MULTICAST_TTL; + +/** IP multicast loopback. @see pj_IP_MULTICAST_LOOP() */ +extern const pj_uint16_t PJ_IP_MULTICAST_LOOP; + +/** Add an IP group membership. @see pj_IP_ADD_MEMBERSHIP() */ +extern const pj_uint16_t PJ_IP_ADD_MEMBERSHIP; + +/** Drop an IP group membership. @see pj_IP_DROP_MEMBERSHIP() */ +extern const pj_uint16_t PJ_IP_DROP_MEMBERSHIP; + + +#if defined(PJ_DLL) + /** Get #PJ_SO_TYPE constant */ + PJ_DECL(pj_uint16_t) pj_SO_TYPE(void); + + /** Get #PJ_SO_RCVBUF constant */ + PJ_DECL(pj_uint16_t) pj_SO_RCVBUF(void); + + /** Get #PJ_SO_SNDBUF constant */ + PJ_DECL(pj_uint16_t) pj_SO_SNDBUF(void); + + /** Get #PJ_TCP_NODELAY constant */ + PJ_DECL(pj_uint16_t) pj_TCP_NODELAY(void); + + /** Get #PJ_SO_REUSEADDR constant */ + PJ_DECL(pj_uint16_t) pj_SO_REUSEADDR(void); + + /** Get #PJ_SO_NOSIGPIPE constant */ + PJ_DECL(pj_uint16_t) pj_SO_NOSIGPIPE(void); + + /** Get #PJ_SO_PRIORITY constant */ + PJ_DECL(pj_uint16_t) pj_SO_PRIORITY(void); + + /** Get #PJ_IP_MULTICAST_IF constant */ + PJ_DECL(pj_uint16_t) pj_IP_MULTICAST_IF(void); + + /** Get #PJ_IP_MULTICAST_TTL constant */ + PJ_DECL(pj_uint16_t) pj_IP_MULTICAST_TTL(void); + + /** Get #PJ_IP_MULTICAST_LOOP constant */ + PJ_DECL(pj_uint16_t) pj_IP_MULTICAST_LOOP(void); + + /** Get #PJ_IP_ADD_MEMBERSHIP constant */ + PJ_DECL(pj_uint16_t) pj_IP_ADD_MEMBERSHIP(void); + + /** Get #PJ_IP_DROP_MEMBERSHIP constant */ + PJ_DECL(pj_uint16_t) pj_IP_DROP_MEMBERSHIP(void); +#else + /** Get #PJ_SO_TYPE constant */ +# define pj_SO_TYPE() PJ_SO_TYPE + + /** Get #PJ_SO_RCVBUF constant */ +# define pj_SO_RCVBUF() PJ_SO_RCVBUF + + /** Get #PJ_SO_SNDBUF constant */ +# define pj_SO_SNDBUF() PJ_SO_SNDBUF + + /** Get #PJ_TCP_NODELAY constant */ +# define pj_TCP_NODELAY() PJ_TCP_NODELAY + + /** Get #PJ_SO_REUSEADDR constant */ +# define pj_SO_REUSEADDR() PJ_SO_REUSEADDR + + /** Get #PJ_SO_NOSIGPIPE constant */ +# define pj_SO_NOSIGPIPE() PJ_SO_NOSIGPIPE + + /** Get #PJ_SO_PRIORITY constant */ +# define pj_SO_PRIORITY() PJ_SO_PRIORITY + + /** Get #PJ_IP_MULTICAST_IF constant */ +# define pj_IP_MULTICAST_IF() PJ_IP_MULTICAST_IF + + /** Get #PJ_IP_MULTICAST_TTL constant */ +# define pj_IP_MULTICAST_TTL() PJ_IP_MULTICAST_TTL + + /** Get #PJ_IP_MULTICAST_LOOP constant */ +# define pj_IP_MULTICAST_LOOP() PJ_IP_MULTICAST_LOOP + + /** Get #PJ_IP_ADD_MEMBERSHIP constant */ +# define pj_IP_ADD_MEMBERSHIP() PJ_IP_ADD_MEMBERSHIP + + /** Get #PJ_IP_DROP_MEMBERSHIP constant */ +# define pj_IP_DROP_MEMBERSHIP() PJ_IP_DROP_MEMBERSHIP +#endif + + +/* + * Flags to be specified in #pj_sock_recv, #pj_sock_send, etc. + */ + +/** Out-of-band messages. @see pj_MSG_OOB() */ +extern const int PJ_MSG_OOB; + +/** Peek, don't remove from buffer. @see pj_MSG_PEEK() */ +extern const int PJ_MSG_PEEK; + +/** Don't route. @see pj_MSG_DONTROUTE() */ +extern const int PJ_MSG_DONTROUTE; + + +#if defined(PJ_DLL) + /** Get #PJ_MSG_OOB constant */ + PJ_DECL(int) pj_MSG_OOB(void); + + /** Get #PJ_MSG_PEEK constant */ + PJ_DECL(int) pj_MSG_PEEK(void); + + /** Get #PJ_MSG_DONTROUTE constant */ + PJ_DECL(int) pj_MSG_DONTROUTE(void); +#else + /** Get #PJ_MSG_OOB constant */ +# define pj_MSG_OOB() PJ_MSG_OOB + + /** Get #PJ_MSG_PEEK constant */ +# define pj_MSG_PEEK() PJ_MSG_PEEK + + /** Get #PJ_MSG_DONTROUTE constant */ +# define pj_MSG_DONTROUTE() PJ_MSG_DONTROUTE +#endif + + +/** + * Flag to be specified in #pj_sock_shutdown(). + */ +typedef enum pj_socket_sd_type +{ + PJ_SD_RECEIVE = 0, /**< No more receive. */ + PJ_SHUT_RD = 0, /**< Alias for SD_RECEIVE. */ + PJ_SD_SEND = 1, /**< No more sending. */ + PJ_SHUT_WR = 1, /**< Alias for SD_SEND. */ + PJ_SD_BOTH = 2, /**< No more send and receive. */ + PJ_SHUT_RDWR = 2 /**< Alias for SD_BOTH. */ +} pj_socket_sd_type; + + + +/** Address to accept any incoming messages. */ +#define PJ_INADDR_ANY ((pj_uint32_t)0) + +/** Address indicating an error return */ +#define PJ_INADDR_NONE ((pj_uint32_t)0xffffffff) + +/** Address to send to all hosts. */ +#define PJ_INADDR_BROADCAST ((pj_uint32_t)0xffffffff) + + +/** + * Maximum length specifiable by #pj_sock_listen(). + * If the build system doesn't override this value, then the lowest + * denominator (five, in Win32 systems) will be used. + */ +#if !defined(PJ_SOMAXCONN) +# define PJ_SOMAXCONN 5 +#endif + + +/** + * Constant for invalid socket returned by #pj_sock_socket() and + * #pj_sock_accept(). + */ +#define PJ_INVALID_SOCKET (-1) + +/* Must undefine s_addr because of pj_in_addr below */ +#undef s_addr + +/** + * This structure describes Internet address. + */ +typedef struct pj_in_addr +{ + pj_uint32_t s_addr; /**< The 32bit IP address. */ +} pj_in_addr; + + +/** + * Maximum length of text representation of an IPv4 address. + */ +#define PJ_INET_ADDRSTRLEN 16 + +/** + * Maximum length of text representation of an IPv6 address. + */ +#define PJ_INET6_ADDRSTRLEN 46 + +/** + * The size of sin_zero field in pj_sockaddr_in structure. Most OSes + * use 8, but others such as the BSD TCP/IP stack in eCos uses 24. + */ +#ifndef PJ_SOCKADDR_IN_SIN_ZERO_LEN +# define PJ_SOCKADDR_IN_SIN_ZERO_LEN 8 +#endif + +/** + * This structure describes Internet socket address. + * If PJ_SOCKADDR_HAS_LEN is not zero, then sin_zero_len member is added + * to this struct. As far the application is concerned, the value of + * this member will always be zero. Internally, PJLIB may modify the value + * before calling OS socket API, and reset the value back to zero before + * returning the struct to application. + */ +struct pj_sockaddr_in +{ +#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0 + pj_uint8_t sin_zero_len; /**< Just ignore this. */ + pj_uint8_t sin_family; /**< Address family. */ +#else + pj_uint16_t sin_family; /**< Address family. */ +#endif + pj_uint16_t sin_port; /**< Transport layer port number. */ + pj_in_addr sin_addr; /**< IP address. */ + char sin_zero[PJ_SOCKADDR_IN_SIN_ZERO_LEN]; /**< Padding.*/ +}; + + +#undef s6_addr + +/** + * This structure describes IPv6 address. + */ +typedef union pj_in6_addr +{ + /* This is the main entry */ + pj_uint8_t s6_addr[16]; /**< 8-bit array */ + + /* While these are used for proper alignment */ + pj_uint32_t u6_addr32[4]; + + /* Do not use this with Winsock2, as this will align pj_sockaddr_in6 + * to 64-bit boundary and Winsock2 doesn't like it! + * Update 26/04/2010: + * This is now disabled, see http://trac.pjsip.org/repos/ticket/1058 + */ +#if 0 && defined(PJ_HAS_INT64) && PJ_HAS_INT64!=0 && \ + (!defined(PJ_WIN32) || PJ_WIN32==0) + pj_int64_t u6_addr64[2]; +#endif + +} pj_in6_addr; + + +/** Initializer value for pj_in6_addr. */ +#define PJ_IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } } + +/** Initializer value for pj_in6_addr. */ +#define PJ_IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } } + +/** + * This structure describes IPv6 socket address. + * If PJ_SOCKADDR_HAS_LEN is not zero, then sin_zero_len member is added + * to this struct. As far the application is concerned, the value of + * this member will always be zero. Internally, PJLIB may modify the value + * before calling OS socket API, and reset the value back to zero before + * returning the struct to application. + */ +typedef struct pj_sockaddr_in6 +{ +#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0 + pj_uint8_t sin6_zero_len; /**< Just ignore this. */ + pj_uint8_t sin6_family; /**< Address family. */ +#else + pj_uint16_t sin6_family; /**< Address family */ +#endif + pj_uint16_t sin6_port; /**< Transport layer port number. */ + pj_uint32_t sin6_flowinfo; /**< IPv6 flow information */ + pj_in6_addr sin6_addr; /**< IPv6 address. */ + pj_uint32_t sin6_scope_id; /**< Set of interfaces for a scope */ +} pj_sockaddr_in6; + + +/** + * This structure describes common attributes found in transport addresses. + * If PJ_SOCKADDR_HAS_LEN is not zero, then sa_zero_len member is added + * to this struct. As far the application is concerned, the value of + * this member will always be zero. Internally, PJLIB may modify the value + * before calling OS socket API, and reset the value back to zero before + * returning the struct to application. + */ +typedef struct pj_addr_hdr +{ +#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0 + pj_uint8_t sa_zero_len; + pj_uint8_t sa_family; +#else + pj_uint16_t sa_family; /**< Common data: address family. */ +#endif +} pj_addr_hdr; + + +/** + * This union describes a generic socket address. + */ +typedef union pj_sockaddr +{ + pj_addr_hdr addr; /**< Generic transport address. */ + pj_sockaddr_in ipv4; /**< IPv4 transport address. */ + pj_sockaddr_in6 ipv6; /**< IPv6 transport address. */ +} pj_sockaddr; + + +/** + * This structure provides multicast group information for IPv4 addresses. + */ +typedef struct pj_ip_mreq { + pj_in_addr imr_multiaddr; /**< IP multicast address of group. */ + pj_in_addr imr_interface; /**< local IP address of interface. */ +} pj_ip_mreq; + + +/***************************************************************************** + * + * SOCKET ADDRESS MANIPULATION. + * + ***************************************************************************** + */ + +/** + * Convert 16-bit value from network byte order to host byte order. + * + * @param netshort 16-bit network value. + * @return 16-bit host value. + */ +PJ_DECL(pj_uint16_t) pj_ntohs(pj_uint16_t netshort); + +/** + * Convert 16-bit value from host byte order to network byte order. + * + * @param hostshort 16-bit host value. + * @return 16-bit network value. + */ +PJ_DECL(pj_uint16_t) pj_htons(pj_uint16_t hostshort); + +/** + * Convert 32-bit value from network byte order to host byte order. + * + * @param netlong 32-bit network value. + * @return 32-bit host value. + */ +PJ_DECL(pj_uint32_t) pj_ntohl(pj_uint32_t netlong); + +/** + * Convert 32-bit value from host byte order to network byte order. + * + * @param hostlong 32-bit host value. + * @return 32-bit network value. + */ +PJ_DECL(pj_uint32_t) pj_htonl(pj_uint32_t hostlong); + +/** + * Convert an Internet host address given in network byte order + * to string in standard numbers and dots notation. + * + * @param inaddr The host address. + * @return The string address. + */ +PJ_DECL(char*) pj_inet_ntoa(pj_in_addr inaddr); + +/** + * This function converts the Internet host address cp from the standard + * numbers-and-dots notation into binary data and stores it in the structure + * that inp points to. + * + * @param cp IP address in standard numbers-and-dots notation. + * @param inp Structure that holds the output of the conversion. + * + * @return nonzero if the address is valid, zero if not. + */ +PJ_DECL(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp); + +/** + * This function converts an address in its standard text presentation form + * into its numeric binary form. It supports both IPv4 and IPv6 address + * conversion. + * + * @param af Specify the family of the address. The PJ_AF_INET and + * PJ_AF_INET6 address families shall be supported. + * @param src Points to the string being passed in. + * @param dst Points to a buffer into which the function stores the + * numeric address; this shall be large enough to hold the + * numeric address (32 bits for PJ_AF_INET, 128 bits for + * PJ_AF_INET6). + * + * @return PJ_SUCCESS if conversion was successful. + */ +PJ_DECL(pj_status_t) pj_inet_pton(int af, const pj_str_t *src, void *dst); + +/** + * This function converts a numeric address into a text string suitable + * for presentation. It supports both IPv4 and IPv6 address + * conversion. + * @see pj_sockaddr_print() + * + * @param af Specify the family of the address. This can be PJ_AF_INET + * or PJ_AF_INET6. + * @param src Points to a buffer holding an IPv4 address if the af argument + * is PJ_AF_INET, or an IPv6 address if the af argument is + * PJ_AF_INET6; the address must be in network byte order. + * @param dst Points to a buffer where the function stores the resulting + * text string; it shall not be NULL. + * @param size Specifies the size of this buffer, which shall be large + * enough to hold the text string (PJ_INET_ADDRSTRLEN characters + * for IPv4, PJ_INET6_ADDRSTRLEN characters for IPv6). + * + * @return PJ_SUCCESS if conversion was successful. + */ +PJ_DECL(pj_status_t) pj_inet_ntop(int af, const void *src, + char *dst, int size); + +/** + * Converts numeric address into its text string representation. + * @see pj_sockaddr_print() + * + * @param af Specify the family of the address. This can be PJ_AF_INET + * or PJ_AF_INET6. + * @param src Points to a buffer holding an IPv4 address if the af argument + * is PJ_AF_INET, or an IPv6 address if the af argument is + * PJ_AF_INET6; the address must be in network byte order. + * @param dst Points to a buffer where the function stores the resulting + * text string; it shall not be NULL. + * @param size Specifies the size of this buffer, which shall be large + * enough to hold the text string (PJ_INET_ADDRSTRLEN characters + * for IPv4, PJ_INET6_ADDRSTRLEN characters for IPv6). + * + * @return The address string or NULL if failed. + */ +PJ_DECL(char*) pj_inet_ntop2(int af, const void *src, + char *dst, int size); + +/** + * Print socket address. + * + * @param addr The socket address. + * @param buf Text buffer. + * @param size Size of buffer. + * @param flags Bitmask combination of these value: + * - 1: port number is included. + * - 2: square bracket is included for IPv6 address. + * + * @return The address string. + */ +PJ_DECL(char*) pj_sockaddr_print(const pj_sockaddr_t *addr, + char *buf, int size, + unsigned flags); + +/** + * Convert address string with numbers and dots to binary IP address. + * + * @param cp The IP address in numbers and dots notation. + * @return If success, the IP address is returned in network + * byte order. If failed, PJ_INADDR_NONE will be + * returned. + * @remark + * This is an obsolete interface to #pj_inet_aton(); it is obsolete + * because -1 is a valid address (255.255.255.255), and #pj_inet_aton() + * provides a cleaner way to indicate error return. + */ +PJ_DECL(pj_in_addr) pj_inet_addr(const pj_str_t *cp); + +/** + * Convert address string with numbers and dots to binary IP address. + * + * @param cp The IP address in numbers and dots notation. + * @return If success, the IP address is returned in network + * byte order. If failed, PJ_INADDR_NONE will be + * returned. + * @remark + * This is an obsolete interface to #pj_inet_aton(); it is obsolete + * because -1 is a valid address (255.255.255.255), and #pj_inet_aton() + * provides a cleaner way to indicate error return. + */ +PJ_DECL(pj_in_addr) pj_inet_addr2(const char *cp); + +/** + * Initialize IPv4 socket address based on the address and port info. + * The string address may be in a standard numbers and dots notation or + * may be a hostname. If hostname is specified, then the function will + * resolve the host into the IP address. + * + * @see pj_sockaddr_init() + * + * @param addr The IP socket address to be set. + * @param cp The address string, which can be in a standard + * dotted numbers or a hostname to be resolved. + * @param port The port number, in host byte order. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pj_sockaddr_in_init( pj_sockaddr_in *addr, + const pj_str_t *cp, + pj_uint16_t port); + +/** + * Initialize IP socket address based on the address and port info. + * The string address may be in a standard numbers and dots notation or + * may be a hostname. If hostname is specified, then the function will + * resolve the host into the IP address. + * + * @see pj_sockaddr_in_init() + * + * @param af Internet address family. + * @param addr The IP socket address to be set. + * @param cp The address string, which can be in a standard + * dotted numbers or a hostname to be resolved. + * @param port The port number, in host byte order. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pj_sockaddr_init(int af, + pj_sockaddr *addr, + const pj_str_t *cp, + pj_uint16_t port); + +/** + * Compare two socket addresses. + * + * @param addr1 First address. + * @param addr2 Second address. + * + * @return Zero on equal, -1 if addr1 is less than addr2, + * and +1 if addr1 is more than addr2. + */ +PJ_DECL(int) pj_sockaddr_cmp(const pj_sockaddr_t *addr1, + const pj_sockaddr_t *addr2); + +/** + * Get pointer to the address part of a socket address. + * + * @param addr Socket address. + * + * @return Pointer to address part (sin_addr or sin6_addr, + * depending on address family) + */ +PJ_DECL(void*) pj_sockaddr_get_addr(const pj_sockaddr_t *addr); + +/** + * Check that a socket address contains a non-zero address part. + * + * @param addr Socket address. + * + * @return Non-zero if address is set to non-zero. + */ +PJ_DECL(pj_bool_t) pj_sockaddr_has_addr(const pj_sockaddr_t *addr); + +/** + * Get the address part length of a socket address, based on its address + * family. For PJ_AF_INET, the length will be sizeof(pj_in_addr), and + * for PJ_AF_INET6, the length will be sizeof(pj_in6_addr). + * + * @param addr Socket address. + * + * @return Length in bytes. + */ +PJ_DECL(unsigned) pj_sockaddr_get_addr_len(const pj_sockaddr_t *addr); + +/** + * Get the socket address length, based on its address + * family. For PJ_AF_INET, the length will be sizeof(pj_sockaddr_in), and + * for PJ_AF_INET6, the length will be sizeof(pj_sockaddr_in6). + * + * @param addr Socket address. + * + * @return Length in bytes. + */ +PJ_DECL(unsigned) pj_sockaddr_get_len(const pj_sockaddr_t *addr); + +/** + * Copy only the address part (sin_addr/sin6_addr) of a socket address. + * + * @param dst Destination socket address. + * @param src Source socket address. + * + * @see @pj_sockaddr_cp() + */ +PJ_DECL(void) pj_sockaddr_copy_addr(pj_sockaddr *dst, + const pj_sockaddr *src); +/** + * Copy socket address. This will copy the whole structure depending + * on the address family of the source socket address. + * + * @param dst Destination socket address. + * @param src Source socket address. + * + * @see @pj_sockaddr_copy_addr() + */ +PJ_DECL(void) pj_sockaddr_cp(pj_sockaddr_t *dst, const pj_sockaddr_t *src); + +/** + * Get the IP address of an IPv4 socket address. + * The address is returned as 32bit value in host byte order. + * + * @param addr The IP socket address. + * @return 32bit address, in host byte order. + */ +PJ_DECL(pj_in_addr) pj_sockaddr_in_get_addr(const pj_sockaddr_in *addr); + +/** + * Set the IP address of an IPv4 socket address. + * + * @param addr The IP socket address. + * @param hostaddr The host address, in host byte order. + */ +PJ_DECL(void) pj_sockaddr_in_set_addr(pj_sockaddr_in *addr, + pj_uint32_t hostaddr); + +/** + * Set the IP address of an IP socket address from string address, + * with resolving the host if necessary. The string address may be in a + * standard numbers and dots notation or may be a hostname. If hostname + * is specified, then the function will resolve the host into the IP + * address. + * + * @see pj_sockaddr_set_str_addr() + * + * @param addr The IP socket address to be set. + * @param cp The address string, which can be in a standard + * dotted numbers or a hostname to be resolved. + * + * @return PJ_SUCCESS on success. + */ +PJ_DECL(pj_status_t) pj_sockaddr_in_set_str_addr( pj_sockaddr_in *addr, + const pj_str_t *cp); + +/** + * Set the IP address of an IPv4 or IPv6 socket address from string address, + * with resolving the host if necessary. The string address may be in a + * standard IPv6 or IPv6 address or may be a hostname. If hostname + * is specified, then the function will resolve the host into the IP + * address according to the address family. + * + * @param af Address family. + * @param addr The IP socket address to be set. + * @param cp The address string, which can be in a standard + * IP numbers (IPv4 or IPv6) or a hostname to be resolved. + * + * @return PJ_SUCCESS on success. + */ +PJ_DECL(pj_status_t) pj_sockaddr_set_str_addr(int af, + pj_sockaddr *addr, + const pj_str_t *cp); + +/** + * Get the port number of a socket address, in host byte order. + * This function can be used for both IPv4 and IPv6 socket address. + * + * @param addr Socket address. + * + * @return Port number, in host byte order. + */ +PJ_DECL(pj_uint16_t) pj_sockaddr_get_port(const pj_sockaddr_t *addr); + +/** + * Get the transport layer port number of an Internet socket address. + * The port is returned in host byte order. + * + * @param addr The IP socket address. + * @return Port number, in host byte order. + */ +PJ_DECL(pj_uint16_t) pj_sockaddr_in_get_port(const pj_sockaddr_in *addr); + +/** + * Set the port number of an Internet socket address. + * + * @param addr The socket address. + * @param hostport The port number, in host byte order. + */ +PJ_DECL(pj_status_t) pj_sockaddr_set_port(pj_sockaddr *addr, + pj_uint16_t hostport); + +/** + * Set the port number of an IPv4 socket address. + * + * @see pj_sockaddr_set_port() + * + * @param addr The IP socket address. + * @param hostport The port number, in host byte order. + */ +PJ_DECL(void) pj_sockaddr_in_set_port(pj_sockaddr_in *addr, + pj_uint16_t hostport); + +/** + * Parse string containing IP address and optional port into socket address, + * possibly also with address family detection. This function supports both + * IPv4 and IPv6 parsing, however IPv6 parsing may only be done if IPv6 is + * enabled during compilation. + * + * This function supports parsing several formats. Sample IPv4 inputs and + * their default results:: + * - "10.0.0.1:80": address 10.0.0.1 and port 80. + * - "10.0.0.1": address 10.0.0.1 and port zero. + * - "10.0.0.1:": address 10.0.0.1 and port zero. + * - "10.0.0.1:0": address 10.0.0.1 and port zero. + * - ":80": address 0.0.0.0 and port 80. + * - ":": address 0.0.0.0 and port 0. + * - "localhost": address 127.0.0.1 and port 0. + * - "localhost:": address 127.0.0.1 and port 0. + * - "localhost:80": address 127.0.0.1 and port 80. + * + * Sample IPv6 inputs and their default results: + * - "[fec0::01]:80": address fec0::01 and port 80 + * - "[fec0::01]": address fec0::01 and port 0 + * - "[fec0::01]:": address fec0::01 and port 0 + * - "[fec0::01]:0": address fec0::01 and port 0 + * - "fec0::01": address fec0::01 and port 0 + * - "fec0::01:80": address fec0::01:80 and port 0 + * - "::": address zero (::) and port 0 + * - "[::]": address zero (::) and port 0 + * - "[::]:": address zero (::) and port 0 + * - ":::": address zero (::) and port 0 + * - "[::]:80": address zero (::) and port 0 + * - ":::80": address zero (::) and port 80 + * + * Note: when the IPv6 socket address contains port number, the IP + * part of the socket address should be enclosed with square brackets, + * otherwise the port number will be included as part of the IP address + * (see "fec0::01:80" example above). + * + * @param af Optionally specify the address family to be used. If the + * address family is to be deducted from the input, specify + * pj_AF_UNSPEC() here. Other supported values are + * #pj_AF_INET() and #pj_AF_INET6() + * @param options Additional options to assist the parsing, must be zero + * for now. + * @param str The input string to be parsed. + * @param addr Pointer to store the result. + * + * @return PJ_SUCCESS if the parsing is successful. + * + * @see pj_sockaddr_parse2() + */ +PJ_DECL(pj_status_t) pj_sockaddr_parse(int af, unsigned options, + const pj_str_t *str, + pj_sockaddr *addr); + +/** + * This function is similar to #pj_sockaddr_parse(), except that it will not + * convert the hostpart into IP address (thus possibly resolving the hostname + * into a #pj_sockaddr. + * + * Unlike #pj_sockaddr_parse(), this function has a limitation that if port + * number is specified in an IPv6 input string, the IP part of the IPv6 socket + * address MUST be enclosed in square brackets, otherwise the port number will + * be considered as part of the IPv6 IP address. + * + * @param af Optionally specify the address family to be used. If the + * address family is to be deducted from the input, specify + * #pj_AF_UNSPEC() here. Other supported values are + * #pj_AF_INET() and #pj_AF_INET6() + * @param options Additional options to assist the parsing, must be zero + * for now. + * @param str The input string to be parsed. + * @param hostpart Optional pointer to store the host part of the socket + * address, with any brackets removed. + * @param port Optional pointer to store the port number. If port number + * is not found, this will be set to zero upon return. + * @param raf Optional pointer to store the detected address family of + * the input address. + * + * @return PJ_SUCCESS if the parsing is successful. + * + * @see pj_sockaddr_parse() + */ +PJ_DECL(pj_status_t) pj_sockaddr_parse2(int af, unsigned options, + const pj_str_t *str, + pj_str_t *hostpart, + pj_uint16_t *port, + int *raf); + +/***************************************************************************** + * + * HOST NAME AND ADDRESS. + * + ***************************************************************************** + */ + +/** + * Get system's host name. + * + * @return The hostname, or empty string if the hostname can not + * be identified. + */ +PJ_DECL(const pj_str_t*) pj_gethostname(void); + +/** + * Get host's IP address, which the the first IP address that is resolved + * from the hostname. + * + * @return The host's IP address, PJ_INADDR_NONE if the host + * IP address can not be identified. + */ +PJ_DECL(pj_in_addr) pj_gethostaddr(void); + + +/***************************************************************************** + * + * SOCKET API. + * + ***************************************************************************** + */ + +/** + * Create new socket/endpoint for communication. + * + * @param family Specifies a communication domain; this selects the + * protocol family which will be used for communication. + * @param type The socket has the indicated type, which specifies the + * communication semantics. + * @param protocol Specifies a particular protocol to be used with the + * socket. Normally only a single protocol exists to support + * a particular socket type within a given protocol family, + * in which a case protocol can be specified as 0. + * @param sock New socket descriptor, or PJ_INVALID_SOCKET on error. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pj_sock_socket(int family, + int type, + int protocol, + pj_sock_t *sock); + +/** + * Close the socket descriptor. + * + * @param sockfd The socket descriptor. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pj_sock_close(pj_sock_t sockfd); + + +/** + * This function gives the socket sockfd the local address my_addr. my_addr is + * addrlen bytes long. Traditionally, this is called assigning a name to + * a socket. When a socket is created with #pj_sock_socket(), it exists in a + * name space (address family) but has no name assigned. + * + * @param sockfd The socket desriptor. + * @param my_addr The local address to bind the socket to. + * @param addrlen The length of the address. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pj_sock_bind( pj_sock_t sockfd, + const pj_sockaddr_t *my_addr, + int addrlen); + +/** + * Bind the IP socket sockfd to the given address and port. + * + * @param sockfd The socket descriptor. + * @param addr Local address to bind the socket to, in host byte order. + * @param port The local port to bind the socket to, in host byte order. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pj_sock_bind_in( pj_sock_t sockfd, + pj_uint32_t addr, + pj_uint16_t port); + +#if PJ_HAS_TCP +/** + * Listen for incoming connection. This function only applies to connection + * oriented sockets (such as PJ_SOCK_STREAM or PJ_SOCK_SEQPACKET), and it + * indicates the willingness to accept incoming connections. + * + * @param sockfd The socket descriptor. + * @param backlog Defines the maximum length the queue of pending + * connections may grow to. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pj_sock_listen( pj_sock_t sockfd, + int backlog ); + +/** + * Accept new connection on the specified connection oriented server socket. + * + * @param serverfd The server socket. + * @param newsock New socket on success, of PJ_INVALID_SOCKET if failed. + * @param addr A pointer to sockaddr type. If the argument is not NULL, + * it will be filled by the address of connecting entity. + * @param addrlen Initially specifies the length of the address, and upon + * return will be filled with the exact address length. + * + * @return Zero on success, or the error number. + */ +PJ_DECL(pj_status_t) pj_sock_accept( pj_sock_t serverfd, + pj_sock_t *newsock, + pj_sockaddr_t *addr, + int *addrlen); +#endif + +/** + * The file descriptor sockfd must refer to a socket. If the socket is of + * type PJ_SOCK_DGRAM then the serv_addr address is the address to which + * datagrams are sent by default, and the only address from which datagrams + * are received. If the socket is of type PJ_SOCK_STREAM or PJ_SOCK_SEQPACKET, + * this call attempts to make a connection to another socket. The + * other socket is specified by serv_addr, which is an address (of length + * addrlen) in the communications space of the socket. Each communications + * space interprets the serv_addr parameter in its own way. + * + * @param sockfd The socket descriptor. + * @param serv_addr Server address to connect to. + * @param addrlen The length of server address. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pj_sock_connect( pj_sock_t sockfd, + const pj_sockaddr_t *serv_addr, + int addrlen); + +/** + * Return the address of peer which is connected to socket sockfd. + * + * @param sockfd The socket descriptor. + * @param addr Pointer to sockaddr structure to which the address + * will be returned. + * @param namelen Initially the length of the addr. Upon return the value + * will be set to the actual length of the address. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pj_sock_getpeername(pj_sock_t sockfd, + pj_sockaddr_t *addr, + int *namelen); + +/** + * Return the current name of the specified socket. + * + * @param sockfd The socket descriptor. + * @param addr Pointer to sockaddr structure to which the address + * will be returned. + * @param namelen Initially the length of the addr. Upon return the value + * will be set to the actual length of the address. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pj_sock_getsockname( pj_sock_t sockfd, + pj_sockaddr_t *addr, + int *namelen); + +/** + * Get socket option associated with a socket. Options may exist at multiple + * protocol levels; they are always present at the uppermost socket level. + * + * @param sockfd The socket descriptor. + * @param level The level which to get the option from. + * @param optname The option name. + * @param optval Identifies the buffer which the value will be + * returned. + * @param optlen Initially contains the length of the buffer, upon + * return will be set to the actual size of the value. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pj_sock_getsockopt( pj_sock_t sockfd, + pj_uint16_t level, + pj_uint16_t optname, + void *optval, + int *optlen); +/** + * Manipulate the options associated with a socket. Options may exist at + * multiple protocol levels; they are always present at the uppermost socket + * level. + * + * @param sockfd The socket descriptor. + * @param level The level which to get the option from. + * @param optname The option name. + * @param optval Identifies the buffer which contain the value. + * @param optlen The length of the value. + * + * @return PJ_SUCCESS or the status code. + */ +PJ_DECL(pj_status_t) pj_sock_setsockopt( pj_sock_t sockfd, + pj_uint16_t level, + pj_uint16_t optname, + const void *optval, + int optlen); + + +/** + * Receives data stream or message coming to the specified socket. + * + * @param sockfd The socket descriptor. + * @param buf The buffer to receive the data or message. + * @param len On input, the length of the buffer. On return, + * contains the length of data received. + * @param flags Flags (such as pj_MSG_PEEK()). + * + * @return PJ_SUCCESS or the error code. + */ +PJ_DECL(pj_status_t) pj_sock_recv(pj_sock_t sockfd, + void *buf, + pj_ssize_t *len, + unsigned flags); + +/** + * Receives data stream or message coming to the specified socket. + * + * @param sockfd The socket descriptor. + * @param buf The buffer to receive the data or message. + * @param len On input, the length of the buffer. On return, + * contains the length of data received. + * @param flags Flags (such as pj_MSG_PEEK()). + * @param from If not NULL, it will be filled with the source + * address of the connection. + * @param fromlen Initially contains the length of from address, + * and upon return will be filled with the actual + * length of the address. + * + * @return PJ_SUCCESS or the error code. + */ +PJ_DECL(pj_status_t) pj_sock_recvfrom( pj_sock_t sockfd, + void *buf, + pj_ssize_t *len, + unsigned flags, + pj_sockaddr_t *from, + int *fromlen); + +/** + * Transmit data to the socket. + * + * @param sockfd Socket descriptor. + * @param buf Buffer containing data to be sent. + * @param len On input, the length of the data in the buffer. + * Upon return, it will be filled with the length + * of data sent. + * @param flags Flags (such as pj_MSG_DONTROUTE()). + * + * @return PJ_SUCCESS or the status code. + */ +PJ_DECL(pj_status_t) pj_sock_send(pj_sock_t sockfd, + const void *buf, + pj_ssize_t *len, + unsigned flags); + +/** + * Transmit data to the socket to the specified address. + * + * @param sockfd Socket descriptor. + * @param buf Buffer containing data to be sent. + * @param len On input, the length of the data in the buffer. + * Upon return, it will be filled with the length + * of data sent. + * @param flags Flags (such as pj_MSG_DONTROUTE()). + * @param to The address to send. + * @param tolen The length of the address in bytes. + * + * @return PJ_SUCCESS or the status code. + */ +PJ_DECL(pj_status_t) pj_sock_sendto(pj_sock_t sockfd, + const void *buf, + pj_ssize_t *len, + unsigned flags, + const pj_sockaddr_t *to, + int tolen); + +#if PJ_HAS_TCP +/** + * The shutdown call causes all or part of a full-duplex connection on the + * socket associated with sockfd to be shut down. + * + * @param sockfd The socket descriptor. + * @param how If how is PJ_SHUT_RD, further receptions will be + * disallowed. If how is PJ_SHUT_WR, further transmissions + * will be disallowed. If how is PJ_SHUT_RDWR, further + * receptions andtransmissions will be disallowed. + * + * @return Zero on success. + */ +PJ_DECL(pj_status_t) pj_sock_shutdown( pj_sock_t sockfd, + int how); +#endif + +/** + * @} + */ + + +PJ_END_DECL + +#endif /* __PJ_SOCK_H__ */ + diff --git a/pjlib/include/pj/sock_qos.h b/pjlib/include/pj/sock_qos.h new file mode 100644 index 0000000..fbd9afd --- /dev/null +++ b/pjlib/include/pj/sock_qos.h @@ -0,0 +1,427 @@ +/* $Id: sock_qos.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 + * + * 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_SOCK_QOS_H__ +#define __PJ_SOCK_QOS_H__ + +/** + * @file sock_qos.h + * @brief Socket QoS API + */ + +#include + +PJ_BEGIN_DECL + + +/** + * @defgroup socket_qos Socket Quality of Service (QoS) API: TOS, DSCP, WMM, IEEE 802.1p + * @ingroup PJ_SOCK + * @{ + + + \section intro QoS Technologies + + QoS settings are available for both Layer 2 and 3 of TCP/IP protocols: + + \subsection intro_ieee8021p Layer 2: IEEE 802.1p for Ethernet + + IEEE 802.1p tagging will mark frames sent by a host for prioritized + delivery using a 3-bit Priority field in the virtual local area network + (VLAN) header of the Ethernet frame. The VLAN header is placed inside + the Ethernet header, between the Source Address field and either the + Length field (for an IEEE 802.3 frame) or the EtherType field (for an + Ethernet II frame). + + \subsection intro_wmm Layer 2: WMM + + At the Network Interface layer for IEEE 802.11 wireless, the Wi-Fi + Alliance certification for Wi-Fi Multimedia (WMM) defines four access + categories for prioritizing network traffic. These access categories + are (in order of highest to lowest priority) voice, video, best-effort, + and background. Host support for WMM prioritization requires that both + wireless network adapters and their drivers support WMM. Wireless + access points (APs) must have WMM enabled. + + \subsection intro_dscp Layer 3: DSCP + + At the Internet layer, you can use Differentiated Services/Diffserv and + set the value of the Differentiated Services Code Point (DSCP) in the + IP header. As defined in RFC 2474, the DSCP value is the high-order 6 bits + of the IP version 4 (IPv4) TOS field and the IP version 6 (IPv6) Traffic + Class field. + + \subsection intro_other Layer 3: Other + + Other mechanisms exist (such as RSVP, IntServ) but this will not be + implemented. + + + \section availability QoS Availability + + \subsection linux Linux + + DSCP is available via IP TOS option. + + Ethernet 802.1p tagging is done by setting setsockopt(SO_PRIORITY) option + of the socket, then with the set_egress_map option of the vconfig utility + to convert this to set vlan-qos field of the packet. + + WMM is not known to be available. + + \subsection windows Windows and Windows Mobile + + (It's a mess!) + + DSCP is settable with setsockopt() on Windows 2000 or older, but Windows + would silently ignore this call on WinXP or later, unless administrator + modifies the registry. On Windows 2000, Windows XP, and Windows Server + 2003, GQoS (Generic QoS) API is the standard API, but this API may not be + supported in the future. On Vista and Windows 7, the is a new QoS2 API, + also known as Quality Windows Audio-Video Experience (qWAVE). + + IEEE 802.1p tagging is available via Traffic Control (TC) API, available + on Windows XP SP2, but this needs administrator access. For Vista and + later, it's in qWAVE. + + WMM is available for mobile platforms on Windows Mobile 6 platform and + Windows Embedded CE 6, via setsockopt(IP_DSCP_TRAFFIC_TYPE). qWAVE + supports this as well. + + \subsection symbian Symbian S60 3rd Ed + + Both DSCP and WMM is supported via RSocket::SetOpt() with will set both + Layer 2 and Layer 3 QoS settings accordingly. Internally, PJLIB sets the + DSCP field of the socket, and based on certain DSCP values mapping, + Symbian will set the WMM tag accordingly. + + \section api PJLIB's QoS API Abstraction + + Based on the above, the following API is implemented. + + Declare the following "standard" traffic types. + + \code + typedef enum pj_qos_type + { + PJ_QOS_TYPE_BEST_EFFORT, + PJ_QOS_TYPE_BACKGROUND, + PJ_QOS_TYPE_VIDEO, + PJ_QOS_TYPE_VOICE, + PJ_QOS_TYPE_CONTROL + } pj_qos_type; + \endcode + + The traffic classes above will determine how the Layer 2 and 3 QoS + settings will be used. The standard mapping between the classes above + to the corresponding Layer 2 and 3 settings are as follows: + + \code + ================================================================= + PJLIB Traffic Type IP DSCP WMM 802.1p + ----------------------------------------------------------------- + BEST_EFFORT 0x00 BE (Bulk Effort) 0 + BACKGROUND 0x08 BK (Bulk) 2 + VIDEO 0x28 VI (Video) 5 + VOICE 0x30 VO (Voice) 6 + CONTROL 0x38 VO (Voice) 7 + ================================================================= + \endcode + + There are two sets of API provided to manipulate the QoS parameters. + + \subsection portable_api Portable API + + The first set of API is: + + \code + // Set QoS parameters + PJ_DECL(pj_status_t) pj_sock_set_qos_type(pj_sock_t sock, + pj_qos_type val); + + // Get QoS parameters + PJ_DECL(pj_status_t) pj_sock_get_qos_type(pj_sock_t sock, + pj_qos_type *p_val); + \endcode + + The API will set the traffic type according to the DSCP class, for both + Layer 2 and Layer 3 QoS settings, where it's available. If any of the + layer QoS setting is not settable, the API will silently ignore it. + If both layers are not setable, the API will return error. + + The API above is the recommended use of QoS, since it is the most + portable across all platforms. + + \subsection detail_api Fine Grained Control API + + The second set of API is intended for application that wants to fine + tune the QoS parameters. + + The Layer 2 and 3 QoS parameters are stored in pj_qos_params structure: + + \code + typedef enum pj_qos_flag + { + PJ_QOS_PARAM_HAS_DSCP = 1, + PJ_QOS_PARAM_HAS_SO_PRIO = 2, + PJ_QOS_PARAM_HAS_WMM = 4 + } pj_qos_flag; + + typedef enum pj_qos_wmm_prio + { + PJ_QOS_WMM_PRIO_BULK_EFFORT, + PJ_QOS_WMM_PRIO_BULK, + PJ_QOS_WMM_PRIO_VIDEO, + PJ_QOS_WMM_PRIO_VOICE + } pj_qos_wmm_prio; + + typedef struct pj_qos_params + { + pj_uint8_t flags; // Determines which values to + // set, bitmask of pj_qos_flag + pj_uint8_t dscp_val; // The 6 bits DSCP value to set + pj_uint8_t so_prio; // SO_PRIORITY value + pj_qos_wmm_prio wmm_prio; // WMM priority value + } pj_qos_params; + \endcode + + The second set of API with more fine-grained control over the parameters + are: + + \code + // Retrieve QoS params for the specified traffic type + PJ_DECL(pj_status_t) pj_qos_get_params(pj_qos_type type, + pj_qos_params *p); + + // Set QoS parameters to the socket + PJ_DECL(pj_status_t) pj_sock_set_qos_params(pj_sock_t sock, + const pj_qos_params *p); + + // Get QoS parameters from the socket + PJ_DECL(pj_status_t) pj_sock_get_qos_params(pj_sock_t sock, + pj_qos_params *p); + \endcode + + + Important: + + The pj_sock_set/get_qos_params() APIs are not portable, and it's probably + only going to be implemented on Linux. Application should always try to + use pj_sock_set_qos_type() instead. + */ + + +/** + * High level traffic classification. + */ +typedef enum pj_qos_type +{ + PJ_QOS_TYPE_BEST_EFFORT, /**< Best effort traffic (default value). + Any QoS function calls with specifying + this value are effectively no-op */ + PJ_QOS_TYPE_BACKGROUND, /**< Background traffic. */ + PJ_QOS_TYPE_VIDEO, /**< Video traffic. */ + PJ_QOS_TYPE_VOICE, /**< Voice traffic. */ + PJ_QOS_TYPE_CONTROL /**< Control traffic. */ +} pj_qos_type; + +/** + * Bitmask flag to indicate which QoS layer setting is set in the + * \a flags field of the #pj_qos_params structure. + */ +typedef enum pj_qos_flag +{ + PJ_QOS_PARAM_HAS_DSCP = 1, /**< DSCP field is set. */ + PJ_QOS_PARAM_HAS_SO_PRIO = 2, /**< Socket SO_PRIORITY */ + PJ_QOS_PARAM_HAS_WMM = 4 /**< WMM field is set. */ +} pj_qos_flag; + + +/** + * Standard WMM priorities. + */ +typedef enum pj_qos_wmm_prio +{ + PJ_QOS_WMM_PRIO_BULK_EFFORT, /**< Bulk effort priority */ + PJ_QOS_WMM_PRIO_BULK, /**< Bulk priority. */ + PJ_QOS_WMM_PRIO_VIDEO, /**< Video priority */ + PJ_QOS_WMM_PRIO_VOICE /**< Voice priority */ +} pj_qos_wmm_prio; + + +/** + * QoS parameters to be set or retrieved to/from the socket. + */ +typedef struct pj_qos_params +{ + pj_uint8_t flags; /**< Determines which values to + set, bitmask of pj_qos_flag */ + pj_uint8_t dscp_val; /**< The 6 bits DSCP value to set */ + pj_uint8_t so_prio; /**< SO_PRIORITY value */ + pj_qos_wmm_prio wmm_prio; /**< WMM priority value */ +} pj_qos_params; + + + +/** + * This is the high level and portable API to enable QoS on the specified + * socket, by setting the traffic type to the specified parameter. + * + * @param sock The socket. + * @param type Traffic type to be set. + * + * @return PJ_SUCCESS if at least Layer 2 or Layer 3 setting is + * successfully set. If both Layer 2 and Layer 3 settings + * can't be set, this function will return error. + */ +PJ_DECL(pj_status_t) pj_sock_set_qos_type(pj_sock_t sock, + pj_qos_type type); + +/** + * This is the high level and portable API to get the traffic type that has + * been set on the socket. On occasions where the Layer 2 or Layer 3 settings + * were modified by using low level API, this function may return approximation + * of the closest QoS type that matches the settings. + * + * @param sock The socket. + * @param p_type Pointer to receive the traffic type of the socket. + * + * @return PJ_SUCCESS if traffic type for the socket can be obtained + * or approximated.. + */ +PJ_DECL(pj_status_t) pj_sock_get_qos_type(pj_sock_t sock, + pj_qos_type *p_type); + + +/** + * This is a convenience function to apply QoS to the socket, and print error + * logging if the operations failed. Both QoS traffic type and the low level + * QoS parameters can be applied with this function. + * + * @param sock The socket handle. + * @param qos_type QoS traffic type. The QoS traffic type will be applied + * only if the value is not PJ_QOS_TYPE_BEST_EFFORT, + * @param qos_params Optional low-level QoS parameters. This will be + * applied only if this argument is not NULL and the + * flags inside the structure is non-zero. Upon return, + * the flags will indicate which parameters have been + * applied successfully. + * @param log_level This function will print to log at this level upon + * encountering errors. + * @param log_sender Optional sender name in the log. + * @param sock_name Optional name to help identify the socket in the log. + * + * @return PJ_SUCCESS if at least Layer 2 or Layer 3 setting is + * successfully set. If both Layer 2 and Layer 3 settings + * can't be set, this function will return error. + * + * @see pj_sock_apply_qos2() + */ +PJ_DECL(pj_status_t) pj_sock_apply_qos(pj_sock_t sock, + pj_qos_type qos_type, + pj_qos_params *qos_params, + unsigned log_level, + const char *log_sender, + const char *sock_name); + +/** + * Variant of #pj_sock_apply_qos() where the \a qos_params parameter is + * const. + * + * @see pj_sock_apply_qos() + */ +PJ_DECL(pj_status_t) pj_sock_apply_qos2(pj_sock_t sock, + pj_qos_type qos_type, + const pj_qos_params *qos_params, + unsigned log_level, + const char *log_sender, + const char *sock_name); + +/** + * Retrieve the standard mapping of QoS params for the specified traffic + * type. + * + * @param type The traffic type from which the QoS parameters + * are to be retrieved. + * @param p_param Pointer to receive the QoS parameters. + * + * @return PJ_SUCCESS on success or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_qos_get_params(pj_qos_type type, + pj_qos_params *p_param); + + +/** + * Retrieve the traffic type that matches the specified QoS parameters. + * If no exact matching is found, this function will return an + * approximation of the closest matching traffic type for the specified + * QoS parameters. + * + * @param param Structure containing QoS parameters to map into + * "standard" traffic types. + * @param p_type Pointer to receive the traffic type. + * + * @return PJ_SUCCESS on success or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_qos_get_type(const pj_qos_params *param, + pj_qos_type *p_type); + + +/** + * This is a low level API to set QoS parameters to the socket. + * + * @param sock The socket. + * @param param Structure containing QoS parameters to be applied + * to the socket. Upon return, the \a flags field + * of this structure will be set with bitmask value + * indicating which QoS settings have successfully + * been applied to the socket. + * + * @return PJ_SUCCESS if at least one field setting has been + * successfully set. If no setting can't be set, + * this function will return error. + */ +PJ_DECL(pj_status_t) pj_sock_set_qos_params(pj_sock_t sock, + pj_qos_params *param); + +/** + * This is a low level API to get QoS parameters from the socket. + * + * @param sock The socket. + * @param p_param Pointer to receive the parameters. Upon returning + * successfully, the \a flags field of this structure + * will be initialized with the appropriate bitmask + * to indicate which fields have been successfully + * retrieved. + * + * @return PJ_SUCCESS on success or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_sock_get_qos_params(pj_sock_t sock, + pj_qos_params *p_param); + + +/** + * @} + */ + + +PJ_END_DECL + +#endif /* __PJ_SOCK_QOS_H__ */ + diff --git a/pjlib/include/pj/sock_select.h b/pjlib/include/pj/sock_select.h new file mode 100644 index 0000000..dc39db1 --- /dev/null +++ b/pjlib/include/pj/sock_select.h @@ -0,0 +1,152 @@ +/* $Id: sock_select.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 + * + * 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_SELECT_H__ +#define __PJ_SELECT_H__ + +/** + * @file sock_select.h + * @brief Socket select(). + */ + +#include + +PJ_BEGIN_DECL + +/** + * @defgroup PJ_SOCK_SELECT Socket select() API. + * @ingroup PJ_IO + * @{ + * This module provides portable abstraction for \a select() like API. + * The abstraction is needed so that it can utilize various event + * dispatching mechanisms that are available across platforms. + * + * The API is very similar to normal \a select() usage. + * + * \section pj_sock_select_examples_sec Examples + * + * For some examples on how to use the select API, please see: + * + * - \ref page_pjlib_select_test + */ + +/** + * Portable structure declarations for pj_fd_set. + * The implementation of pj_sock_select() does not use this structure + * per-se, but instead it will use the native fd_set structure. However, + * we must make sure that the size of pj_fd_set_t can accomodate the + * native fd_set structure. + */ +typedef struct pj_fd_set_t +{ + pj_sock_t data[PJ_IOQUEUE_MAX_HANDLES+ 4]; /**< Opaque buffer for fd_set */ +} pj_fd_set_t; + + +/** + * Initialize the descriptor set pointed to by fdsetp to the null set. + * + * @param fdsetp The descriptor set. + */ +PJ_DECL(void) PJ_FD_ZERO(pj_fd_set_t *fdsetp); + + +/** + * This is an internal function, application shouldn't use this. + * + * Get the number of descriptors in the set. This is defined in sock_select.c + * This function will only return the number of sockets set from PJ_FD_SET + * operation. When the set is modified by other means (such as by select()), + * the count will not be reflected here. + * + * @param fdsetp The descriptor set. + * + * @return Number of descriptors in the set. + */ +PJ_DECL(pj_size_t) PJ_FD_COUNT(const pj_fd_set_t *fdsetp); + + +/** + * Add the file descriptor fd to the set pointed to by fdsetp. + * If the file descriptor fd is already in this set, there shall be no effect + * on the set, nor will an error be returned. + * + * @param fd The socket descriptor. + * @param fdsetp The descriptor set. + */ +PJ_DECL(void) PJ_FD_SET(pj_sock_t fd, pj_fd_set_t *fdsetp); + +/** + * Remove the file descriptor fd from the set pointed to by fdsetp. + * If fd is not a member of this set, there shall be no effect on the set, + * nor will an error be returned. + * + * @param fd The socket descriptor. + * @param fdsetp The descriptor set. + */ +PJ_DECL(void) PJ_FD_CLR(pj_sock_t fd, pj_fd_set_t *fdsetp); + + +/** + * Evaluate to non-zero if the file descriptor fd is a member of the set + * pointed to by fdsetp, and shall evaluate to zero otherwise. + * + * @param fd The socket descriptor. + * @param fdsetp The descriptor set. + * + * @return Nonzero if fd is member of the descriptor set. + */ +PJ_DECL(pj_bool_t) PJ_FD_ISSET(pj_sock_t fd, const pj_fd_set_t *fdsetp); + + +/** + * This function wait for a number of file descriptors to change status. + * The behaviour is the same as select() function call which appear in + * standard BSD socket libraries. + * + * @param n On Unices, this specifies the highest-numbered + * descriptor in any of the three set, plus 1. On Windows, + * the value is ignored. + * @param readfds Optional pointer to a set of sockets to be checked for + * readability. + * @param writefds Optional pointer to a set of sockets to be checked for + * writability. + * @param exceptfds Optional pointer to a set of sockets to be checked for + * errors. + * @param timeout Maximum time for select to wait, or null for blocking + * operations. + * + * @return The total number of socket handles that are ready, or + * zero if the time limit expired, or -1 if an error occurred. + */ +PJ_DECL(int) pj_sock_select( int n, + pj_fd_set_t *readfds, + pj_fd_set_t *writefds, + pj_fd_set_t *exceptfds, + const pj_time_val *timeout); + + +/** + * @} + */ + + +PJ_END_DECL + +#endif /* __PJ_SELECT_H__ */ diff --git a/pjlib/include/pj/ssl_sock.h b/pjlib/include/pj/ssl_sock.h new file mode 100644 index 0000000..a81b7d9 --- /dev/null +++ b/pjlib/include/pj/ssl_sock.h @@ -0,0 +1,1051 @@ +/* $Id: ssl_sock.h 4146 2012-05-30 06:35:59Z nanang $ */ +/* + * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com) + * + * 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_SSL_SOCK_H__ +#define __PJ_SSL_SOCK_H__ + +/** + * @file ssl_sock.h + * @brief Secure socket + */ + +#include +#include +#include + + +PJ_BEGIN_DECL + +/** + * @defgroup PJ_SSL_SOCK Secure socket I/O + * @brief Secure socket provides security on socket operation using standard + * security protocols such as SSL and TLS. + * @ingroup PJ_IO + * @{ + * + * Secure socket wraps normal socket and applies security features, i.e: + * privacy and data integrity, on the socket traffic, using standard security + * protocols such as SSL and TLS. + * + * Secure socket employs active socket operations, which is similar to (and + * described more detail) in \ref PJ_ACTIVESOCK. + */ + + + /** + * This opaque structure describes the secure socket. + */ +typedef struct pj_ssl_sock_t pj_ssl_sock_t; + + +/** + * Opaque declaration of endpoint certificate or credentials. This may contains + * certificate, private key, and trusted Certificate Authorities list. + */ +typedef struct pj_ssl_cert_t pj_ssl_cert_t; + + +typedef enum pj_ssl_cert_verify_flag_t +{ + /** + * No error in verification. + */ + PJ_SSL_CERT_ESUCCESS = 0, + + /** + * The issuer certificate cannot be found. + */ + PJ_SSL_CERT_EISSUER_NOT_FOUND = (1 << 0), + + /** + * The certificate is untrusted. + */ + PJ_SSL_CERT_EUNTRUSTED = (1 << 1), + + /** + * The certificate has expired or not yet valid. + */ + PJ_SSL_CERT_EVALIDITY_PERIOD = (1 << 2), + + /** + * One or more fields of the certificate cannot be decoded due to + * invalid format. + */ + PJ_SSL_CERT_EINVALID_FORMAT = (1 << 3), + + /** + * The certificate cannot be used for the specified purpose. + */ + PJ_SSL_CERT_EINVALID_PURPOSE = (1 << 4), + + /** + * The issuer info in the certificate does not match to the (candidate) + * issuer certificate, e.g: issuer name not match to subject name + * of (candidate) issuer certificate. + */ + PJ_SSL_CERT_EISSUER_MISMATCH = (1 << 5), + + /** + * The CRL certificate cannot be found or cannot be read properly. + */ + PJ_SSL_CERT_ECRL_FAILURE = (1 << 6), + + /** + * The certificate has been revoked. + */ + PJ_SSL_CERT_EREVOKED = (1 << 7), + + /** + * The certificate chain length is too long. + */ + PJ_SSL_CERT_ECHAIN_TOO_LONG = (1 << 8), + + /** + * The server identity does not match to any identities specified in + * the certificate, e.g: subjectAltName extension, subject common name. + * This flag will only be set by application as SSL socket does not + * perform server identity verification. + */ + PJ_SSL_CERT_EIDENTITY_NOT_MATCH = (1 << 30), + + /** + * Unknown verification error. + */ + PJ_SSL_CERT_EUNKNOWN = (1 << 31) + +} pj_ssl_cert_verify_flag_t; + + +typedef enum pj_ssl_cert_name_type +{ + PJ_SSL_CERT_NAME_UNKNOWN = 0, + PJ_SSL_CERT_NAME_RFC822, + PJ_SSL_CERT_NAME_DNS, + PJ_SSL_CERT_NAME_URI, + PJ_SSL_CERT_NAME_IP +} pj_ssl_cert_name_type; + +/** + * Describe structure of certificate info. + */ +typedef struct pj_ssl_cert_info { + + unsigned version; /**< Certificate version */ + + pj_uint8_t serial_no[20]; /**< Serial number, array of + octets, first index is + MSB */ + + struct { + pj_str_t cn; /**< Common name */ + pj_str_t info; /**< One line subject, fields + are separated by slash, e.g: + "CN=sample.org/OU=HRD" */ + } subject; /**< Subject */ + + struct { + pj_str_t cn; /**< Common name */ + pj_str_t info; /**< One line subject, fields + are separated by slash.*/ + } issuer; /**< Issuer */ + + struct { + pj_time_val start; /**< Validity start */ + pj_time_val end; /**< Validity end */ + pj_bool_t gmt; /**< Flag if validity date/time + use GMT */ + } validity; /**< Validity */ + + struct { + unsigned cnt; /**< # of entry */ + struct { + pj_ssl_cert_name_type type; + /**< Name type */ + pj_str_t name; /**< The name */ + } *entry; /**< Subject alt name entry */ + } subj_alt_name; /**< Subject alternative + name extension */ + +} pj_ssl_cert_info; + + +/** + * Create credential from files. + * + * @param CA_file The file of trusted CA list. + * @param cert_file The file of certificate. + * @param privkey_file The file of private key. + * @param privkey_pass The password of private key, if any. + * @param p_cert Pointer to credential instance to be created. + * + * @return PJ_SUCCESS when successful. + */ +PJ_DECL(pj_status_t) pj_ssl_cert_load_from_files(pj_pool_t *pool, + const pj_str_t *CA_file, + const pj_str_t *cert_file, + const pj_str_t *privkey_file, + const pj_str_t *privkey_pass, + pj_ssl_cert_t **p_cert); + + +/** + * Dump SSL certificate info. + * + * @param ci The certificate info. + * @param indent String for left indentation. + * @param buf The buffer where certificate info will be printed on. + * @param buf_size The buffer size. + * + * @return The length of the dump result, or -1 when buffer size + * is not sufficient. + */ +PJ_DECL(pj_ssize_t) pj_ssl_cert_info_dump(const pj_ssl_cert_info *ci, + const char *indent, + char *buf, + pj_size_t buf_size); + + +/** + * Get SSL certificate verification error messages from verification status. + * + * @param verify_status The SSL certificate verification status. + * @param error_strings Array of strings to receive the verification error + * messages. + * @param count On input it specifies maximum error messages should be + * retrieved. On output it specifies the number of error + * messages retrieved. + * + * @return PJ_SUCCESS when successful. + */ +PJ_DECL(pj_status_t) pj_ssl_cert_get_verify_status_strings( + pj_uint32_t verify_status, + const char *error_strings[], + unsigned *count); + + +/** + * Cipher suites enumeration. + */ +typedef enum pj_ssl_cipher { + + /* NULL */ + PJ_TLS_NULL_WITH_NULL_NULL = 0x00000000, + + /* TLS/SSLv3 */ + PJ_TLS_RSA_WITH_NULL_MD5 = 0x00000001, + PJ_TLS_RSA_WITH_NULL_SHA = 0x00000002, + PJ_TLS_RSA_WITH_NULL_SHA256 = 0x0000003B, + PJ_TLS_RSA_WITH_RC4_128_MD5 = 0x00000004, + PJ_TLS_RSA_WITH_RC4_128_SHA = 0x00000005, + PJ_TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x0000000A, + PJ_TLS_RSA_WITH_AES_128_CBC_SHA = 0x0000002F, + PJ_TLS_RSA_WITH_AES_256_CBC_SHA = 0x00000035, + PJ_TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x0000003C, + PJ_TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x0000003D, + PJ_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x0000000D, + PJ_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x00000010, + PJ_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x00000013, + PJ_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x00000016, + PJ_TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x00000030, + PJ_TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0x00000031, + PJ_TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x00000032, + PJ_TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x00000033, + PJ_TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0x00000036, + PJ_TLS_DH_RSA_WITH_AES_256_CBC_SHA = 0x00000037, + PJ_TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x00000038, + PJ_TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x00000039, + PJ_TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = 0x0000003E, + PJ_TLS_DH_RSA_WITH_AES_128_CBC_SHA256 = 0x0000003F, + PJ_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x00000040, + PJ_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x00000067, + PJ_TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = 0x00000068, + PJ_TLS_DH_RSA_WITH_AES_256_CBC_SHA256 = 0x00000069, + PJ_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x0000006A, + PJ_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x0000006B, + PJ_TLS_DH_anon_WITH_RC4_128_MD5 = 0x00000018, + PJ_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = 0x0000001B, + PJ_TLS_DH_anon_WITH_AES_128_CBC_SHA = 0x00000034, + PJ_TLS_DH_anon_WITH_AES_256_CBC_SHA = 0x0000003A, + PJ_TLS_DH_anon_WITH_AES_128_CBC_SHA256 = 0x0000006C, + PJ_TLS_DH_anon_WITH_AES_256_CBC_SHA256 = 0x0000006D, + + /* TLS (deprecated) */ + PJ_TLS_RSA_EXPORT_WITH_RC4_40_MD5 = 0x00000003, + PJ_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = 0x00000006, + PJ_TLS_RSA_WITH_IDEA_CBC_SHA = 0x00000007, + PJ_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x00000008, + PJ_TLS_RSA_WITH_DES_CBC_SHA = 0x00000009, + PJ_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x0000000B, + PJ_TLS_DH_DSS_WITH_DES_CBC_SHA = 0x0000000C, + PJ_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0000000E, + PJ_TLS_DH_RSA_WITH_DES_CBC_SHA = 0x0000000F, + PJ_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x00000011, + PJ_TLS_DHE_DSS_WITH_DES_CBC_SHA = 0x00000012, + PJ_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x00000014, + PJ_TLS_DHE_RSA_WITH_DES_CBC_SHA = 0x00000015, + PJ_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = 0x00000017, + PJ_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = 0x00000019, + PJ_TLS_DH_anon_WITH_DES_CBC_SHA = 0x0000001A, + + /* SSLv3 */ + PJ_SSL_FORTEZZA_KEA_WITH_NULL_SHA = 0x0000001C, + PJ_SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA = 0x0000001D, + PJ_SSL_FORTEZZA_KEA_WITH_RC4_128_SHA = 0x0000001E, + + /* SSLv2 */ + PJ_SSL_CK_RC4_128_WITH_MD5 = 0x00010080, + PJ_SSL_CK_RC4_128_EXPORT40_WITH_MD5 = 0x00020080, + PJ_SSL_CK_RC2_128_CBC_WITH_MD5 = 0x00030080, + PJ_SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 = 0x00040080, + PJ_SSL_CK_IDEA_128_CBC_WITH_MD5 = 0x00050080, + PJ_SSL_CK_DES_64_CBC_WITH_MD5 = 0x00060040, + PJ_SSL_CK_DES_192_EDE3_CBC_WITH_MD5 = 0x000700C0 + +} pj_ssl_cipher; + + +/** + * Get cipher list supported by SSL/TLS backend. + * + * @param ciphers The ciphers buffer to receive cipher list. + * @param cipher_num Maximum number of ciphers to be received. + * + * @return PJ_SUCCESS when successful. + */ +PJ_DECL(pj_status_t) pj_ssl_cipher_get_availables(pj_ssl_cipher ciphers[], + unsigned *cipher_num); + + +/** + * Check if the specified cipher is supported by SSL/TLS backend. + * + * @param cipher The cipher. + * + * @return PJ_TRUE when supported. + */ +PJ_DECL(pj_bool_t) pj_ssl_cipher_is_supported(pj_ssl_cipher cipher); + + +/** + * Get cipher name string. + * + * @param cipher The cipher. + * + * @return The cipher name or NULL if cipher is not recognized/ + * supported. + */ +PJ_DECL(const char*) pj_ssl_cipher_name(pj_ssl_cipher cipher); + + +/** + * Get cipher ID from cipher name string. + * + * @param cipher_name The cipher name string. + * + * @return The cipher ID or PJ_TLS_UNKNOWN_CIPHER if the cipher + * name string is not recognized/supported. + */ +PJ_DECL(pj_ssl_cipher) pj_ssl_cipher_id(const char *cipher_name); + + +/** + * This structure contains the callbacks to be called by the secure socket. + */ +typedef struct pj_ssl_sock_cb +{ + /** + * This callback is called when a data arrives as the result of + * pj_ssl_sock_start_read(). + * + * @param ssock The secure 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 secure socket in the + * callback and return PJ_FALSE here. + */ + pj_bool_t (*on_data_read)(pj_ssl_sock_t *ssock, + 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_ssl_sock_start_recvfrom(). + * + * @param ssock The secure 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 secure socket in the + * callback and return PJ_FALSE here. + */ + pj_bool_t (*on_data_recvfrom)(pj_ssl_sock_t *ssock, + 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 ssock The secure 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 secure socket in the + * callback and return PJ_FALSE here. + */ + pj_bool_t (*on_data_sent)(pj_ssl_sock_t *ssock, + pj_ioqueue_op_key_t *send_key, + pj_ssize_t sent); + + /** + * This callback is called when new connection arrives as the result + * of pj_ssl_sock_start_accept(). + * + * @param ssock The secure socket. + * @param newsock The new incoming secure 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 secure socket + * in the callback and return PJ_FALSE here. + */ + pj_bool_t (*on_accept_complete)(pj_ssl_sock_t *ssock, + pj_ssl_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 ssock The secure socket. + * @param status The connection result. If connection has been + * successfully established, the status will contain + * PJ_SUCCESS. + * + * @return Application may destroy the secure socket in the + * callback and return PJ_FALSE here. + */ + pj_bool_t (*on_connect_complete)(pj_ssl_sock_t *ssock, + pj_status_t status); + +} pj_ssl_sock_cb; + + +/** + * Enumeration of secure socket protocol types. + */ +typedef enum pj_ssl_sock_proto +{ + PJ_SSL_SOCK_PROTO_DEFAULT, /**< Default protocol of backend. */ + PJ_SSL_SOCK_PROTO_TLS1, /**< TLSv1.0 protocol. */ + PJ_SSL_SOCK_PROTO_SSL3, /**< SSLv3.0 protocol. */ + PJ_SSL_SOCK_PROTO_SSL23, /**< SSLv3.0 but can roll back to + SSLv2.0. */ + PJ_SSL_SOCK_PROTO_SSL2, /**< SSLv2.0 protocol. */ + PJ_SSL_SOCK_PROTO_DTLS1 /**< DTLSv1.0 protocol. */ +} pj_ssl_sock_proto; + + +/** + * Definition of secure socket info structure. + */ +typedef struct pj_ssl_sock_info +{ + /** + * Describes whether secure socket connection is established, i.e: TLS/SSL + * handshaking has been done successfully. + */ + pj_bool_t established; + + /** + * Describes secure socket protocol being used. + */ + pj_ssl_sock_proto proto; + + /** + * Describes cipher suite being used, this will only be set when connection + * is established. + */ + pj_ssl_cipher cipher; + + /** + * Describes local address. + */ + pj_sockaddr local_addr; + + /** + * Describes remote address. + */ + pj_sockaddr remote_addr; + + /** + * Describes active local certificate info. + */ + pj_ssl_cert_info *local_cert_info; + + /** + * Describes active remote certificate info. + */ + pj_ssl_cert_info *remote_cert_info; + + /** + * Status of peer certificate verification. + */ + pj_uint32_t verify_status; + + /** + * Last native error returned by the backend. + */ + unsigned long last_native_err; + +} pj_ssl_sock_info; + + +/** + * Definition of secure socket creation parameters. + */ +typedef struct pj_ssl_sock_param +{ + /** + * Specifies socket address family, either pj_AF_INET() and pj_AF_INET6(). + * + * Default is pj_AF_INET(). + */ + int sock_af; + + /** + * Specify socket type, either pj_SOCK_DGRAM() or pj_SOCK_STREAM(). + * + * Default is pj_SOCK_STREAM(). + */ + int sock_type; + + /** + * Specify the ioqueue to use. Secure socket uses the ioqueue to perform + * active socket operations, see \ref PJ_ACTIVESOCK for more detail. + */ + pj_ioqueue_t *ioqueue; + + /** + * Specify the timer heap to use. Secure socket uses the timer to provide + * auto cancelation on asynchronous operation when it takes longer time + * than specified timeout period, e.g: security negotiation timeout. + */ + pj_timer_heap_t *timer_heap; + + /** + * Specify secure socket callbacks, see #pj_ssl_sock_cb. + */ + pj_ssl_sock_cb cb; + + /** + * Specify secure socket user data. + */ + void *user_data; + + /** + * Specify security protocol to use, see #pj_ssl_sock_proto. + * + * Default is PJ_SSL_SOCK_PROTO_DEFAULT. + */ + pj_ssl_sock_proto proto; + + /** + * Number of concurrent asynchronous operations that is to be supported + * by the secure socket. This value only affects socket receive and + * accept operations -- the secure 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 secure socket will disable + * concurrency for the socket. When this value is +1, the secure socket + * will enable concurrency for the socket. + * + * The default value is -1. + */ + int concurrency; + + /** + * If this option is specified, the secure 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 + * secure 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; + + /** + * Specify buffer size for sending operation. Buffering sending data + * is used for allowing application to perform multiple outstanding + * send operations. Whenever application specifies this setting too + * small, sending operation may return PJ_ENOMEM. + * + * Default value is 8192 bytes. + */ + pj_size_t send_buffer_size; + + /** + * Specify buffer size for receiving encrypted (and perhaps compressed) + * data on underlying socket. This setting is unused on Symbian, since + * SSL/TLS Symbian backend, CSecureSocket, can use application buffer + * directly. + * + * Default value is 1500. + */ + pj_size_t read_buffer_size; + + /** + * Number of ciphers contained in the specified cipher preference. + * If this is set to zero, then default cipher list of the backend + * will be used. + */ + unsigned ciphers_num; + + /** + * Ciphers and order preference. If empty, then default cipher list and + * its default order of the backend will be used. + */ + pj_ssl_cipher *ciphers; + + /** + * Security negotiation timeout. If this is set to zero (both sec and + * msec), the negotiation doesn't have a timeout. + * + * Default value is zero. + */ + pj_time_val timeout; + + /** + * Specify whether endpoint should verify peer certificate. + * + * Default value is PJ_FALSE. + */ + pj_bool_t verify_peer; + + /** + * When secure socket is acting as server (handles incoming connection), + * it will require the client to provide certificate. + * + * Default value is PJ_FALSE. + */ + pj_bool_t require_client_cert; + + /** + * Server name indication. When secure socket is acting as client + * (perform outgoing connection) and the server may host multiple + * 'virtual' servers at a single underlying network address, setting + * this will allow client to tell the server a name of the server + * it is contacting. + * + * Default value is zero/not-set. + */ + pj_str_t server_name; + + /** + * QoS traffic type to be set on this transport. When application wants + * to apply QoS tagging to the transport, it's preferable to set this + * field rather than \a qos_param fields since this is more portable. + * + * Default value is PJ_QOS_TYPE_BEST_EFFORT. + */ + pj_qos_type qos_type; + + /** + * Set the low level QoS parameters to the transport. This is a lower + * level operation than setting the \a qos_type field and may not be + * supported on all platforms. + * + * By default all settings in this structure are disabled. + */ + pj_qos_params qos_params; + + /** + * Specify if the transport should ignore any errors when setting the QoS + * traffic type/parameters. + * + * Default: PJ_TRUE + */ + pj_bool_t qos_ignore_error; + + +} pj_ssl_sock_param; + + +/** + * Initialize the secure socket parameters for its creation with + * the default values. + * + * @param param The parameter to be initialized. + */ +PJ_DECL(void) pj_ssl_sock_param_default(pj_ssl_sock_param *param); + + +/** + * Create secure socket instance. + * + * @param pool The pool for allocating secure socket instance. + * @param param The secure socket parameter, see #pj_ssl_sock_param. + * @param p_ssock Pointer to secure socket instance to be created. + * + * @return PJ_SUCCESS when successful. + */ +PJ_DECL(pj_status_t) pj_ssl_sock_create(pj_pool_t *pool, + const pj_ssl_sock_param *param, + pj_ssl_sock_t **p_ssock); + + +/** + * Set secure socket certificate or credentials. Credentials may include + * certificate, private key and trusted Certification Authorities list. + * Normally, server socket must provide certificate (and private key). + * Socket client may also need to provide certificate in case requested + * by the server. + * + * @param ssock The secure socket instance. + * @param pool The pool. + * @param cert The endpoint certificate/credentials, see + * #pj_ssl_cert_t. + * + * @return PJ_SUCCESS if the operation has been successful, + * or the appropriate error code on failure. + */ +PJ_DECL(pj_status_t) pj_ssl_sock_set_certificate( + pj_ssl_sock_t *ssock, + pj_pool_t *pool, + const pj_ssl_cert_t *cert); + + +/** + * Close and destroy the secure socket. + * + * @param ssock The secure socket. + * + * @return PJ_SUCCESS if the operation has been successful, + * or the appropriate error code on failure. + */ +PJ_DECL(pj_status_t) pj_ssl_sock_close(pj_ssl_sock_t *ssock); + + +/** + * Associate arbitrary data with the secure socket. Application may + * inspect this data in the callbacks and associate it with higher + * level processing. + * + * @param ssock The secure socket. + * @param user_data The user data to be associated with the secure + * socket. + * + * @return PJ_SUCCESS if the operation has been successful, + * or the appropriate error code on failure. + */ +PJ_DECL(pj_status_t) pj_ssl_sock_set_user_data(pj_ssl_sock_t *ssock, + void *user_data); + +/** + * Retrieve the user data previously associated with this secure + * socket. + * + * @param ssock The secure socket. + * + * @return The user data. + */ +PJ_DECL(void*) pj_ssl_sock_get_user_data(pj_ssl_sock_t *ssock); + + +/** + * Retrieve the local address and port used by specified secure socket. + * + * @param ssock The secure socket. + * @param info The info buffer to be set, see #pj_ssl_sock_info. + * + * @return PJ_SUCCESS on successful. + */ +PJ_DECL(pj_status_t) pj_ssl_sock_get_info(pj_ssl_sock_t *ssock, + pj_ssl_sock_info *info); + + +/** + * Starts read operation on this secure socket. This function will create + * \a async_cnt number of buffers (the \a async_cnt parameter was given + * in \a pj_ssl_sock_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 + * secure socket when \a on_data_read() callback returns non-zero. + * + * @param ssock The secure 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_ssl_sock_start_read(pj_ssl_sock_t *ssock, + pj_pool_t *pool, + unsigned buff_size, + pj_uint32_t flags); + +/** + * Same as #pj_ssl_sock_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 ssock The secure 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_ssl_sock_start_read2(pj_ssl_sock_t *ssock, + pj_pool_t *pool, + unsigned buff_size, + void *readbuf[], + pj_uint32_t flags); + +/** + * Same as pj_ssl_sock_start_read(), except that this function is used + * only for datagram sockets, and it will trigger \a on_data_recvfrom() + * callback instead. + * + * @param ssock The secure 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_ssl_sock_start_recvfrom(pj_ssl_sock_t *ssock, + pj_pool_t *pool, + unsigned buff_size, + pj_uint32_t flags); + +/** + * Same as #pj_ssl_sock_start_recvfrom() except that the recvfrom() + * operation takes the buffer from the argument rather than creating + * new ones. + * + * @param ssock The secure 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_ssl_sock_start_recvfrom2(pj_ssl_sock_t *ssock, + pj_pool_t *pool, + unsigned buff_size, + void *readbuf[], + pj_uint32_t flags); + +/** + * Send data using the socket. + * + * @param ssock The secure 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 or + * PJ_ENOMEM when sending buffer could not handle all + * queued data, see \a send_buffer_size. The callback + * \a on_data_sent() will be called when data is actually + * sent. Any other return value indicates error condition. + */ +PJ_DECL(pj_status_t) pj_ssl_sock_send(pj_ssl_sock_t *ssock, + pj_ioqueue_op_key_t *send_key, + const void *data, + pj_ssize_t *size, + unsigned flags); + +/** + * Send datagram using the socket. + * + * @param ssock The secure 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 Length of buffer containing destination 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_ssl_sock_sendto(pj_ssl_sock_t *ssock, + pj_ioqueue_op_key_t *send_key, + const void *data, + pj_ssize_t *size, + unsigned flags, + const pj_sockaddr_t *addr, + int addr_len); + + +/** + * Starts asynchronous socket accept() operations on this secure socket. + * 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 secure socket when \a on_accept_complete() callback returns non-zero. + * + * @param ssock The secure socket. + * @param pool Pool used to allocate some internal data for the + * operation. + * @param localaddr Local address to bind on. + * @param addr_len Length of buffer containing local address. + * + * @return PJ_SUCCESS if the operation has been successful, + * or the appropriate error code on failure. + */ +PJ_DECL(pj_status_t) pj_ssl_sock_start_accept(pj_ssl_sock_t *ssock, + pj_pool_t *pool, + const pj_sockaddr_t *local_addr, + int addr_len); + + +/** + * Starts asynchronous socket connect() operation and SSL/TLS handshaking + * for this socket. Once the connection is done (either successfully or not), + * the \a on_connect_complete() callback will be called. + * + * @param ssock The secure socket. + * @param pool The pool to allocate some internal data for the + * operation. + * @param localaddr Local address. + * @param remaddr Remote address. + * @param addr_len Length of buffer containing above addresses. + * + * @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_ssl_sock_start_connect(pj_ssl_sock_t *ssock, + pj_pool_t *pool, + const pj_sockaddr_t *localaddr, + const pj_sockaddr_t *remaddr, + int addr_len); + + +/** + * Starts SSL/TLS renegotiation over an already established SSL connection + * for this socket. This operation is performed transparently, no callback + * will be called once the renegotiation completed successfully. However, + * when the renegotiation fails, the connection will be closed and callback + * \a on_data_read() will be invoked with non-PJ_SUCCESS status code. + * + * @param ssock The secure socket. + * + * @return PJ_SUCCESS if renegotiation is completed immediately, + * or PJ_EPENDING if renegotiation has been started and + * waiting for completion, or the appropriate error code + * on failure. + */ +PJ_DECL(pj_status_t) pj_ssl_sock_renegotiate(pj_ssl_sock_t *ssock); + + +/** + * @} + */ + +PJ_END_DECL + +#endif /* __PJ_SSL_SOCK_H__ */ diff --git a/pjlib/include/pj/string.h b/pjlib/include/pj/string.h new file mode 100644 index 0000000..a75f5da --- /dev/null +++ b/pjlib/include/pj/string.h @@ -0,0 +1,692 @@ +/* $Id: string.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 + * + * 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_STRING_H__ +#define __PJ_STRING_H__ + +/** + * @file string.h + * @brief PJLIB String Operations. + */ + +#include +#include + + +PJ_BEGIN_DECL + +/** + * @defgroup PJ_PSTR String Operations + * @ingroup PJ_DS + * @{ + * This module provides string manipulation API. + * + * \section pj_pstr_not_null_sec PJLIB String is NOT Null Terminated! + * + * That is the first information that developers need to know. Instead + * of using normal C string, strings in PJLIB are represented as + * pj_str_t structure below: + * + *
+ *   typedef struct pj_str_t
+ *   {
+ *       char      *ptr;
+ *       pj_size_t  slen;
+ *   } pj_str_t;
+ * 
+ * + * There are some advantages of using this approach: + * - the string can point to arbitrary location in memory even + * if the string in that location is not null terminated. This is + * most usefull for text parsing, where the parsed text can just + * point to the original text in the input. If we use C string, + * then we will have to copy the text portion from the input + * to a string variable. + * - because the length of the string is known, string copy operation + * can be made more efficient. + * + * Most of APIs in PJLIB that expect or return string will represent + * the string as pj_str_t instead of normal C string. + * + * \section pj_pstr_examples_sec Examples + * + * For some examples, please see: + * - @ref page_pjlib_string_test + */ + +/** + * Create string initializer from a normal C string. + * + * @param str Null terminated string to be stored. + * + * @return pj_str_t. + */ +PJ_IDECL(pj_str_t) pj_str(char *str); + +/** + * Create constant string from normal C string. + * + * @param str The string to be initialized. + * @param s Null terminated string. + * + * @return pj_str_t. + */ +PJ_INLINE(const pj_str_t*) pj_cstr(pj_str_t *str, const char *s) +{ + str->ptr = (char*)s; + str->slen = s ? (pj_ssize_t)strlen(s) : 0; + return str; +} + +/** + * Set the pointer and length to the specified value. + * + * @param str the string. + * @param ptr pointer to set. + * @param length length to set. + * + * @return the string. + */ +PJ_INLINE(pj_str_t*) pj_strset( pj_str_t *str, char *ptr, pj_size_t length) +{ + str->ptr = ptr; + str->slen = (pj_ssize_t)length; + return str; +} + +/** + * Set the pointer and length of the string to the source string, which + * must be NULL terminated. + * + * @param str the string. + * @param src pointer to set. + * + * @return the string. + */ +PJ_INLINE(pj_str_t*) pj_strset2( pj_str_t *str, char *src) +{ + str->ptr = src; + str->slen = src ? (pj_ssize_t)strlen(src) : 0; + return str; +} + +/** + * Set the pointer and the length of the string. + * + * @param str The target string. + * @param begin The start of the string. + * @param end The end of the string. + * + * @return the target string. + */ +PJ_INLINE(pj_str_t*) pj_strset3( pj_str_t *str, char *begin, char *end ) +{ + str->ptr = begin; + str->slen = (pj_ssize_t)(end-begin); + return str; +} + +/** + * Assign string. + * + * @param dst The target string. + * @param src The source string. + * + * @return the target string. + */ +PJ_IDECL(pj_str_t*) pj_strassign( pj_str_t *dst, pj_str_t *src ); + +/** + * Copy string contents. + * + * @param dst The target string. + * @param src The source string. + * + * @return the target string. + */ +PJ_IDECL(pj_str_t*) pj_strcpy(pj_str_t *dst, const pj_str_t *src); + +/** + * Copy string contents. + * + * @param dst The target string. + * @param src The source string. + * + * @return the target string. + */ +PJ_IDECL(pj_str_t*) pj_strcpy2(pj_str_t *dst, const char *src); + +/** + * Copy source string to destination up to the specified max length. + * + * @param dst The target string. + * @param src The source string. + * @param max Maximum characters to copy. + * + * @return the target string. + */ +PJ_IDECL(pj_str_t*) pj_strncpy(pj_str_t *dst, const pj_str_t *src, + pj_ssize_t max); + +/** + * Copy source string to destination up to the specified max length, + * and NULL terminate the destination. If source string length is + * greater than or equal to max, then max-1 will be copied. + * + * @param dst The target string. + * @param src The source string. + * @param max Maximum characters to copy. + * + * @return the target string. + */ +PJ_IDECL(pj_str_t*) pj_strncpy_with_null(pj_str_t *dst, const pj_str_t *src, + pj_ssize_t max); + +/** + * Duplicate string. + * + * @param pool The pool. + * @param dst The string result. + * @param src The string to duplicate. + * + * @return the string result. + */ +PJ_IDECL(pj_str_t*) pj_strdup(pj_pool_t *pool, + pj_str_t *dst, + const pj_str_t *src); + +/** + * Duplicate string and NULL terminate the destination string. + * + * @param pool The pool. + * @param dst The string result. + * @param src The string to duplicate. + * + * @return The string result. + */ +PJ_IDECL(pj_str_t*) pj_strdup_with_null(pj_pool_t *pool, + pj_str_t *dst, + const pj_str_t *src); + +/** + * Duplicate string. + * + * @param pool The pool. + * @param dst The string result. + * @param src The string to duplicate. + * + * @return the string result. + */ +PJ_IDECL(pj_str_t*) pj_strdup2(pj_pool_t *pool, + pj_str_t *dst, + const char *src); + +/** + * Duplicate string and NULL terminate the destination string. + * + * @param pool The pool. + * @param dst The string result. + * @param src The string to duplicate. + * + * @return The string result. + */ +PJ_IDECL(pj_str_t*) pj_strdup2_with_null(pj_pool_t *pool, + pj_str_t *dst, + const char *src); + + +/** + * Duplicate string. + * + * @param pool The pool. + * @param src The string to duplicate. + * + * @return the string result. + */ +PJ_IDECL(pj_str_t) pj_strdup3(pj_pool_t *pool, const char *src); + +/** + * Return the length of the string. + * + * @param str The string. + * + * @return the length of the string. + */ +PJ_INLINE(pj_size_t) pj_strlen( const pj_str_t *str ) +{ + return str->slen; +} + +/** + * Return the pointer to the string data. + * + * @param str The string. + * + * @return the pointer to the string buffer. + */ +PJ_INLINE(const char*) pj_strbuf( const pj_str_t *str ) +{ + return str->ptr; +} + +/** + * Compare strings. + * + * @param str1 The string to compare. + * @param str2 The string to compare. + * + * @return + * - < 0 if str1 is less than str2 + * - 0 if str1 is identical to str2 + * - > 0 if str1 is greater than str2 + */ +PJ_IDECL(int) pj_strcmp( const pj_str_t *str1, const pj_str_t *str2); + +/** + * Compare strings. + * + * @param str1 The string to compare. + * @param str2 The string to compare. + * + * @return + * - < 0 if str1 is less than str2 + * - 0 if str1 is identical to str2 + * - > 0 if str1 is greater than str2 + */ +PJ_IDECL(int) pj_strcmp2( const pj_str_t *str1, const char *str2 ); + +/** + * Compare strings. + * + * @param str1 The string to compare. + * @param str2 The string to compare. + * @param len The maximum number of characters to compare. + * + * @return + * - < 0 if str1 is less than str2 + * - 0 if str1 is identical to str2 + * - > 0 if str1 is greater than str2 + */ +PJ_IDECL(int) pj_strncmp( const pj_str_t *str1, const pj_str_t *str2, + pj_size_t len); + +/** + * Compare strings. + * + * @param str1 The string to compare. + * @param str2 The string to compare. + * @param len The maximum number of characters to compare. + * + * @return + * - < 0 if str1 is less than str2 + * - 0 if str1 is identical to str2 + * - > 0 if str1 is greater than str2 + */ +PJ_IDECL(int) pj_strncmp2( const pj_str_t *str1, const char *str2, + pj_size_t len); + +/** + * Perform case-insensitive comparison to the strings. + * + * @param str1 The string to compare. + * @param str2 The string to compare. + * + * @return + * - < 0 if str1 is less than str2 + * - 0 if str1 is equal to str2 + * - > 0 if str1 is greater than str2 + */ +PJ_IDECL(int) pj_stricmp(const pj_str_t *str1, const pj_str_t *str2); + +/** + * Perform lowercase comparison to the strings which consists of only + * alnum characters. More over, it will only return non-zero if both + * strings are not equal, not the usual negative or positive value. + * + * If non-alnum inputs are given, then the function may mistakenly + * treat two strings as equal. + * + * @param str1 The string to compare. + * @param str2 The string to compare. + * @param len The length to compare. + * + * @return + * - 0 if str1 is equal to str2 + * - (-1) if not equal. + */ +#if defined(PJ_HAS_STRICMP_ALNUM) && PJ_HAS_STRICMP_ALNUM!=0 +PJ_IDECL(int) strnicmp_alnum(const char *str1, const char *str2, + int len); +#else +#define strnicmp_alnum pj_ansi_strnicmp +#endif + +/** + * Perform lowercase comparison to the strings which consists of only + * alnum characters. More over, it will only return non-zero if both + * strings are not equal, not the usual negative or positive value. + * + * If non-alnum inputs are given, then the function may mistakenly + * treat two strings as equal. + * + * @param str1 The string to compare. + * @param str2 The string to compare. + * + * @return + * - 0 if str1 is equal to str2 + * - (-1) if not equal. + */ +#if defined(PJ_HAS_STRICMP_ALNUM) && PJ_HAS_STRICMP_ALNUM!=0 +PJ_IDECL(int) pj_stricmp_alnum(const pj_str_t *str1, const pj_str_t *str2); +#else +#define pj_stricmp_alnum pj_stricmp +#endif + +/** + * Perform case-insensitive comparison to the strings. + * + * @param str1 The string to compare. + * @param str2 The string to compare. + * + * @return + * - < 0 if str1 is less than str2 + * - 0 if str1 is identical to str2 + * - > 0 if str1 is greater than str2 + */ +PJ_IDECL(int) pj_stricmp2( const pj_str_t *str1, const char *str2); + +/** + * Perform case-insensitive comparison to the strings. + * + * @param str1 The string to compare. + * @param str2 The string to compare. + * @param len The maximum number of characters to compare. + * + * @return + * - < 0 if str1 is less than str2 + * - 0 if str1 is identical to str2 + * - > 0 if str1 is greater than str2 + */ +PJ_IDECL(int) pj_strnicmp( const pj_str_t *str1, const pj_str_t *str2, + pj_size_t len); + +/** + * Perform case-insensitive comparison to the strings. + * + * @param str1 The string to compare. + * @param str2 The string to compare. + * @param len The maximum number of characters to compare. + * + * @return + * - < 0 if str1 is less than str2 + * - 0 if str1 is identical to str2 + * - > 0 if str1 is greater than str2 + */ +PJ_IDECL(int) pj_strnicmp2( const pj_str_t *str1, const char *str2, + pj_size_t len); + +/** + * Concatenate strings. + * + * @param dst The destination string. + * @param src The source string. + */ +PJ_IDECL(void) pj_strcat(pj_str_t *dst, const pj_str_t *src); + + +/** + * Concatenate strings. + * + * @param dst The destination string. + * @param src The source string. + */ +PJ_IDECL(void) pj_strcat2(pj_str_t *dst, const char *src); + + +/** + * Finds a character in a string. + * + * @param str The string. + * @param chr The character to find. + * + * @return the pointer to first character found, or NULL. + */ +PJ_INLINE(char*) pj_strchr( const pj_str_t *str, int chr) +{ + return (char*) memchr((char*)str->ptr, chr, str->slen); +} + +/** + * Find the occurence of a substring substr in string str. + * + * @param str The string to search. + * @param substr The string to search fo. + * + * @return the pointer to the position of substr in str, or NULL. Note + * that if str is not NULL terminated, the returned pointer + * is pointing to non-NULL terminated string. + */ +PJ_DECL(char*) pj_strstr(const pj_str_t *str, const pj_str_t *substr); + +/** + * Performs substring lookup like pj_strstr() but ignores the case of + * both strings. + * + * @param str The string to search. + * @param substr The string to search fo. + * + * @return the pointer to the position of substr in str, or NULL. Note + * that if str is not NULL terminated, the returned pointer + * is pointing to non-NULL terminated string. + */ +PJ_DECL(char*) pj_stristr(const pj_str_t *str, const pj_str_t *substr); + +/** + * Remove (trim) leading whitespaces from the string. + * + * @param str The string. + * + * @return the string. + */ +PJ_DECL(pj_str_t*) pj_strltrim( pj_str_t *str ); + +/** + * Remove (trim) the trailing whitespaces from the string. + * + * @param str The string. + * + * @return the string. + */ +PJ_DECL(pj_str_t*) pj_strrtrim( pj_str_t *str ); + +/** + * Remove (trim) leading and trailing whitespaces from the string. + * + * @param str The string. + * + * @return the string. + */ +PJ_IDECL(pj_str_t*) pj_strtrim( pj_str_t *str ); + +/** + * Initialize the buffer with some random string. Note that the + * generated string is not NULL terminated. + * + * @param str the string to store the result. + * @param length the length of the random string to generate. + * + * @return the string. + */ +PJ_DECL(char*) pj_create_random_string(char *str, pj_size_t length); + +/** + * Convert string to unsigned integer. The conversion will stop as + * soon as non-digit character is found or all the characters have + * been processed. + * + * @param str the string. + * + * @return the unsigned integer. + */ +PJ_DECL(unsigned long) pj_strtoul(const pj_str_t *str); + +/** + * Convert strings to an unsigned long-integer value. + * This function stops reading the string input either when the number + * of characters has exceeded the length of the input or it has read + * the first character it cannot recognize as part of a number, that is + * a character greater than or equal to base. + * + * @param str The input string. + * @param endptr Optional pointer to receive the remainder/unparsed + * portion of the input. + * @param base Number base to use. + * + * @return the unsigned integer number. + */ +PJ_DECL(unsigned long) pj_strtoul2(const pj_str_t *str, pj_str_t *endptr, + unsigned base); + +/** + * Utility to convert unsigned integer to string. Note that the + * string will be NULL terminated. + * + * @param val the unsigned integer value. + * @param buf the buffer + * + * @return the number of characters written + */ +PJ_DECL(int) pj_utoa(unsigned long val, char *buf); + +/** + * Convert unsigned integer to string with minimum digits. Note that the + * string will be NULL terminated. + * + * @param val The unsigned integer value. + * @param buf The buffer. + * @param min_dig Minimum digits to be printed, or zero to specify no + * minimum digit. + * @param pad The padding character to be put in front of the string + * when the digits is less than minimum. + * + * @return the number of characters written. + */ +PJ_DECL(int) pj_utoa_pad( unsigned long val, char *buf, int min_dig, int pad); + + +/** + * Fill the memory location with zero. + * + * @param dst The destination buffer. + * @param size The number of bytes. + */ +PJ_INLINE(void) pj_bzero(void *dst, pj_size_t size) +{ +#if defined(PJ_HAS_BZERO) && PJ_HAS_BZERO!=0 + bzero(dst, size); +#else + memset(dst, 0, size); +#endif +} + + +/** + * Fill the memory location with value. + * + * @param dst The destination buffer. + * @param c Character to set. + * @param size The number of characters. + * + * @return the value of dst. + */ +PJ_INLINE(void*) pj_memset(void *dst, int c, pj_size_t size) +{ + return memset(dst, c, size); +} + +/** + * Copy buffer. + * + * @param dst The destination buffer. + * @param src The source buffer. + * @param size The size to copy. + * + * @return the destination buffer. + */ +PJ_INLINE(void*) pj_memcpy(void *dst, const void *src, pj_size_t size) +{ + return memcpy(dst, src, size); +} + +/** + * Move memory. + * + * @param dst The destination buffer. + * @param src The source buffer. + * @param size The size to copy. + * + * @return the destination buffer. + */ +PJ_INLINE(void*) pj_memmove(void *dst, const void *src, pj_size_t size) +{ + return memmove(dst, src, size); +} + +/** + * Compare buffers. + * + * @param buf1 The first buffer. + * @param buf2 The second buffer. + * @param size The size to compare. + * + * @return negative, zero, or positive value. + */ +PJ_INLINE(int) pj_memcmp(const void *buf1, const void *buf2, pj_size_t size) +{ + return memcmp(buf1, buf2, size); +} + +/** + * Find character in the buffer. + * + * @param buf The buffer. + * @param c The character to find. + * @param size The size to check. + * + * @return the pointer to location where the character is found, or NULL if + * not found. + */ +PJ_INLINE(void*) pj_memchr(const void *buf, int c, pj_size_t size) +{ + return (void*)memchr((void*)buf, c, size); +} + + +/** + * @} + */ + +#if PJ_FUNCTIONS_ARE_INLINED +# include +#endif + +PJ_END_DECL + +#endif /* __PJ_STRING_H__ */ + diff --git a/pjlib/include/pj/string_i.h b/pjlib/include/pj/string_i.h new file mode 100644 index 0000000..35904ed --- /dev/null +++ b/pjlib/include/pj/string_i.h @@ -0,0 +1,371 @@ +/* $Id: string_i.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 + * + * 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 + */ + +#include + +PJ_IDEF(pj_str_t) pj_str(char *str) +{ + pj_str_t dst; + dst.ptr = str; + dst.slen = str ? pj_ansi_strlen(str) : 0; + return dst; +} + +PJ_IDEF(pj_str_t*) pj_strdup(pj_pool_t *pool, + pj_str_t *dst, + const pj_str_t *src) +{ + /* Without this, destination will be corrupted */ + if (dst == src) + return dst; + + if (src->slen) { + dst->ptr = (char*)pj_pool_alloc(pool, src->slen); + pj_memcpy(dst->ptr, src->ptr, src->slen); + } + dst->slen = src->slen; + return dst; +} + +PJ_IDEF(pj_str_t*) pj_strdup_with_null( pj_pool_t *pool, + pj_str_t *dst, + const pj_str_t *src) +{ + dst->ptr = (char*)pj_pool_alloc(pool, src->slen+1); + if (src->slen) { + pj_memcpy(dst->ptr, src->ptr, src->slen); + } + dst->slen = src->slen; + dst->ptr[dst->slen] = '\0'; + return dst; +} + +PJ_IDEF(pj_str_t*) pj_strdup2(pj_pool_t *pool, + pj_str_t *dst, + const char *src) +{ + dst->slen = src ? pj_ansi_strlen(src) : 0; + if (dst->slen) { + dst->ptr = (char*)pj_pool_alloc(pool, dst->slen); + pj_memcpy(dst->ptr, src, dst->slen); + } else { + dst->ptr = NULL; + } + return dst; +} + +PJ_IDEF(pj_str_t*) pj_strdup2_with_null( pj_pool_t *pool, + pj_str_t *dst, + const char *src) +{ + dst->slen = src ? pj_ansi_strlen(src) : 0; + dst->ptr = (char*)pj_pool_alloc(pool, dst->slen+1); + if (dst->slen) { + pj_memcpy(dst->ptr, src, dst->slen); + } + dst->ptr[dst->slen] = '\0'; + return dst; +} + +PJ_IDEF(pj_str_t) pj_strdup3(pj_pool_t *pool, const char *src) +{ + pj_str_t temp; + pj_strdup2(pool, &temp, src); + return temp; +} + +PJ_IDEF(pj_str_t*) pj_strassign( pj_str_t *dst, pj_str_t *src ) +{ + dst->ptr = src->ptr; + dst->slen = src->slen; + return dst; +} + +PJ_IDEF(pj_str_t*) pj_strcpy(pj_str_t *dst, const pj_str_t *src) +{ + dst->slen = src->slen; + if (src->slen > 0) + pj_memcpy(dst->ptr, src->ptr, src->slen); + return dst; +} + +PJ_IDEF(pj_str_t*) pj_strcpy2(pj_str_t *dst, const char *src) +{ + dst->slen = src ? pj_ansi_strlen(src) : 0; + if (dst->slen > 0) + pj_memcpy(dst->ptr, src, dst->slen); + return dst; +} + +PJ_IDEF(pj_str_t*) pj_strncpy( pj_str_t *dst, const pj_str_t *src, + pj_ssize_t max) +{ + if (max > src->slen) max = src->slen; + pj_memcpy(dst->ptr, src->ptr, max); + dst->slen = max; + return dst; +} + +PJ_IDEF(pj_str_t*) pj_strncpy_with_null( pj_str_t *dst, const pj_str_t *src, + pj_ssize_t max) +{ + if (max <= src->slen) + max = max-1; + else + max = src->slen; + + pj_memcpy(dst->ptr, src->ptr, max); + dst->ptr[max] = '\0'; + dst->slen = max; + return dst; +} + + +PJ_IDEF(int) pj_strcmp( const pj_str_t *str1, const pj_str_t *str2) +{ + if (str1->slen == 0) { + return str2->slen==0 ? 0 : -1; + } else if (str2->slen == 0) { + return 1; + } else { + int min = (str1->slen < str2->slen)? str1->slen : str2->slen; + int res = pj_memcmp(str1->ptr, str2->ptr, min); + if (res == 0) { + return (str1->slen < str2->slen) ? -1 : + (str1->slen == str2->slen ? 0 : 1); + } else { + return res; + } + } +} + +PJ_IDEF(int) pj_strncmp( const pj_str_t *str1, const pj_str_t *str2, + pj_size_t len) +{ + pj_str_t copy1, copy2; + + if (len < (unsigned)str1->slen) { + copy1.ptr = str1->ptr; + copy1.slen = len; + str1 = ©1; + } + + if (len < (unsigned)str2->slen) { + copy2.ptr = str2->ptr; + copy2.slen = len; + str2 = ©2; + } + + return pj_strcmp(str1, str2); +} + +PJ_IDEF(int) pj_strncmp2( const pj_str_t *str1, const char *str2, + pj_size_t len) +{ + pj_str_t copy2; + + if (str2) { + copy2.ptr = (char*)str2; + copy2.slen = pj_ansi_strlen(str2); + } else { + copy2.slen = 0; + } + + return pj_strncmp(str1, ©2, len); +} + +PJ_IDEF(int) pj_strcmp2( const pj_str_t *str1, const char *str2 ) +{ + pj_str_t copy2; + + if (str2) { + copy2.ptr = (char*)str2; + copy2.slen = pj_ansi_strlen(str2); + } else { + copy2.ptr = NULL; + copy2.slen = 0; + } + + return pj_strcmp(str1, ©2); +} + +PJ_IDEF(int) pj_stricmp( const pj_str_t *str1, const pj_str_t *str2) +{ + if (str1->slen == 0) { + return str2->slen==0 ? 0 : -1; + } else if (str2->slen == 0) { + return 1; + } else { + int min = (str1->slen < str2->slen)? str1->slen : str2->slen; + int res = pj_ansi_strnicmp(str1->ptr, str2->ptr, min); + if (res == 0) { + return (str1->slen < str2->slen) ? -1 : + (str1->slen == str2->slen ? 0 : 1); + } else { + return res; + } + } +} + +#if defined(PJ_HAS_STRICMP_ALNUM) && PJ_HAS_STRICMP_ALNUM!=0 +PJ_IDEF(int) strnicmp_alnum( const char *str1, const char *str2, + int len) +{ + if (len==0) + return 0; + else { + register const pj_uint32_t *p1 = (pj_uint32_t*)str1, + *p2 = (pj_uint32_t*)str2; + while (len > 3 && (*p1 & 0x5F5F5F5F)==(*p2 & 0x5F5F5F5F)) + ++p1, ++p2, len-=4; + + if (len > 3) + return -1; +#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0 + else if (len==3) + return ((*p1 & 0x005F5F5F)==(*p2 & 0x005F5F5F)) ? 0 : -1; + else if (len==2) + return ((*p1 & 0x00005F5F)==(*p2 & 0x00005F5F)) ? 0 : -1; + else if (len==1) + return ((*p1 & 0x0000005F)==(*p2 & 0x0000005F)) ? 0 : -1; +#else + else if (len==3) + return ((*p1 & 0x5F5F5F00)==(*p2 & 0x5F5F5F00)) ? 0 : -1; + else if (len==2) + return ((*p1 & 0x5F5F0000)==(*p2 & 0x5F5F0000)) ? 0 : -1; + else if (len==1) + return ((*p1 & 0x5F000000)==(*p2 & 0x5F000000)) ? 0 : -1; +#endif + else + return 0; + } +} + +PJ_IDEF(int) pj_stricmp_alnum(const pj_str_t *str1, const pj_str_t *str2) +{ + register int len = str1->slen; + + if (len != str2->slen) { + return (len < str2->slen) ? -1 : 1; + } else if (len == 0) { + return 0; + } else { + register const pj_uint32_t *p1 = (pj_uint32_t*)str1->ptr, + *p2 = (pj_uint32_t*)str2->ptr; + while (len > 3 && (*p1 & 0x5F5F5F5F)==(*p2 & 0x5F5F5F5F)) + ++p1, ++p2, len-=4; + + if (len > 3) + return -1; +#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0 + else if (len==3) + return ((*p1 & 0x005F5F5F)==(*p2 & 0x005F5F5F)) ? 0 : -1; + else if (len==2) + return ((*p1 & 0x00005F5F)==(*p2 & 0x00005F5F)) ? 0 : -1; + else if (len==1) + return ((*p1 & 0x0000005F)==(*p2 & 0x0000005F)) ? 0 : -1; +#else + else if (len==3) + return ((*p1 & 0x5F5F5F00)==(*p2 & 0x5F5F5F00)) ? 0 : -1; + else if (len==2) + return ((*p1 & 0x5F5F0000)==(*p2 & 0x5F5F0000)) ? 0 : -1; + else if (len==1) + return ((*p1 & 0x5F000000)==(*p2 & 0x5F000000)) ? 0 : -1; +#endif + else + return 0; + } +} +#endif /* PJ_HAS_STRICMP_ALNUM */ + +PJ_IDEF(int) pj_stricmp2( const pj_str_t *str1, const char *str2) +{ + pj_str_t copy2; + + if (str2) { + copy2.ptr = (char*)str2; + copy2.slen = pj_ansi_strlen(str2); + } else { + copy2.ptr = NULL; + copy2.slen = 0; + } + + return pj_stricmp(str1, ©2); +} + +PJ_IDEF(int) pj_strnicmp( const pj_str_t *str1, const pj_str_t *str2, + pj_size_t len) +{ + pj_str_t copy1, copy2; + + if (len < (unsigned)str1->slen) { + copy1.ptr = str1->ptr; + copy1.slen = len; + str1 = ©1; + } + + if (len < (unsigned)str2->slen) { + copy2.ptr = str2->ptr; + copy2.slen = len; + str2 = ©2; + } + + return pj_stricmp(str1, str2); +} + +PJ_IDEF(int) pj_strnicmp2( const pj_str_t *str1, const char *str2, + pj_size_t len) +{ + pj_str_t copy2; + + if (str2) { + copy2.ptr = (char*)str2; + copy2.slen = pj_ansi_strlen(str2); + } else { + copy2.slen = 0; + } + + return pj_strnicmp(str1, ©2, len); +} + +PJ_IDEF(void) pj_strcat(pj_str_t *dst, const pj_str_t *src) +{ + if (src->slen) { + pj_memcpy(dst->ptr + dst->slen, src->ptr, src->slen); + dst->slen += src->slen; + } +} + +PJ_IDEF(void) pj_strcat2(pj_str_t *dst, const char *str) +{ + unsigned len = str? pj_ansi_strlen(str) : 0; + if (len) { + pj_memcpy(dst->ptr + dst->slen, str, len); + dst->slen += len; + } +} + +PJ_IDEF(pj_str_t*) pj_strtrim( pj_str_t *str ) +{ + pj_strltrim(str); + pj_strrtrim(str); + return str; +} + diff --git a/pjlib/include/pj/timer.h b/pjlib/include/pj/timer.h new file mode 100644 index 0000000..1cc11cf --- /dev/null +++ b/pjlib/include/pj/timer.h @@ -0,0 +1,297 @@ +/* $Id: timer.h 4154 2012-06-05 10:41:17Z bennylp $ */ +/* + * 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_TIMER_H__ +#define __PJ_TIMER_H__ + +/** + * @file timer.h + * @brief Timer Heap + */ + +#include + +PJ_BEGIN_DECL + +/** + * @defgroup PJ_TIMER Timer Heap Management. + * @ingroup PJ_MISC + * @brief + * The timer scheduling implementation here is based on ACE library's + * ACE_Timer_Heap, with only little modification to suit our library's style + * (I even left most of the comments in the original source). + * + * To quote the original quote in ACE_Timer_Heap_T class: + * + * This implementation uses a heap-based callout queue of + * absolute times. Therefore, in the average and worst case, + * scheduling, canceling, and expiring timers is O(log N) (where + * N is the total number of timers). In addition, we can also + * preallocate as many \a ACE_Timer_Nodes as there are slots in + * the heap. This allows us to completely remove the need for + * dynamic memory allocation, which is important for real-time + * systems. + * + * You can find the fine ACE library at: + * http://www.cs.wustl.edu/~schmidt/ACE.html + * + * ACE is Copyright (C)1993-2006 Douglas C. Schmidt + * + * @{ + * + * \section pj_timer_examples_sec Examples + * + * For some examples on how to use the timer heap, please see the link below. + * + * - \ref page_pjlib_timer_test + */ + + +/** + * The type for internal timer ID. + */ +typedef int pj_timer_id_t; + +/** + * Forward declaration for pj_timer_entry. + */ +struct pj_timer_entry; + +/** + * The type of callback function to be called by timer scheduler when a timer + * has expired. + * + * @param timer_heap The timer heap. + * @param entry Timer entry which timer's has expired. + */ +typedef void pj_timer_heap_callback(pj_timer_heap_t *timer_heap, + struct pj_timer_entry *entry); + + +/** + * This structure represents an entry to the timer. + */ +typedef struct pj_timer_entry +{ + /** + * User data to be associated with this entry. + * Applications normally will put the instance of object that + * owns the timer entry in this field. + */ + void *user_data; + + /** + * Arbitrary ID assigned by the user/owner of this entry. + * Applications can use this ID to distinguish multiple + * timer entries that share the same callback and user_data. + */ + int id; + + /** + * Callback to be called when the timer expires. + */ + pj_timer_heap_callback *cb; + + /** + * Internal unique timer ID, which is assigned by the timer heap. + * Application should not touch this ID. + */ + pj_timer_id_t _timer_id; + + /** + * The future time when the timer expires, which the value is updated + * by timer heap when the timer is scheduled. + */ + pj_time_val _timer_value; + +#if PJ_TIMER_DEBUG + const char *src_file; + int src_line; +#endif +} pj_timer_entry; + + +/** + * Calculate memory size required to create a timer heap. + * + * @param count Number of timer entries to be supported. + * @return Memory size requirement in bytes. + */ +PJ_DECL(pj_size_t) pj_timer_heap_mem_size(pj_size_t count); + +/** + * Create a timer heap. + * + * @param pool The pool where allocations in the timer heap will be + * allocated. The timer heap will dynamicly allocate + * more storate from the pool if the number of timer + * entries registered is more than the size originally + * requested when calling this function. + * @param count The maximum number of timer entries to be supported + * initially. If the application registers more entries + * during runtime, then the timer heap will resize. + * @param ht Pointer to receive the created timer heap. + * + * @return PJ_SUCCESS, or the appropriate error code. + */ +PJ_DECL(pj_status_t) pj_timer_heap_create( pj_pool_t *pool, + pj_size_t count, + pj_timer_heap_t **ht); + +/** + * Destroy the timer heap. + * + * @param ht The timer heap. + */ +PJ_DECL(void) pj_timer_heap_destroy( pj_timer_heap_t *ht ); + + +/** + * Set lock object to be used by the timer heap. By default, the timer heap + * uses dummy synchronization. + * + * @param ht The timer heap. + * @param lock The lock object to be used for synchronization. + * @param auto_del If nonzero, the lock object will be destroyed when + * the timer heap is destroyed. + */ +PJ_DECL(void) pj_timer_heap_set_lock( pj_timer_heap_t *ht, + pj_lock_t *lock, + pj_bool_t auto_del ); + +/** + * Set maximum number of timed out entries to process in a single poll. + * + * @param ht The timer heap. + * @param count Number of entries. + * + * @return The old number. + */ +PJ_DECL(unsigned) pj_timer_heap_set_max_timed_out_per_poll(pj_timer_heap_t *ht, + unsigned count ); + +/** + * Initialize a timer entry. Application should call this function at least + * once before scheduling the entry to the timer heap, to properly initialize + * the timer entry. + * + * @param entry The timer entry to be initialized. + * @param id Arbitrary ID assigned by the user/owner of this entry. + * Applications can use this ID to distinguish multiple + * timer entries that share the same callback and user_data. + * @param user_data User data to be associated with this entry. + * Applications normally will put the instance of object that + * owns the timer entry in this field. + * @param cb Callback function to be called when the timer elapses. + * + * @return The timer entry itself. + */ +PJ_DECL(pj_timer_entry*) pj_timer_entry_init( pj_timer_entry *entry, + int id, + void *user_data, + pj_timer_heap_callback *cb ); + +/** + * Schedule a timer entry which will expire AFTER the specified delay. + * + * @param ht The timer heap. + * @param entry The entry to be registered. + * @param delay The interval to expire. + * @return PJ_SUCCESS, or the appropriate error code. + */ +#if PJ_TIMER_DEBUG +# define pj_timer_heap_schedule(ht,e,d) \ + pj_timer_heap_schedule_dbg(ht,e,d,__FILE__,__LINE__) + + PJ_DECL(pj_status_t) pj_timer_heap_schedule_dbg( pj_timer_heap_t *ht, + pj_timer_entry *entry, + const pj_time_val *delay, + const char *src_file, + int src_line); +#else +PJ_DECL(pj_status_t) pj_timer_heap_schedule( pj_timer_heap_t *ht, + pj_timer_entry *entry, + const pj_time_val *delay); +#endif /* PJ_TIMER_DEBUG */ + +/** + * Cancel a previously registered timer. + * + * @param ht The timer heap. + * @param entry The entry to be cancelled. + * @return The number of timer cancelled, which should be one if the + * entry has really been registered, or zero if no timer was + * cancelled. + */ +PJ_DECL(int) pj_timer_heap_cancel( pj_timer_heap_t *ht, + pj_timer_entry *entry); + +/** + * Get the number of timer entries. + * + * @param ht The timer heap. + * @return The number of timer entries. + */ +PJ_DECL(pj_size_t) pj_timer_heap_count( pj_timer_heap_t *ht ); + +/** + * Get the earliest time registered in the timer heap. The timer heap + * MUST have at least one timer being scheduled (application should use + * #pj_timer_heap_count() before calling this function). + * + * @param ht The timer heap. + * @param timeval The time deadline of the earliest timer entry. + * + * @return PJ_SUCCESS, or PJ_ENOTFOUND if no entry is scheduled. + */ +PJ_DECL(pj_status_t) pj_timer_heap_earliest_time( pj_timer_heap_t *ht, + pj_time_val *timeval); + +/** + * Poll the timer heap, check for expired timers and call the callback for + * each of the expired timers. + * + * Note: polling the timer heap is not necessary in Symbian. Please see + * @ref PJ_SYMBIAN_OS for more info. + * + * @param ht The timer heap. + * @param next_delay If this parameter is not NULL, it will be filled up with + * the time delay until the next timer elapsed, or + * PJ_MAXINT32 in the sec part if no entry exist. + * + * @return The number of timers expired. + */ +PJ_DECL(unsigned) pj_timer_heap_poll( pj_timer_heap_t *ht, + pj_time_val *next_delay); + +#if PJ_TIMER_DEBUG +/** + * Dump timer heap entries. + * + * @param ht The timer heap. + */ +PJ_DECL(void) pj_timer_heap_dump(pj_timer_heap_t *ht); +#endif + +/** + * @} + */ + +PJ_END_DECL + +#endif /* __PJ_TIMER_H__ */ + diff --git a/pjlib/include/pj/types.h b/pjlib/include/pj/types.h new file mode 100644 index 0000000..99c54db --- /dev/null +++ b/pjlib/include/pj/types.h @@ -0,0 +1,542 @@ +/* $Id: types.h 4154 2012-06-05 10:41:17Z bennylp $ */ +/* + * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 Benny Prijono + * + * 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_TYPES_H__ +#define __PJ_TYPES_H__ + + +/** + * @file types.h + * @brief Declaration of basic types and utility. + */ +/** + * @defgroup PJ_BASIC Basic Data Types and Library Functionality. + * @ingroup PJ_DS + * @{ + */ +#include + +PJ_BEGIN_DECL + +/* ************************************************************************* */ + +/** Signed 32bit integer. */ +typedef int pj_int32_t; + +/** Unsigned 32bit integer. */ +typedef unsigned int pj_uint32_t; + +/** Signed 16bit integer. */ +typedef short pj_int16_t; + +/** Unsigned 16bit integer. */ +typedef unsigned short pj_uint16_t; + +/** Signed 8bit integer. */ +typedef signed char pj_int8_t; + +/** Unsigned 8bit integer. */ +typedef unsigned char pj_uint8_t; + +/** Large unsigned integer. */ +typedef size_t pj_size_t; + +/** Large signed integer. */ +typedef long pj_ssize_t; + +/** Status code. */ +typedef int pj_status_t; + +/** Boolean. */ +typedef int pj_bool_t; + +/** Native char type, which will be equal to wchar_t for Unicode + * and char for ANSI. */ +#if defined(PJ_NATIVE_STRING_IS_UNICODE) && PJ_NATIVE_STRING_IS_UNICODE!=0 + typedef wchar_t pj_char_t; +#else + typedef char pj_char_t; +#endif + +/** This macro creates Unicode or ANSI literal string depending whether + * native platform string is Unicode or ANSI. */ +#if defined(PJ_NATIVE_STRING_IS_UNICODE) && PJ_NATIVE_STRING_IS_UNICODE!=0 +# define PJ_T(literal_str) L##literal_str +#else +# define PJ_T(literal_str) literal_str +#endif + + +/** Status is OK. */ +#define PJ_SUCCESS 0 + +/** True value. */ +#define PJ_TRUE 1 + +/** False value. */ +#define PJ_FALSE 0 + +/** + * File offset type. + */ +#if defined(PJ_HAS_INT64) && PJ_HAS_INT64!=0 +typedef pj_int64_t pj_off_t; +#else +typedef pj_ssize_t pj_off_t; +#endif + +/* ************************************************************************* */ +/* + * Data structure types. + */ +/** + * This type is used as replacement to legacy C string, and used throughout + * the library. By convention, the string is NOT null terminated. + */ +struct pj_str_t +{ + /** Buffer pointer, which is by convention NOT null terminated. */ + char *ptr; + + /** The length of the string. */ + pj_ssize_t slen; +}; + +/** + * This structure represents high resolution (64bit) time value. The time + * values represent time in cycles, which is retrieved by calling + * #pj_get_timestamp(). + */ +typedef union pj_timestamp +{ + struct + { +#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0 + pj_uint32_t lo; /**< Low 32-bit value of the 64-bit value. */ + pj_uint32_t hi; /**< high 32-bit value of the 64-bit value. */ +#else + pj_uint32_t hi; /**< high 32-bit value of the 64-bit value. */ + pj_uint32_t lo; /**< Low 32-bit value of the 64-bit value. */ +#endif + } u32; /**< The 64-bit value as two 32-bit values. */ + +#if PJ_HAS_INT64 + pj_uint64_t u64; /**< The whole 64-bit value, where available. */ +#endif +} pj_timestamp; + + + +/** + * The opaque data type for linked list, which is used as arguments throughout + * the linked list operations. + */ +typedef void pj_list_type; + +/** + * List. + */ +typedef struct pj_list pj_list; + +/** + * Opaque data type for hash tables. + */ +typedef struct pj_hash_table_t pj_hash_table_t; + +/** + * Opaque data type for hash entry (only used internally by hash table). + */ +typedef struct pj_hash_entry pj_hash_entry; + +/** + * Data type for hash search iterator. + * This structure should be opaque, however applications need to declare + * concrete variable of this type, that's why the declaration is visible here. + */ +typedef struct pj_hash_iterator_t +{ + pj_uint32_t index; /**< Internal index. */ + pj_hash_entry *entry; /**< Internal entry. */ +} pj_hash_iterator_t; + + +/** + * Forward declaration for memory pool factory. + */ +typedef struct pj_pool_factory pj_pool_factory; + +/** + * Opaque data type for memory pool. + */ +typedef struct pj_pool_t pj_pool_t; + +/** + * Forward declaration for caching pool, a pool factory implementation. + */ +typedef struct pj_caching_pool pj_caching_pool; + +/** + * This type is used as replacement to legacy C string, and used throughout + * the library. + */ +typedef struct pj_str_t pj_str_t; + +/** + * Opaque data type for I/O Queue structure. + */ +typedef struct pj_ioqueue_t pj_ioqueue_t; + +/** + * Opaque data type for key that identifies a handle registered to the + * I/O queue framework. + */ +typedef struct pj_ioqueue_key_t pj_ioqueue_key_t; + +/** + * Opaque data to identify timer heap. + */ +typedef struct pj_timer_heap_t pj_timer_heap_t; + +/** + * Opaque data type for atomic operations. + */ +typedef struct pj_atomic_t pj_atomic_t; + +/** + * Value type of an atomic variable. + */ +typedef PJ_ATOMIC_VALUE_TYPE pj_atomic_value_t; + +/* ************************************************************************* */ + +/** Thread handle. */ +typedef struct pj_thread_t pj_thread_t; + +/** Lock object. */ +typedef struct pj_lock_t pj_lock_t; + +/** Mutex handle. */ +typedef struct pj_mutex_t pj_mutex_t; + +/** Semaphore handle. */ +typedef struct pj_sem_t pj_sem_t; + +/** Event object. */ +typedef struct pj_event_t pj_event_t; + +/** Unidirectional stream pipe object. */ +typedef struct pj_pipe_t pj_pipe_t; + +/** Operating system handle. */ +typedef void *pj_oshandle_t; + +/** Socket handle. */ +typedef long pj_sock_t; + +/** Generic socket address. */ +typedef void pj_sockaddr_t; + +/** Forward declaration. */ +typedef struct pj_sockaddr_in pj_sockaddr_in; + +/** Color type. */ +typedef unsigned int pj_color_t; + +/** Exception id. */ +typedef int pj_exception_id_t; + +/* ************************************************************************* */ + +/** Utility macro to compute the number of elements in static array. */ +#define PJ_ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) + +/** Maximum value for signed 32-bit integer. */ +#define PJ_MAXINT32 0x7FFFFFFFL + +/** + * Length of object names. + */ +#define PJ_MAX_OBJ_NAME 32 + +/* ************************************************************************* */ +/* + * General. + */ +/** + * Initialize the PJ Library. + * This function must be called before using the library. The purpose of this + * function is to initialize static library data, such as character table used + * in random string generation, and to initialize operating system dependent + * functionality (such as WSAStartup() in Windows). + * + * Apart from calling pj_init(), application typically should also initialize + * the random seed by calling pj_srand(). + * + * @return PJ_SUCCESS on success. + */ +PJ_DECL(pj_status_t) pj_init(void); + + +/** + * Shutdown PJLIB. + */ +PJ_DECL(void) pj_shutdown(void); + +/** + * Type of callback to register to pj_atexit(). + */ +typedef void (*pj_exit_callback)(void); + +/** + * Register cleanup function to be called by PJLIB when pj_shutdown() is + * called. + * + * @param func The function to be registered. + * + * @return PJ_SUCCESS on success. + */ +PJ_DECL(pj_status_t) pj_atexit(pj_exit_callback func); + + + +/** + * Swap the byte order of an 16bit data. + * + * @param val16 The 16bit data. + * + * @return An 16bit data with swapped byte order. + */ +PJ_INLINE(pj_int16_t) pj_swap16(pj_int16_t val16) +{ + pj_uint8_t *p = (pj_uint8_t*)&val16; + pj_uint8_t tmp = *p; + *p = *(p+1); + *(p+1) = tmp; + return val16; +} + +/** + * Swap the byte order of an 32bit data. + * + * @param val32 The 32bit data. + * + * @return An 32bit data with swapped byte order. + */ +PJ_INLINE(pj_int32_t) pj_swap32(pj_int32_t val32) +{ + pj_uint8_t *p = (pj_uint8_t*)&val32; + pj_uint8_t tmp = *p; + *p = *(p+3); + *(p+3) = tmp; + tmp = *(p+1); + *(p+1) = *(p+2); + *(p+2) = tmp; + return val32; +} + + +/** + * @} + */ +/** + * @addtogroup PJ_TIME Time Data Type and Manipulation. + * @ingroup PJ_MISC + * @{ + */ + +/** + * Representation of time value in this library. + * This type can be used to represent either an interval or a specific time + * or date. + */ +typedef struct pj_time_val +{ + /** The seconds part of the time. */ + long sec; + + /** The miliseconds fraction of the time. */ + long msec; + +} pj_time_val; + +/** + * Normalize the value in time value. + * @param t Time value to be normalized. + */ +PJ_DECL(void) pj_time_val_normalize(pj_time_val *t); + +/** + * Get the total time value in miliseconds. This is the same as + * multiplying the second part with 1000 and then add the miliseconds + * part to the result. + * + * @param t The time value. + * @return Total time in miliseconds. + * @hideinitializer + */ +#define PJ_TIME_VAL_MSEC(t) ((t).sec * 1000 + (t).msec) + +/** + * This macro will check if \a t1 is equal to \a t2. + * + * @param t1 The first time value to compare. + * @param t2 The second time value to compare. + * @return Non-zero if both time values are equal. + * @hideinitializer + */ +#define PJ_TIME_VAL_EQ(t1, t2) ((t1).sec==(t2).sec && (t1).msec==(t2).msec) + +/** + * This macro will check if \a t1 is greater than \a t2 + * + * @param t1 The first time value to compare. + * @param t2 The second time value to compare. + * @return Non-zero if t1 is greater than t2. + * @hideinitializer + */ +#define PJ_TIME_VAL_GT(t1, t2) ((t1).sec>(t2).sec || \ + ((t1).sec==(t2).sec && (t1).msec>(t2).msec)) + +/** + * This macro will check if \a t1 is greater than or equal to \a t2 + * + * @param t1 The first time value to compare. + * @param t2 The second time value to compare. + * @return Non-zero if t1 is greater than or equal to t2. + * @hideinitializer + */ +#define PJ_TIME_VAL_GTE(t1, t2) (PJ_TIME_VAL_GT(t1,t2) || \ + PJ_TIME_VAL_EQ(t1,t2)) + +/** + * This macro will check if \a t1 is less than \a t2 + * + * @param t1 The first time value to compare. + * @param t2 The second time value to compare. + * @return Non-zero if t1 is less than t2. + * @hideinitializer + */ +#define PJ_TIME_VAL_LT(t1, t2) (!(PJ_TIME_VAL_GTE(t1,t2))) + +/** + * This macro will check if \a t1 is less than or equal to \a t2. + * + * @param t1 The first time value to compare. + * @param t2 The second time value to compare. + * @return Non-zero if t1 is less than or equal to t2. + * @hideinitializer + */ +#define PJ_TIME_VAL_LTE(t1, t2) (!PJ_TIME_VAL_GT(t1, t2)) + +/** + * Add \a t2 to \a t1 and store the result in \a t1. Effectively + * + * this macro will expand as: (\a t1 += \a t2). + * @param t1 The time value to add. + * @param t2 The time value to be added to \a t1. + * @hideinitializer + */ +#define PJ_TIME_VAL_ADD(t1, t2) do { \ + (t1).sec += (t2).sec; \ + (t1).msec += (t2).msec; \ + pj_time_val_normalize(&(t1)); \ + } while (0) + + +/** + * Substract \a t2 from \a t1 and store the result in \a t1. Effectively + * this macro will expand as (\a t1 -= \a t2). + * + * @param t1 The time value to subsctract. + * @param t2 The time value to be substracted from \a t1. + * @hideinitializer + */ +#define PJ_TIME_VAL_SUB(t1, t2) do { \ + (t1).sec -= (t2).sec; \ + (t1).msec -= (t2).msec; \ + pj_time_val_normalize(&(t1)); \ + } while (0) + + +/** + * This structure represent the parsed representation of time. + * It is acquired by calling #pj_time_decode(). + */ +typedef struct pj_parsed_time +{ + /** This represents day of week where value zero means Sunday */ + int wday; + + /* This represents day of the year, 0-365, where zero means + * 1st of January. + */ + /*int yday; */ + + /** This represents day of month: 1-31 */ + int day; + + /** This represents month, with the value is 0 - 11 (zero is January) */ + int mon; + + /** This represent the actual year (unlike in ANSI libc where + * the value must be added by 1900). + */ + int year; + + /** This represents the second part, with the value is 0-59 */ + int sec; + + /** This represents the minute part, with the value is: 0-59 */ + int min; + + /** This represents the hour part, with the value is 0-23 */ + int hour; + + /** This represents the milisecond part, with the value is 0-999 */ + int msec; + +} pj_parsed_time; + + +/** + * @} // Time Management + */ + +/* ************************************************************************* */ +/* + * Terminal. + */ +/** + * Color code combination. + */ +enum { + PJ_TERM_COLOR_R = 2, /**< Red */ + PJ_TERM_COLOR_G = 4, /**< Green */ + PJ_TERM_COLOR_B = 1, /**< Blue. */ + PJ_TERM_COLOR_BRIGHT = 8 /**< Bright mask. */ +}; + + + + +PJ_END_DECL + + +#endif /* __PJ_TYPES_H__ */ + diff --git a/pjlib/include/pj/unicode.h b/pjlib/include/pj/unicode.h new file mode 100644 index 0000000..cd41b9a --- /dev/null +++ b/pjlib/include/pj/unicode.h @@ -0,0 +1,141 @@ +/* $Id: unicode.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 + * + * 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_UNICODE_H__ +#define __PJ_UNICODE_H__ + +#include + + +/** + * @defgroup PJ_UNICODE Unicode Support + * @ingroup PJ_MISC + * @{ + */ + +PJ_BEGIN_DECL + + +/** + * @file unicode.h + * @brief Provides Unicode conversion for Unicode OSes + */ + +/** + * Convert ANSI strings to Unicode strings. + * + * @param str The ANSI string to be converted. + * @param len The length of the input string. + * @param wbuf Buffer to hold the Unicode string output. + * @param wbuf_count Buffer size, in number of elements (not bytes). + * + * @return The Unicode string, NULL terminated. + */ +PJ_DECL(wchar_t*) pj_ansi_to_unicode(const char *str, pj_size_t len, + wchar_t *wbuf, pj_size_t wbuf_count); + + +/** + * Convert Unicode string to ANSI string. + * + * @param wstr The Unicode string to be converted. + * @param len The length of the input string. + * @param buf Buffer to hold the ANSI string output. + * @param buf_size Size of the output buffer. + * + * @return The ANSI string, NULL terminated. + */ +PJ_DECL(char*) pj_unicode_to_ansi(const wchar_t *wstr, pj_size_t len, + char *buf, pj_size_t buf_size); + + +#if defined(PJ_NATIVE_STRING_IS_UNICODE) && PJ_NATIVE_STRING_IS_UNICODE!=0 + +/** + * This macro is used to declare temporary Unicode buffer for ANSI to + * Unicode conversion, and should be put in declaration section of a block. + * When PJ_NATIVE_STRING_IS_UNICODE macro is not defined, this + * macro will expand to nothing. + */ +# define PJ_DECL_UNICODE_TEMP_BUF(buf,size) wchar_t buf[size]; + +/** + * This macro will convert ANSI string to native, when the platform's + * native string is Unicode (PJ_NATIVE_STRING_IS_UNICODE is non-zero). + */ +# define PJ_STRING_TO_NATIVE(s,buf,max) pj_ansi_to_unicode( \ + s, strlen(s), \ + buf, max) + +/** + * This macro is used to declare temporary ANSI buffer for Unicode to + * ANSI conversion, and should be put in declaration section of a block. + * When PJ_NATIVE_STRING_IS_UNICODE macro is not defined, this + * macro will expand to nothing. + */ +# define PJ_DECL_ANSI_TEMP_BUF(buf,size) char buf[size]; + + +/** + * This macro will convert Unicode string to ANSI, when the platform's + * native string is Unicode (PJ_NATIVE_STRING_IS_UNICODE is non-zero). + */ +# define PJ_NATIVE_TO_STRING(cs,buf,max) pj_unicode_to_ansi( \ + cs, wcslen(cs), \ + buf, max) + +#else + +/** + * This macro is used to declare temporary Unicode buffer for ANSI to + * Unicode conversion, and should be put in declaration section of a block. + * When PJ_NATIVE_STRING_IS_UNICODE macro is not defined, this + * macro will expand to nothing. + */ +# define PJ_DECL_UNICODE_TEMP_BUF(var,size) +/** + * This macro will convert ANSI string to native, when the platform's + * native string is Unicode (PJ_NATIVE_STRING_IS_UNICODE is non-zero). + */ +# define PJ_STRING_TO_NATIVE(s,buf,max) ((char*)s) +/** + * This macro is used to declare temporary ANSI buffer for Unicode to + * ANSI conversion, and should be put in declaration section of a block. + * When PJ_NATIVE_STRING_IS_UNICODE macro is not defined, this + * macro will expand to nothing. + */ +# define PJ_DECL_ANSI_TEMP_BUF(buf,size) +/** + * This macro will convert Unicode string to ANSI, when the platform's + * native string is Unicode (PJ_NATIVE_STRING_IS_UNICODE is non-zero). + */ +# define PJ_NATIVE_TO_STRING(cs,buf,max) ((char*)(const char*)cs) + +#endif + + + +PJ_END_DECL + +/* + * @} + */ + + +#endif /* __PJ_UNICODE_H__ */ -- cgit v1.2.3