Add support for several platforms to obtain the real thread ID.
[asterisk/asterisk.git] / include / asterisk / utils.h
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  * \brief Utility functions
21  */
22
23 #ifndef _ASTERISK_UTILS_H
24 #define _ASTERISK_UTILS_H
25
26 #include "asterisk/network.h"
27
28 #include <time.h>       /* we want to override localtime_r */
29 #include <unistd.h>
30 #include <string.h>
31
32 #include "asterisk/lock.h"
33 #include "asterisk/time.h"
34 #include "asterisk/logger.h"
35 #include "asterisk/localtime.h"
36 #include "asterisk/stringfields.h"
37
38 /*!
39 \note \verbatim
40    Note:
41    It is very important to use only unsigned variables to hold
42    bit flags, as otherwise you can fall prey to the compiler's
43    sign-extension antics if you try to use the top two bits in
44    your variable.
45
46    The flag macros below use a set of compiler tricks to verify
47    that the caller is using an "unsigned int" variable to hold
48    the flags, and nothing else. If the caller uses any other
49    type of variable, a warning message similar to this:
50
51    warning: comparison of distinct pointer types lacks cast
52    will be generated.
53
54    The "dummy" variable below is used to make these comparisons.
55
56    Also note that at -O2 or above, this type-safety checking
57    does _not_ produce any additional object code at all.
58  \endverbatim
59 */
60
61 extern unsigned int __unsigned_int_flags_dummy;
62
63 #define ast_test_flag(p,flag)           ({ \
64                                         typeof ((p)->flags) __p = (p)->flags; \
65                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
66                                         (void) (&__p == &__x); \
67                                         ((p)->flags & (flag)); \
68                                         })
69
70 #define ast_set_flag(p,flag)            do { \
71                                         typeof ((p)->flags) __p = (p)->flags; \
72                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
73                                         (void) (&__p == &__x); \
74                                         ((p)->flags |= (flag)); \
75                                         } while(0)
76
77 #define ast_clear_flag(p,flag)          do { \
78                                         typeof ((p)->flags) __p = (p)->flags; \
79                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
80                                         (void) (&__p == &__x); \
81                                         ((p)->flags &= ~(flag)); \
82                                         } while(0)
83
84 #define ast_copy_flags(dest,src,flagz)  do { \
85                                         typeof ((dest)->flags) __d = (dest)->flags; \
86                                         typeof ((src)->flags) __s = (src)->flags; \
87                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
88                                         (void) (&__d == &__x); \
89                                         (void) (&__s == &__x); \
90                                         (dest)->flags &= ~(flagz); \
91                                         (dest)->flags |= ((src)->flags & (flagz)); \
92                                         } while (0)
93
94 #define ast_set2_flag(p,value,flag)     do { \
95                                         typeof ((p)->flags) __p = (p)->flags; \
96                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
97                                         (void) (&__p == &__x); \
98                                         if (value) \
99                                                 (p)->flags |= (flag); \
100                                         else \
101                                                 (p)->flags &= ~(flag); \
102                                         } while (0)
103
104 #define ast_set_flags_to(p,flag,value)  do { \
105                                         typeof ((p)->flags) __p = (p)->flags; \
106                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
107                                         (void) (&__p == &__x); \
108                                         (p)->flags &= ~(flag); \
109                                         (p)->flags |= (value); \
110                                         } while (0)
111
112
113 /* The following 64-bit flag code can most likely be erased after app_dial
114    is reorganized to either reduce the large number of options, or handle
115    them in some other way. At the time of this writing, app_dial would be
116    the only user of 64-bit option flags */
117
118 extern uint64_t __unsigned_int_flags_dummy64;
119
120 #define ast_test_flag64(p,flag)                 ({ \
121                                         typeof ((p)->flags) __p = (p)->flags; \
122                                         typeof (__unsigned_int_flags_dummy64) __x = 0; \
123                                         (void) (&__p == &__x); \
124                                         ((p)->flags & (flag)); \
125                                         })
126
127 #define ast_set_flag64(p,flag)          do { \
128                                         typeof ((p)->flags) __p = (p)->flags; \
129                                         typeof (__unsigned_int_flags_dummy64) __x = 0; \
130                                         (void) (&__p == &__x); \
131                                         ((p)->flags |= (flag)); \
132                                         } while(0)
133
134 #define ast_clear_flag64(p,flag)                do { \
135                                         typeof ((p)->flags) __p = (p)->flags; \
136                                         typeof (__unsigned_int_flags_dummy64) __x = 0; \
137                                         (void) (&__p == &__x); \
138                                         ((p)->flags &= ~(flag)); \
139                                         } while(0)
140
141 #define ast_copy_flags64(dest,src,flagz)        do { \
142                                         typeof ((dest)->flags) __d = (dest)->flags; \
143                                         typeof ((src)->flags) __s = (src)->flags; \
144                                         typeof (__unsigned_int_flags_dummy64) __x = 0; \
145                                         (void) (&__d == &__x); \
146                                         (void) (&__s == &__x); \
147                                         (dest)->flags &= ~(flagz); \
148                                         (dest)->flags |= ((src)->flags & (flagz)); \
149                                         } while (0)
150
151 #define ast_set2_flag64(p,value,flag)   do { \
152                                         typeof ((p)->flags) __p = (p)->flags; \
153                                         typeof (__unsigned_int_flags_dummy64) __x = 0; \
154                                         (void) (&__p == &__x); \
155                                         if (value) \
156                                                 (p)->flags |= (flag); \
157                                         else \
158                                                 (p)->flags &= ~(flag); \
159                                         } while (0)
160
161 #define ast_set_flags_to64(p,flag,value)        do { \
162                                         typeof ((p)->flags) __p = (p)->flags; \
163                                         typeof (__unsigned_int_flags_dummy64) __x = 0; \
164                                         (void) (&__p == &__x); \
165                                         (p)->flags &= ~(flag); \
166                                         (p)->flags |= (value); \
167                                         } while (0)
168
169
170 /* Non-type checking variations for non-unsigned int flags.  You
171    should only use non-unsigned int flags where required by 
172    protocol etc and if you know what you're doing :)  */
173 #define ast_test_flag_nonstd(p,flag) \
174                                         ((p)->flags & (flag))
175
176 #define ast_set_flag_nonstd(p,flag)             do { \
177                                         ((p)->flags |= (flag)); \
178                                         } while(0)
179
180 #define ast_clear_flag_nonstd(p,flag)           do { \
181                                         ((p)->flags &= ~(flag)); \
182                                         } while(0)
183
184 #define ast_copy_flags_nonstd(dest,src,flagz)   do { \
185                                         (dest)->flags &= ~(flagz); \
186                                         (dest)->flags |= ((src)->flags & (flagz)); \
187                                         } while (0)
188
189 #define ast_set2_flag_nonstd(p,value,flag)      do { \
190                                         if (value) \
191                                                 (p)->flags |= (flag); \
192                                         else \
193                                                 (p)->flags &= ~(flag); \
194                                         } while (0)
195
196 #define AST_FLAGS_ALL UINT_MAX
197
198 /*! \brief Structure used to handle boolean flags 
199 */
200 struct ast_flags {
201         unsigned int flags;
202 };
203
204 /*! \brief Structure used to handle a large number of boolean flags == used only in app_dial?
205 */
206 struct ast_flags64 {
207         uint64_t flags;
208 };
209
210 struct ast_hostent {
211         struct hostent hp;
212         char buf[1024];
213 };
214
215 /*! \brief Thread-safe gethostbyname function to use in Asterisk */
216 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp);
217
218 /*!  \brief Produces MD5 hash based on input string */
219 void ast_md5_hash(char *output, const char *input);
220 /*! \brief Produces SHA1 hash based on input string */
221 void ast_sha1_hash(char *output, const char *input);
222
223 int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks);
224
225 #undef MIN
226 #define MIN(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); ((__a > __b) ? __b : __a);})
227 #undef MAX
228 #define MAX(a, b) ({ typeof(a) __a = (a); typeof(b) __b = (b); ((__a < __b) ? __b : __a);})
229
230 /*!
231  * \brief Encode data in base64
232  * \param dst the destination buffer
233  * \param src the source data to be encoded
234  * \param srclen the number of bytes present in the source buffer
235  * \param max the maximum number of bytes to write into the destination
236  *        buffer, *including* the terminating NULL character.
237  */
238 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max);
239
240 /*!
241  * \brief Decode data from base64
242  * \param dst the destination buffer
243  * \param src the source buffer
244  * \param max The maximum number of bytes to write into the destination
245  *            buffer.  Note that this function will not ensure that the
246  *            destination buffer is NULL terminated.  So, in general,
247  *            this parameter should be sizeof(dst) - 1.
248  */
249 int ast_base64decode(unsigned char *dst, const char *src, int max);
250
251 /*! \brief Turn text string to URI-encoded %XX version 
252  *
253  * \note 
254  *  At this point, this function is encoding agnostic; it does not
255  *  check whether it is fed legal UTF-8. We escape control
256  *  characters (\x00-\x1F\x7F), '%', and all characters above 0x7F.
257  *  If do_special_char == 1 we will convert all characters except alnum
258  *  and the mark set.
259  *  Outbuf needs to have more memory allocated than the instring
260  *  to have room for the expansion. Every char that is converted
261  *  is replaced by three ASCII characters.
262  *
263  *  \param string       String to be converted
264  *  \param outbuf       Resulting encoded string
265  *  \param buflen       Size of output buffer
266  *  \param do_special_char      Convert all non alphanum characters execept
267  *         those in the mark set as defined by rfc 3261 section 25.1
268  */
269 char *ast_uri_encode(const char *string, char *outbuf, int buflen, int do_special_char);
270
271 /*!     \brief Decode URI, URN, URL (overwrite string)
272         \param s        String to be decoded 
273  */
274 void ast_uri_decode(char *s);
275
276 static force_inline void ast_slinear_saturated_add(short *input, short *value)
277 {
278         int res;
279
280         res = (int) *input + *value;
281         if (res > 32767)
282                 *input = 32767;
283         else if (res < -32767)
284                 *input = -32767;
285         else
286                 *input = (short) res;
287 }
288
289 static force_inline void ast_slinear_saturated_subtract(short *input, short *value)
290 {
291         int res;
292
293         res = (int) *input - *value;
294         if (res > 32767)
295                 *input = 32767;
296         else if (res < -32767)
297                 *input = -32767;
298         else
299                 *input = (short) res;
300 }
301         
302 static force_inline void ast_slinear_saturated_multiply(short *input, short *value)
303 {
304         int res;
305
306         res = (int) *input * *value;
307         if (res > 32767)
308                 *input = 32767;
309         else if (res < -32767)
310                 *input = -32767;
311         else
312                 *input = (short) res;
313 }
314
315 static force_inline void ast_slinear_saturated_divide(short *input, short *value)
316 {
317         *input /= *value;
318 }
319
320 #ifdef localtime_r
321 #undef localtime_r
322 #endif
323 #define localtime_r __dont_use_localtime_r_use_ast_localtime_instead__
324
325 int ast_utils_init(void);
326 int ast_wait_for_input(int fd, int ms);
327
328 /*!
329         \brief Try to write string, but wait no more than ms milliseconds
330         before timing out.
331
332         \note If you are calling ast_carefulwrite, it is assumed that you are calling
333         it on a file descriptor that _DOES_ have NONBLOCK set.  This way,
334         there is only one system call made to do a write, unless we actually
335         have a need to wait.  This way, we get better performance.
336 */
337 int ast_carefulwrite(int fd, char *s, int len, int timeoutms);
338
339 /*!
340  * \brief Write data to a file stream with a timeout
341  *
342  * \param f the file stream to write to
343  * \param fd the file description to poll on to know when the file stream can
344  *        be written to without blocking.
345  * \param s the buffer to write from
346  * \param len the number of bytes to write
347  * \param timeoutms The maximum amount of time to block in this function trying
348  *        to write, specified in milliseconds.
349  *
350  * \note This function assumes that the associated file stream has been set up
351  *       as non-blocking.
352  *
353  * \retval 0 success
354  * \retval -1 error
355  */
356 int ast_careful_fwrite(FILE *f, int fd, const char *s, size_t len, int timeoutms);
357
358 /*
359  * Thread management support (should be moved to lock.h or a different header)
360  */
361
362 #define AST_STACKSIZE (((sizeof(void *) * 8 * 8) - 16) * 1024)
363
364 #if defined(LOW_MEMORY)
365 #define AST_BACKGROUND_STACKSIZE (((sizeof(void *) * 8 * 2) - 16) * 1024)
366 #else
367 #define AST_BACKGROUND_STACKSIZE AST_STACKSIZE
368 #endif
369
370 void ast_register_thread(char *name);
371 void ast_unregister_thread(void *id);
372
373 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
374                              void *data, size_t stacksize, const char *file, const char *caller,
375                              int line, const char *start_fn);
376
377 int ast_pthread_create_detached_stack(pthread_t *thread, pthread_attr_t *attr, void*(*start_routine)(void *),
378                                  void *data, size_t stacksize, const char *file, const char *caller,
379                                  int line, const char *start_fn);
380
381 #define ast_pthread_create(a, b, c, d)                          \
382         ast_pthread_create_stack(a, b, c, d,                    \
383                 0, __FILE__, __FUNCTION__, __LINE__, #c)
384
385 #define ast_pthread_create_detached(a, b, c, d)                 \
386         ast_pthread_create_detached_stack(a, b, c, d,           \
387                 0, __FILE__, __FUNCTION__, __LINE__, #c)
388
389 #define ast_pthread_create_background(a, b, c, d)               \
390         ast_pthread_create_stack(a, b, c, d,                    \
391                 AST_BACKGROUND_STACKSIZE,                       \
392                 __FILE__, __FUNCTION__, __LINE__, #c)
393
394 #define ast_pthread_create_detached_background(a, b, c, d)      \
395         ast_pthread_create_detached_stack(a, b, c, d,           \
396                 AST_BACKGROUND_STACKSIZE,                       \
397                 __FILE__, __FUNCTION__, __LINE__, #c)
398
399 /* End of thread management support */
400
401 /*!
402         \brief Process a string to find and replace characters
403         \param start The string to analyze
404         \param find The character to find
405         \param replace_with The character that will replace the one we are looking for
406 */
407 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
408
409 long int ast_random(void);
410
411
412 /*! 
413  * \brief free() wrapper
414  *
415  * ast_free_ptr should be used when a function pointer for free() needs to be passed
416  * as the argument to a function. Otherwise, astmm will cause seg faults.
417  */
418 #ifdef __AST_DEBUG_MALLOC
419 static void ast_free_ptr(void *ptr) attribute_unused;
420 static void ast_free_ptr(void *ptr)
421 {
422         ast_free(ptr);
423 }
424 #else
425 #define ast_free free
426 #define ast_free_ptr ast_free
427 #endif
428
429 #ifndef __AST_DEBUG_MALLOC
430
431 #define MALLOC_FAILURE_MSG \
432         ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
433 /*!
434  * \brief A wrapper for malloc()
435  *
436  * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
437  * message in the case that the allocation fails.
438  *
439  * The argument and return value are the same as malloc()
440  */
441 #define ast_malloc(len) \
442         _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
443
444 AST_INLINE_API(
445 void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func),
446 {
447         void *p;
448
449         if (!(p = malloc(len)))
450                 MALLOC_FAILURE_MSG;
451
452         return p;
453 }
454 )
455
456 /*!
457  * \brief A wrapper for calloc()
458  *
459  * ast_calloc() is a wrapper for calloc() that will generate an Asterisk log
460  * message in the case that the allocation fails.
461  *
462  * The arguments and return value are the same as calloc()
463  */
464 #define ast_calloc(num, len) \
465         _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
466
467 AST_INLINE_API(
468 void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
469 {
470         void *p;
471
472         if (!(p = calloc(num, len)))
473                 MALLOC_FAILURE_MSG;
474
475         return p;
476 }
477 )
478
479 /*!
480  * \brief A wrapper for calloc() for use in cache pools
481  *
482  * ast_calloc_cache() is a wrapper for calloc() that will generate an Asterisk log
483  * message in the case that the allocation fails. When memory debugging is in use,
484  * the memory allocated by this function will be marked as 'cache' so it can be
485  * distinguished from normal memory allocations.
486  *
487  * The arguments and return value are the same as calloc()
488  */
489 #define ast_calloc_cache(num, len) \
490         _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
491
492 /*!
493  * \brief A wrapper for realloc()
494  *
495  * ast_realloc() is a wrapper for realloc() that will generate an Asterisk log
496  * message in the case that the allocation fails.
497  *
498  * The arguments and return value are the same as realloc()
499  */
500 #define ast_realloc(p, len) \
501         _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
502
503 AST_INLINE_API(
504 void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
505 {
506         void *newp;
507
508         if (!(newp = realloc(p, len)))
509                 MALLOC_FAILURE_MSG;
510
511         return newp;
512 }
513 )
514
515 /*!
516  * \brief A wrapper for strdup()
517  *
518  * ast_strdup() is a wrapper for strdup() that will generate an Asterisk log
519  * message in the case that the allocation fails.
520  *
521  * ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL
522  * argument is provided, ast_strdup will return NULL without generating any
523  * kind of error log message.
524  *
525  * The argument and return value are the same as strdup()
526  */
527 #define ast_strdup(str) \
528         _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
529
530 AST_INLINE_API(
531 char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func),
532 {
533         char *newstr = NULL;
534
535         if (str) {
536                 if (!(newstr = strdup(str)))
537                         MALLOC_FAILURE_MSG;
538         }
539
540         return newstr;
541 }
542 )
543
544 /*!
545  * \brief A wrapper for strndup()
546  *
547  * ast_strndup() is a wrapper for strndup() that will generate an Asterisk log
548  * message in the case that the allocation fails.
549  *
550  * ast_strndup(), unlike strndup(), can safely accept a NULL argument for the
551  * string to duplicate. If a NULL argument is provided, ast_strdup will return  
552  * NULL without generating any kind of error log message.
553  *
554  * The arguments and return value are the same as strndup()
555  */
556 #define ast_strndup(str, len) \
557         _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
558
559 AST_INLINE_API(
560 char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
561 {
562         char *newstr = NULL;
563
564         if (str) {
565                 if (!(newstr = strndup(str, len)))
566                         MALLOC_FAILURE_MSG;
567         }
568
569         return newstr;
570 }
571 )
572
573 /*!
574  * \brief A wrapper for asprintf()
575  *
576  * ast_asprintf() is a wrapper for asprintf() that will generate an Asterisk log
577  * message in the case that the allocation fails.
578  *
579  * The arguments and return value are the same as asprintf()
580  */
581 #define ast_asprintf(ret, fmt, ...) \
582         _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
583
584 int __attribute__((format(printf, 5, 6)))
585         _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...);
586
587 /*!
588  * \brief A wrapper for vasprintf()
589  *
590  * ast_vasprintf() is a wrapper for vasprintf() that will generate an Asterisk log
591  * message in the case that the allocation fails.
592  *
593  * The arguments and return value are the same as vasprintf()
594  */
595 #define ast_vasprintf(ret, fmt, ap) \
596         _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
597
598 AST_INLINE_API(
599 __attribute__((format(printf, 5, 0)))
600 int _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
601 {
602         int res;
603
604         if ((res = vasprintf(ret, fmt, ap)) == -1)
605                 MALLOC_FAILURE_MSG;
606
607         return res;
608 }
609 )
610
611 #endif /* AST_DEBUG_MALLOC */
612
613 #if !defined(ast_strdupa) && defined(__GNUC__)
614 /*!
615   \brief duplicate a string in memory from the stack
616   \param s The string to duplicate
617
618   This macro will duplicate the given string.  It returns a pointer to the stack
619   allocatted memory for the new string.
620 */
621 #define ast_strdupa(s)                                                    \
622         (__extension__                                                    \
623         ({                                                                \
624                 const char *__old = (s);                                  \
625                 size_t __len = strlen(__old) + 1;                         \
626                 char *__new = __builtin_alloca(__len);                    \
627                 memcpy (__new, __old, __len);                             \
628                 __new;                                                    \
629         }))
630 #endif
631
632 /*!
633   \brief Disable PMTU discovery on a socket
634   \param sock The socket to manipulate
635   \return Nothing
636
637   On Linux, UDP sockets default to sending packets with the Dont Fragment (DF)
638   bit set. This is supposedly done to allow the application to do PMTU
639   discovery, but Asterisk does not do this.
640
641   Because of this, UDP packets sent by Asterisk that are larger than the MTU
642   of any hop in the path will be lost. This function can be called on a socket
643   to ensure that the DF bit will not be set.
644  */
645 void ast_enable_packet_fragmentation(int sock);
646
647 /*!
648   \brief Recursively create directory path
649   \param path The directory path to create
650   \param mode The permissions with which to try to create the directory
651   \return 0 on success or an error code otherwise
652
653   Creates a directory path, creating parent directories as needed.
654  */
655 int ast_mkdir(const char *path, int mode);
656
657 #define ARRAY_LEN(a) (sizeof(a) / sizeof(0[a]))
658
659
660 /* Definition for Digest authorization */
661 struct ast_http_digest {
662         AST_DECLARE_STRING_FIELDS(
663                 AST_STRING_FIELD(username);
664                 AST_STRING_FIELD(nonce);
665                 AST_STRING_FIELD(uri);
666                 AST_STRING_FIELD(realm);
667                 AST_STRING_FIELD(domain);
668                 AST_STRING_FIELD(response);
669                 AST_STRING_FIELD(cnonce);
670                 AST_STRING_FIELD(opaque);
671                 AST_STRING_FIELD(nc);
672         );
673         int qop;                /* Flag set to 1, if we send/recv qop="quth" */
674 };
675
676 /*!
677  *\brief Parse digest authorization header.
678  *\return Returns -1 if we have no auth or something wrong with digest.
679  *\note This function may be used for Digest request and responce header.
680  * request arg is set to nonzero, if we parse Digest Request.
681  * pedantic arg can be set to nonzero if we need to do addition Digest check.
682  */
683 int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic);
684
685
686 #ifdef AST_DEVMODE
687 #define ast_assert(a) _ast_assert(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
688 static void force_inline _ast_assert(int condition, const char *condition_str, 
689         const char *file, int line, const char *function)
690 {
691         if (__builtin_expect(!condition, 1)) {
692                 /* Attempt to put it into the logger, but hope that at least someone saw the
693                  * message on stderr ... */
694                 ast_log(__LOG_ERROR, file, line, function, "FRACK!, Failed assertion %s (%d)\n",
695                         condition_str, condition);
696                 fprintf(stderr, "FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
697                         condition_str, condition, line, function, file);
698                 /* Give the logger a chance to get the message out, just in case we abort(), or
699                  * Asterisk crashes due to whatever problem just happened after we exit ast_assert(). */
700                 usleep(1);
701 #ifdef DO_CRASH
702                 abort();
703                 /* Just in case abort() doesn't work or something else super silly,
704                  * and for Qwell's amusement. */
705                 *((int*)0)=0;
706 #endif
707         }
708 }
709 #else
710 #define ast_assert(a)
711 #endif
712
713 #include "asterisk/strings.h"
714
715 /*!
716  * \brief An Entity ID is essentially a MAC address, brief and unique 
717  */
718 struct ast_eid {
719         unsigned char eid[6];
720 } __attribute__((__packed__));
721
722 /*!
723  * \brief Global EID
724  *
725  * This is set in asterisk.conf, or determined automatically by taking the mac
726  * address of an Ethernet interface on the system.
727  */
728 extern struct ast_eid ast_eid_default;
729
730 /*!
731  * \brief Fill in an ast_eid with the default eid of this machine
732  * \since 1.6.1
733  */
734 void ast_set_default_eid(struct ast_eid *eid);
735
736 /*!
737  * /brief Convert an EID to a string
738  * \since 1.6.1
739  */
740 char *ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid);
741
742 /*!
743  * \brief Convert a string into an EID
744  *
745  * This function expects an EID in the format:
746  *    00:11:22:33:44:55
747  *
748  * \return 0 success, non-zero failure
749  * \since 1.6.1
750  */
751 int ast_str_to_eid(struct ast_eid *eid, const char *s);
752
753 /*!
754  * \brief Compare two EIDs
755  *
756  * \return 0 if the two are the same, non-zero otherwise
757  * \since 1.6.1
758  */
759 int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2);
760
761 /*!
762  * \brief Get current thread ID
763  * \param None
764  * \return the ID if platform is supported, else -1
765  */
766 int ast_get_tid(void);
767
768 #endif /* _ASTERISK_UTILS_H */