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