1 /* $Id$ */ 2 /* 3 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) 4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 #ifndef __PJ_ERRNO_H__ 21 #define __PJ_ERRNO_H__ 22 23 /** 24 * @file errno.h 25 * @brief PJLIB Error Subsystem 26 */ 27 #include <pj/types.h> 28 #include <pj/compat/errno.h> 29 #include <stdarg.h> 30 31 PJ_BEGIN_DECL 32 33 /** 34 * @defgroup pj_errno Error Subsystem 35 * @{ 36 * 37 * The PJLIB Error Subsystem is a framework to unify all error codes 38 * produced by all components into a single error space, and provide 39 * uniform set of APIs to access them. With this framework, any error 40 * codes are encoded as pj_status_t value. The framework is extensible, 41 * application may register new error spaces to be recognized by 42 * the framework. 43 * 44 * @section pj_errno_retval Return Values 45 * 46 * All functions that returns @a pj_status_t returns @a PJ_SUCCESS if the 47 * operation was completed successfully, or non-zero value to indicate 48 * error. If the error came from operating system, then the native error 49 * code is translated/folded into PJLIB's error namespace by using 50 * #PJ_STATUS_FROM_OS() macro. The function will do this automatically 51 * before returning the error to caller. 52 * 53 * @section err_services Retrieving and Displaying Error Messages 54 * 55 * The framework provides the following APIs to retrieve and/or display 56 * error messages: 57 * 58 * - #pj_strerror(): this is the base API to retrieve error string 59 * description for the specified pj_status_t error code. 60 * 61 * - #PJ_PERROR() macro: use this macro similar to PJ_LOG to format 62 * an error message and display them to the log 63 * 64 * - #pj_perror(): this function is similar to PJ_PERROR() but unlike 65 * #PJ_PERROR(), this function will always be included in the 66 * link process. Due to this reason, prefer to use #PJ_PERROR() 67 * if the application is concerned about the executable size. 68 * 69 * Application MUST NOT pass native error codes (such as error code from 70 * functions like GetLastError() or errno) to PJLIB functions expecting 71 * @a pj_status_t. 72 * 73 * @section err_extending Extending the Error Space 74 * 75 * Application may register new error space to be recognized by the 76 * framework by using #pj_register_strerror(). Use the range started 77 * from PJ_ERRNO_START_USER to avoid conflict with existing error 78 * spaces. 79 * 80 */ 81 82 /** 83 * Guidelines on error message length. 84 */ 85 #define PJ_ERR_MSG_SIZE 80 86 87 /** 88 * Buffer for title string of #PJ_PERROR(). 89 */ 90 #ifndef PJ_PERROR_TITLE_BUF_SIZE 91 # define PJ_PERROR_TITLE_BUF_SIZE 120 92 #endif 93 94 95 /** 96 * Get the last platform error/status, folded into pj_status_t. 97 * @return OS dependent error code, folded into pj_status_t. 98 * @remark This function gets errno, or calls GetLastError() function and 99 * convert the code into pj_status_t with PJ_STATUS_FROM_OS. Do 100 * not call this for socket functions! 101 * @see pj_get_netos_error() 102 */ 103 PJ_DECL(pj_status_t) pj_get_os_error(void); 104 105 /** 106 * Set last error. 107 * @param code pj_status_t 108 */ 109 PJ_DECL(void) pj_set_os_error(pj_status_t code); 110 111 /** 112 * Get the last error from socket operations. 113 * @return Last socket error, folded into pj_status_t. 114 */ 115 PJ_DECL(pj_status_t) pj_get_netos_error(void); 116 117 /** 118 * Set error code. 119 * @param code pj_status_t. 120 */ 121 PJ_DECL(void) pj_set_netos_error(pj_status_t code); 122 123 124 /** 125 * Get the error message for the specified error code. The message 126 * string will be NULL terminated. 127 * 128 * @param statcode The error code. 129 * @param buf Buffer to hold the error message string. 130 * @param bufsize Size of the buffer. 131 * 132 * @return The error message as NULL terminated string, 133 * wrapped with pj_str_t. 134 */ 135 PJ_DECL(pj_str_t) pj_strerror( pj_status_t statcode, 136 char *buf, pj_size_t bufsize); 137 138 /** 139 * A utility macro to print error message pertaining to the specified error 140 * code to the log. This macro will construct the error message title 141 * according to the 'title_fmt' argument, and add the error string pertaining 142 * to the error code after the title string. A colon (':') will be added 143 * automatically between the title and the error string. 144 * 145 * This function is similar to pj_perror() function, but has the advantage 146 * that the function call can be omitted from the link process if the 147 * log level argument is below PJ_LOG_MAX_LEVEL threshold. 148 * 149 * Note that the title string constructed from the title_fmt will be built on 150 * a string buffer which size is PJ_PERROR_TITLE_BUF_SIZE, which normally is 151 * allocated from the stack. By default this buffer size is small (around 152 * 120 characters). Application MUST ensure that the constructed title string 153 * will not exceed this limit, since not all platforms support truncating 154 * the string. 155 * 156 * @see pj_perror() 157 * 158 * @param level The logging verbosity level, valid values are 0-6. Lower 159 * number indicates higher importance, with level zero 160 * indicates fatal error. Only numeral argument is 161 * permitted (e.g. not variable). 162 * @param arg Enclosed 'printf' like arguments, with the following 163 * arguments: 164 * - the sender (NULL terminated string), 165 * - the error code (pj_status_t) 166 * - the format string (title_fmt), and 167 * - optional variable number of arguments suitable for the 168 * format string. 169 * 170 * Sample: 171 * \verbatim 172 PJ_PERROR(2, (__FILE__, PJ_EBUSY, "Error making %s", "coffee")); 173 \endverbatim 174 * @hideinitializer 175 */ 176 #define PJ_PERROR(level,arg) do { \ 177 pj_perror_wrapper_##level(arg); \ 178 } while (0) 179 180 /** 181 * A utility function to print error message pertaining to the specified error 182 * code to the log. This function will construct the error message title 183 * according to the 'title_fmt' argument, and add the error string pertaining 184 * to the error code after the title string. A colon (':') will be added 185 * automatically between the title and the error string. 186 * 187 * Unlike the PJ_PERROR() macro, this function takes the \a log_level argument 188 * as a normal argument, unlike in PJ_PERROR() where a numeral value must be 189 * given. However this function will always be linked to the executable, 190 * unlike PJ_PERROR() which can be omitted when the level is below the 191 * PJ_LOG_MAX_LEVEL. 192 * 193 * Note that the title string constructed from the title_fmt will be built on 194 * a string buffer which size is PJ_PERROR_TITLE_BUF_SIZE, which normally is 195 * allocated from the stack. By default this buffer size is small (around 196 * 120 characters). Application MUST ensure that the constructed title string 197 * will not exceed this limit, since not all platforms support truncating 198 * the string. 199 * 200 * @see PJ_PERROR() 201 */ 202 PJ_DECL(void) pj_perror(int log_level, const char *sender, pj_status_t status, 203 const char *title_fmt, ...); 204 205 206 /** 207 * Type of callback to be specified in #pj_register_strerror() 208 * 209 * @param e The error code to lookup. 210 * @param msg Buffer to store the error message. 211 * @param max Length of the buffer. 212 * 213 * @return The error string. 214 */ 215 typedef pj_str_t (*pj_error_callback)(pj_status_t e, char *msg, pj_size_t max); 216 217 218 /** 219 * Register strerror message handler for the specified error space. 220 * Application can register its own handler to supply the error message 221 * for the specified error code range. This handler will be called 222 * by #pj_strerror(). 223 * 224 * @param start_code The starting error code where the handler should 225 * be called to retrieve the error message. 226 * @param err_space The size of error space. The error code range then 227 * will fall in start_code to start_code+err_space-1 228 * range. 229 * @param f The handler to be called when #pj_strerror() is 230 * supplied with error code that falls into this range. 231 * 232 * @return PJ_SUCCESS or the specified error code. The 233 * registration may fail when the error space has been 234 * occupied by other handler, or when there are too many 235 * handlers registered to PJLIB. 236 */ 237 PJ_DECL(pj_status_t) pj_register_strerror(pj_status_t start_code, 238 pj_status_t err_space, 239 pj_error_callback f); 240 241 /** 242 * @hideinitializer 243 * Return platform os error code folded into pj_status_t code. This is 244 * the macro that is used throughout the library for all PJLIB's functions 245 * that returns error from operating system. Application may override 246 * this macro to reduce size (e.g. by defining it to always return 247 * #PJ_EUNKNOWN). 248 * 249 * Note: 250 * This macro MUST return non-zero value regardless whether zero is 251 * passed as the argument. The reason is to protect logic error when 252 * the operating system doesn't report error codes properly. 253 * 254 * @param os_code Platform OS error code. This value may be evaluated 255 * more than once. 256 * @return The platform os error code folded into pj_status_t. 257 */ 258 #ifndef PJ_RETURN_OS_ERROR 259 # define PJ_RETURN_OS_ERROR(os_code) (os_code ? \ 260 PJ_STATUS_FROM_OS(os_code) : -1) 261 #endif 262 263 264 /** 265 * @hideinitializer 266 * Fold a platform specific error into an pj_status_t code. 267 * 268 * @param e The platform os error code. 269 * @return pj_status_t 270 * @warning Macro implementation; the syserr argument may be evaluated 271 * multiple times. 272 */ 273 #if PJ_NATIVE_ERR_POSITIVE 274 # define PJ_STATUS_FROM_OS(e) (e == 0 ? PJ_SUCCESS : e + PJ_ERRNO_START_SYS) 275 #else 276 # define PJ_STATUS_FROM_OS(e) (e == 0 ? PJ_SUCCESS : PJ_ERRNO_START_SYS - e) 277 #endif 278 279 /** 280 * @hideinitializer 281 * Fold an pj_status_t code back to the native platform defined error. 282 * 283 * @param e The pj_status_t folded platform os error code. 284 * @return pj_os_err_type 285 * @warning macro implementation; the statcode argument may be evaluated 286 * multiple times. If the statcode was not created by 287 * pj_get_os_error or PJ_STATUS_FROM_OS, the results are undefined. 288 */ 289 #if PJ_NATIVE_ERR_POSITIVE 290 # define PJ_STATUS_TO_OS(e) (e == 0 ? PJ_SUCCESS : e - PJ_ERRNO_START_SYS) 291 #else 292 # define PJ_STATUS_TO_OS(e) (e == 0 ? PJ_SUCCESS : PJ_ERRNO_START_SYS - e) 293 #endif 294 295 296 /** 297 * @defgroup pj_errnum PJLIB's Own Error Codes 298 * @ingroup pj_errno 299 * @{ 300 */ 301 302 /** 303 * Use this macro to generate error message text for your error code, 304 * so that they look uniformly as the rest of the libraries. 305 * 306 * @param code The error code 307 * @param msg The error test. 308 */ 309 #ifndef PJ_BUILD_ERR 310 # define PJ_BUILD_ERR(code,msg) { code, msg " (" #code ")" } 311 #endif 312 313 314 /** 315 * @hideinitializer 316 * Unknown error has been reported. 317 */ 318 #define PJ_EUNKNOWN (PJ_ERRNO_START_STATUS + 1) /* 70001 */ 319 /** 320 * @hideinitializer 321 * The operation is pending and will be completed later. 322 */ 323 #define PJ_EPENDING (PJ_ERRNO_START_STATUS + 2) /* 70002 */ 324 /** 325 * @hideinitializer 326 * Too many connecting sockets. 327 */ 328 #define PJ_ETOOMANYCONN (PJ_ERRNO_START_STATUS + 3) /* 70003 */ 329 /** 330 * @hideinitializer 331 * Invalid argument. 332 */ 333 #define PJ_EINVAL (PJ_ERRNO_START_STATUS + 4) /* 70004 */ 334 /** 335 * @hideinitializer 336 * Name too long (eg. hostname too long). 337 */ 338 #define PJ_ENAMETOOLONG (PJ_ERRNO_START_STATUS + 5) /* 70005 */ 339 /** 340 * @hideinitializer 341 * Not found. 342 */ 343 #define PJ_ENOTFOUND (PJ_ERRNO_START_STATUS + 6) /* 70006 */ 344 /** 345 * @hideinitializer 346 * Not enough memory. 347 */ 348 #define PJ_ENOMEM (PJ_ERRNO_START_STATUS + 7) /* 70007 */ 349 /** 350 * @hideinitializer 351 * Bug detected! 352 */ 353 #define PJ_EBUG (PJ_ERRNO_START_STATUS + 8) /* 70008 */ 354 /** 355 * @hideinitializer 356 * Operation timed out. 357 */ 358 #define PJ_ETIMEDOUT (PJ_ERRNO_START_STATUS + 9) /* 70009 */ 359 /** 360 * @hideinitializer 361 * Too many objects. 362 */ 363 #define PJ_ETOOMANY (PJ_ERRNO_START_STATUS + 10)/* 70010 */ 364 /** 365 * @hideinitializer 366 * Object is busy. 367 */ 368 #define PJ_EBUSY (PJ_ERRNO_START_STATUS + 11)/* 70011 */ 369 /** 370 * @hideinitializer 371 * The specified option is not supported. 372 */ 373 #define PJ_ENOTSUP (PJ_ERRNO_START_STATUS + 12)/* 70012 */ 374 /** 375 * @hideinitializer 376 * Invalid operation. 377 */ 378 #define PJ_EINVALIDOP (PJ_ERRNO_START_STATUS + 13)/* 70013 */ 379 /** 380 * @hideinitializer 381 * Operation is cancelled. 382 */ 383 #define PJ_ECANCELLED (PJ_ERRNO_START_STATUS + 14)/* 70014 */ 384 /** 385 * @hideinitializer 386 * Object already exists. 387 */ 388 #define PJ_EEXISTS (PJ_ERRNO_START_STATUS + 15)/* 70015 */ 389 /** 390 * @hideinitializer 391 * End of file. 392 */ 393 #define PJ_EEOF (PJ_ERRNO_START_STATUS + 16)/* 70016 */ 394 /** 395 * @hideinitializer 396 * Size is too big. 397 */ 398 #define PJ_ETOOBIG (PJ_ERRNO_START_STATUS + 17)/* 70017 */ 399 /** 400 * @hideinitializer 401 * Error in gethostbyname(). This is a generic error returned when 402 * gethostbyname() has returned an error. 403 */ 404 #define PJ_ERESOLVE (PJ_ERRNO_START_STATUS + 18)/* 70018 */ 405 /** 406 * @hideinitializer 407 * Size is too small. 408 */ 409 #define PJ_ETOOSMALL (PJ_ERRNO_START_STATUS + 19)/* 70019 */ 410 /** 411 * @hideinitializer 412 * Ignored 413 */ 414 #define PJ_EIGNORED (PJ_ERRNO_START_STATUS + 20)/* 70020 */ 415 /** 416 * @hideinitializer 417 * IPv6 is not supported 418 */ 419 #define PJ_EIPV6NOTSUP (PJ_ERRNO_START_STATUS + 21)/* 70021 */ 420 /** 421 * @hideinitializer 422 * Unsupported address family 423 */ 424 #define PJ_EAFNOTSUP (PJ_ERRNO_START_STATUS + 22)/* 70022 */ 425 /** 426 * @hideinitializer 427 * Object no longer exists 428 */ 429 #define PJ_EGONE (PJ_ERRNO_START_STATUS + 23)/* 70023 */ 430 /** 431 * @hideinitializer 432 * Socket is stopped 433 */ 434 #define PJ_ESOCKETSTOP (PJ_ERRNO_START_STATUS + 24)/* 70024 */ 435 436 /** @} */ /* pj_errnum */ 437 438 /** @} */ /* pj_errno */ 439 440 441 /** 442 * PJ_ERRNO_START is where PJLIB specific error values start. 443 */ 444 #define PJ_ERRNO_START 20000 445 446 /** 447 * PJ_ERRNO_SPACE_SIZE is the maximum number of errors in one of 448 * the error/status range below. 449 */ 450 #define PJ_ERRNO_SPACE_SIZE 50000 451 452 /** 453 * PJ_ERRNO_START_STATUS is where PJLIB specific status codes start. 454 * Effectively the error in this class would be 70000 - 119000. 455 */ 456 #define PJ_ERRNO_START_STATUS (PJ_ERRNO_START + PJ_ERRNO_SPACE_SIZE) 457 458 /** 459 * PJ_ERRNO_START_SYS converts platform specific error codes into 460 * pj_status_t values. 461 * Effectively the error in this class would be 120000 - 169000. 462 */ 463 #define PJ_ERRNO_START_SYS (PJ_ERRNO_START_STATUS + PJ_ERRNO_SPACE_SIZE) 464 465 /** 466 * PJ_ERRNO_START_USER are reserved for applications that use error 467 * codes along with PJLIB codes. 468 * Effectively the error in this class would be 170000 - 219000. 469 */ 470 #define PJ_ERRNO_START_USER (PJ_ERRNO_START_SYS + PJ_ERRNO_SPACE_SIZE) 471 472 473 /* 474 * Below are list of error spaces that have been taken so far: 475 * - PJSIP_ERRNO_START (PJ_ERRNO_START_USER) 476 * - PJMEDIA_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE) 477 * - PJSIP_SIMPLE_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*2) 478 * - PJLIB_UTIL_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*3) 479 * - PJNATH_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*4) 480 * - PJMEDIA_AUDIODEV_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*5) 481 * - PJ_SSL_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*6) 482 * - PJMEDIA_VIDEODEV_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*7) 483 */ 484 485 /* Internal */ 486 void pj_errno_clear_handlers(void); 487 488 489 /****** Internal for PJ_PERROR *******/ 490 491 /** 492 * @def pj_perror_wrapper_1(arg) 493 * Internal function to write log with verbosity 1. Will evaluate to 494 * empty expression if PJ_LOG_MAX_LEVEL is below 1. 495 * @param arg Log expression. 496 */ 497 #if PJ_LOG_MAX_LEVEL >= 1 498 #define pj_perror_wrapper_1(arg) pj_perror_1 arg 499 /** Internal function. */ 500 PJ_DECL(void) pj_perror_1(const char *sender, pj_status_t status, 501 const char *title_fmt, ...); 502 #else 503 #define pj_perror_wrapper_1(arg) 504 #endif 505 506 /** 507 * @def pj_perror_wrapper_2(arg) 508 * Internal function to write log with verbosity 2. Will evaluate to 509 * empty expression if PJ_LOG_MAX_LEVEL is below 2. 510 * @param arg Log expression. 511 */ 512 #if PJ_LOG_MAX_LEVEL >= 2 513 #define pj_perror_wrapper_2(arg) pj_perror_2 arg 514 /** Internal function. */ 515 PJ_DECL(void) pj_perror_2(const char *sender, pj_status_t status, 516 const char *title_fmt, ...); 517 #else 518 #define pj_perror_wrapper_2(arg) 519 #endif 520 521 /** 522 * @def pj_perror_wrapper_3(arg) 523 * Internal function to write log with verbosity 3. Will evaluate to 524 * empty expression if PJ_LOG_MAX_LEVEL is below 3. 525 * @param arg Log expression. 526 */ 527 #if PJ_LOG_MAX_LEVEL >= 3 528 #define pj_perror_wrapper_3(arg) pj_perror_3 arg 529 /** Internal function. */ 530 PJ_DECL(void) pj_perror_3(const char *sender, pj_status_t status, 531 const char *title_fmt, ...); 532 #else 533 #define pj_perror_wrapper_3(arg) 534 #endif 535 536 /** 537 * @def pj_perror_wrapper_4(arg) 538 * Internal function to write log with verbosity 4. Will evaluate to 539 * empty expression if PJ_LOG_MAX_LEVEL is below 4. 540 * @param arg Log expression. 541 */ 542 #if PJ_LOG_MAX_LEVEL >= 4 543 #define pj_perror_wrapper_4(arg) pj_perror_4 arg 544 /** Internal function. */ 545 PJ_DECL(void) pj_perror_4(const char *sender, pj_status_t status, 546 const char *title_fmt, ...); 547 #else 548 #define pj_perror_wrapper_4(arg) 549 #endif 550 551 /** 552 * @def pj_perror_wrapper_5(arg) 553 * Internal function to write log with verbosity 5. Will evaluate to 554 * empty expression if PJ_LOG_MAX_LEVEL is below 5. 555 * @param arg Log expression. 556 */ 557 #if PJ_LOG_MAX_LEVEL >= 5 558 #define pj_perror_wrapper_5(arg) pj_perror_5 arg 559 /** Internal function. */ 560 PJ_DECL(void) pj_perror_5(const char *sender, pj_status_t status, 561 const char *title_fmt, ...); 562 #else 563 #define pj_perror_wrapper_5(arg) 564 #endif 565 566 /** 567 * @def pj_perror_wrapper_6(arg) 568 * Internal function to write log with verbosity 6. Will evaluate to 569 * empty expression if PJ_LOG_MAX_LEVEL is below 6. 570 * @param arg Log expression. 571 */ 572 #if PJ_LOG_MAX_LEVEL >= 6 573 #define pj_perror_wrapper_6(arg) pj_perror_6 arg 574 /** Internal function. */ 575 PJ_DECL(void) pj_perror_6(const char *sender, pj_status_t status, 576 const char *title_fmt, ...); 577 #else 578 #define pj_perror_wrapper_6(arg) 579 #endif 580 581 582 583 584 PJ_END_DECL 585 586 #endif /* __PJ_ERRNO_H__ */ 587 588