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