| /* $Id: errno.h 4461 2013-04-05 03:02:19Z riza $ */ |
| /* |
| * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) |
| * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org> |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| */ |
| #ifndef __PJ_ERRNO_H__ |
| #define __PJ_ERRNO_H__ |
| |
| /** |
| * @file errno.h |
| * @brief PJLIB Error Subsystem |
| */ |
| #include <pj/types.h> |
| #include <pj/compat/errno.h> |
| #include <stdarg.h> |
| |
| 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 */ |
| /** |
| * @hideinitializer |
| * Object no longer exists |
| */ |
| #define PJ_EGONE (PJ_ERRNO_START_STATUS + 23)/* 70023 */ |
| /** |
| * @hideinitializer |
| * Socket is stopped |
| */ |
| #define PJ_ESOCKETSTOP (PJ_ERRNO_START_STATUS + 24)/* 70024 */ |
| |
| /** @} */ /* 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__ */ |
| |