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