incorporates r159808 from branches/1.4:
[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 int test_for_thread_safety(void);
311
312 #ifdef localtime_r
313 #undef localtime_r
314 #endif
315 #define localtime_r __dont_use_localtime_r_use_ast_localtime_instead__
316
317 int ast_utils_init(void);
318 int ast_wait_for_input(int fd, int ms);
319
320 /*!
321         \brief Try to write string, but wait no more than ms milliseconds
322         before timing out.
323
324         \note If you are calling ast_carefulwrite, it is assumed that you are calling
325         it on a file descriptor that _DOES_ have NONBLOCK set.  This way,
326         there is only one system call made to do a write, unless we actually
327         have a need to wait.  This way, we get better performance.
328 */
329 int ast_carefulwrite(int fd, char *s, int len, int timeoutms);
330
331 /*
332  * Thread management support (should be moved to lock.h or a different header)
333  */
334  
335 #define AST_STACKSIZE 240 * 1024
336
337 #if defined(LOW_MEMORY)
338 #define AST_BACKGROUND_STACKSIZE 48 * 1024
339 #else
340 #define AST_BACKGROUND_STACKSIZE 240 * 1024
341 #endif
342
343 void ast_register_thread(char *name);
344 void ast_unregister_thread(void *id);
345
346 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
347                              void *data, size_t stacksize, const char *file, const char *caller,
348                              int line, const char *start_fn);
349
350 int ast_pthread_create_detached_stack(pthread_t *thread, pthread_attr_t *attr, void*(*start_routine)(void *),
351                                  void *data, size_t stacksize, const char *file, const char *caller,
352                                  int line, const char *start_fn);
353
354 #define ast_pthread_create(a, b, c, d)                          \
355         ast_pthread_create_stack(a, b, c, d,                    \
356                 0, __FILE__, __FUNCTION__, __LINE__, #c)
357
358 #define ast_pthread_create_detached(a, b, c, d)                 \
359         ast_pthread_create_detached_stack(a, b, c, d,           \
360                 0, __FILE__, __FUNCTION__, __LINE__, #c)
361
362 #define ast_pthread_create_background(a, b, c, d)               \
363         ast_pthread_create_stack(a, b, c, d,                    \
364                 AST_BACKGROUND_STACKSIZE,                       \
365                 __FILE__, __FUNCTION__, __LINE__, #c)
366
367 #define ast_pthread_create_detached_background(a, b, c, d)      \
368         ast_pthread_create_detached_stack(a, b, c, d,           \
369                 AST_BACKGROUND_STACKSIZE,                       \
370                 __FILE__, __FUNCTION__, __LINE__, #c)
371
372 /* End of thread management support */
373
374 /*!
375         \brief Process a string to find and replace characters
376         \param start The string to analyze
377         \param find The character to find
378         \param replace_with The character that will replace the one we are looking for
379 */
380 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
381
382 long int ast_random(void);
383
384 #define ast_free free
385
386 /*! 
387  * \brief free() wrapper
388  *
389  * ast_free_ptr should be used when a function pointer for free() needs to be passed
390  * as the argument to a function. Otherwise, astmm will cause seg faults.
391  */
392 #ifdef __AST_DEBUG_MALLOC
393 static void ast_free_ptr(void *ptr) attribute_unused;
394 static void ast_free_ptr(void *ptr)
395 {
396         ast_free(ptr);
397 }
398 #else
399 #define ast_free_ptr ast_free
400 #endif
401
402 #ifndef __AST_DEBUG_MALLOC
403
404 #define MALLOC_FAILURE_MSG \
405         ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
406 /*!
407  * \brief A wrapper for malloc()
408  *
409  * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
410  * message in the case that the allocation fails.
411  *
412  * The argument and return value are the same as malloc()
413  */
414 #define ast_malloc(len) \
415         _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
416
417 AST_INLINE_API(
418 void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func),
419 {
420         void *p;
421
422         if (!(p = malloc(len)))
423                 MALLOC_FAILURE_MSG;
424
425         return p;
426 }
427 )
428
429 /*!
430  * \brief A wrapper for calloc()
431  *
432  * ast_calloc() is a wrapper for calloc() that will generate an Asterisk log
433  * message in the case that the allocation fails.
434  *
435  * The arguments and return value are the same as calloc()
436  */
437 #define ast_calloc(num, len) \
438         _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
439
440 AST_INLINE_API(
441 void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
442 {
443         void *p;
444
445         if (!(p = calloc(num, len)))
446                 MALLOC_FAILURE_MSG;
447
448         return p;
449 }
450 )
451
452 /*!
453  * \brief A wrapper for calloc() for use in cache pools
454  *
455  * ast_calloc_cache() is a wrapper for calloc() that will generate an Asterisk log
456  * message in the case that the allocation fails. When memory debugging is in use,
457  * the memory allocated by this function will be marked as 'cache' so it can be
458  * distinguished from normal memory allocations.
459  *
460  * The arguments and return value are the same as calloc()
461  */
462 #define ast_calloc_cache(num, len) \
463         _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
464
465 /*!
466  * \brief A wrapper for realloc()
467  *
468  * ast_realloc() is a wrapper for realloc() that will generate an Asterisk log
469  * message in the case that the allocation fails.
470  *
471  * The arguments and return value are the same as realloc()
472  */
473 #define ast_realloc(p, len) \
474         _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
475
476 AST_INLINE_API(
477 void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
478 {
479         void *newp;
480
481         if (!(newp = realloc(p, len)))
482                 MALLOC_FAILURE_MSG;
483
484         return newp;
485 }
486 )
487
488 /*!
489  * \brief A wrapper for strdup()
490  *
491  * ast_strdup() is a wrapper for strdup() that will generate an Asterisk log
492  * message in the case that the allocation fails.
493  *
494  * ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL
495  * argument is provided, ast_strdup will return NULL without generating any
496  * kind of error log message.
497  *
498  * The argument and return value are the same as strdup()
499  */
500 #define ast_strdup(str) \
501         _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
502
503 AST_INLINE_API(
504 char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func),
505 {
506         char *newstr = NULL;
507
508         if (str) {
509                 if (!(newstr = strdup(str)))
510                         MALLOC_FAILURE_MSG;
511         }
512
513         return newstr;
514 }
515 )
516
517 /*!
518  * \brief A wrapper for strndup()
519  *
520  * ast_strndup() is a wrapper for strndup() that will generate an Asterisk log
521  * message in the case that the allocation fails.
522  *
523  * ast_strndup(), unlike strndup(), can safely accept a NULL argument for the
524  * string to duplicate. If a NULL argument is provided, ast_strdup will return  
525  * NULL without generating any kind of error log message.
526  *
527  * The arguments and return value are the same as strndup()
528  */
529 #define ast_strndup(str, len) \
530         _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
531
532 AST_INLINE_API(
533 char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
534 {
535         char *newstr = NULL;
536
537         if (str) {
538                 if (!(newstr = strndup(str, len)))
539                         MALLOC_FAILURE_MSG;
540         }
541
542         return newstr;
543 }
544 )
545
546 /*!
547  * \brief A wrapper for asprintf()
548  *
549  * ast_asprintf() is a wrapper for asprintf() that will generate an Asterisk log
550  * message in the case that the allocation fails.
551  *
552  * The arguments and return value are the same as asprintf()
553  */
554 #define ast_asprintf(ret, fmt, ...) \
555         _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
556
557 int __attribute__((format(printf, 5, 6)))
558         _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...);
559
560 /*!
561  * \brief A wrapper for vasprintf()
562  *
563  * ast_vasprintf() is a wrapper for vasprintf() that will generate an Asterisk log
564  * message in the case that the allocation fails.
565  *
566  * The arguments and return value are the same as vasprintf()
567  */
568 #define ast_vasprintf(ret, fmt, ap) \
569         _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
570
571 AST_INLINE_API(
572 __attribute__((format(printf, 5, 0)))
573 int _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
574 {
575         int res;
576
577         if ((res = vasprintf(ret, fmt, ap)) == -1)
578                 MALLOC_FAILURE_MSG;
579
580         return res;
581 }
582 )
583
584 #else
585
586 /* If astmm is in use, let it handle these.  Otherwise, it will report that
587    all allocations are coming from this header file */
588
589 #define ast_malloc(a)           malloc(a)
590 #define ast_calloc(a,b)         calloc(a,b)
591 #define ast_realloc(a,b)        realloc(a,b)
592 #define ast_strdup(a)           strdup(a)
593 #define ast_strndup(a,b)        strndup(a,b)
594 #define ast_asprintf(a,b,...)   asprintf(a,b,__VA_ARGS__)
595 #define ast_vasprintf(a,b,c)    vasprintf(a,b,c)
596
597 #endif /* AST_DEBUG_MALLOC */
598
599 #if !defined(ast_strdupa) && defined(__GNUC__)
600 /*!
601   \brief duplicate a string in memory from the stack
602   \param s The string to duplicate
603
604   This macro will duplicate the given string.  It returns a pointer to the stack
605   allocatted memory for the new string.
606 */
607 #define ast_strdupa(s)                                                    \
608         (__extension__                                                    \
609         ({                                                                \
610                 const char *__old = (s);                                  \
611                 size_t __len = strlen(__old) + 1;                         \
612                 char *__new = __builtin_alloca(__len);                    \
613                 memcpy (__new, __old, __len);                             \
614                 __new;                                                    \
615         }))
616 #endif
617
618 /*!
619   \brief Disable PMTU discovery on a socket
620   \param sock The socket to manipulate
621   \return Nothing
622
623   On Linux, UDP sockets default to sending packets with the Dont Fragment (DF)
624   bit set. This is supposedly done to allow the application to do PMTU
625   discovery, but Asterisk does not do this.
626
627   Because of this, UDP packets sent by Asterisk that are larger than the MTU
628   of any hop in the path will be lost. This function can be called on a socket
629   to ensure that the DF bit will not be set.
630  */
631 void ast_enable_packet_fragmentation(int sock);
632
633 /*!
634   \brief Recursively create directory path
635   \param path The directory path to create
636   \param mode The permissions with which to try to create the directory
637   \return 0 on success or an error code otherwise
638
639   Creates a directory path, creating parent directories as needed.
640  */
641 int ast_mkdir(const char *path, int mode);
642
643 #define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
644
645 #ifdef AST_DEVMODE
646 #define ast_assert(a) _ast_assert(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
647 static void force_inline _ast_assert(int condition, const char *condition_str, 
648         const char *file, int line, const char *function)
649 {
650         if (__builtin_expect(!condition, 1)) {
651                 /* Attempt to put it into the logger, but hope that at least someone saw the
652                  * message on stderr ... */
653                 ast_log(__LOG_ERROR, file, line, function, "FRACK!, Failed assertion %s (%d)\n",
654                         condition_str, condition);
655                 fprintf(stderr, "FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
656                         condition_str, condition, line, function, file);
657                 /* Give the logger a chance to get the message out, just in case we abort(), or
658                  * Asterisk crashes due to whatever problem just happened after we exit ast_assert(). */
659                 usleep(1);
660 #ifdef DO_CRASH
661                 abort();
662                 /* Just in case abort() doesn't work or something else super silly,
663                  * and for Qwell's amusement. */
664                 *((int*)0)=0;
665 #endif
666         }
667 }
668 #else
669 #define ast_assert(a)
670 #endif
671
672 #include "asterisk/strings.h"
673
674 /*!
675  * \brief An Entity ID is essentially a MAC address, brief and unique 
676  */
677 struct ast_eid {
678         unsigned char eid[6];
679 } __attribute__((__packed__));
680
681 /*!
682  * \brief Global EID
683  *
684  * This is set in asterisk.conf, or determined automatically by taking the mac
685  * address of an Ethernet interface on the system.
686  */
687 extern struct ast_eid g_eid;
688
689 /*!
690  * \brief Fill in an ast_eid with the default eid of this machine
691  */
692 void ast_set_default_eid(struct ast_eid *eid);
693
694 /*!
695  * /brief Convert an EID to a string
696  */
697 char *ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid);
698
699 /*!
700  * \brief Convert a string into an EID
701  *
702  * This function expects an EID in the format:
703  *    00:11:22:33:44:55
704  *
705  * \return 0 success, non-zero failure
706  */
707 int ast_str_to_eid(struct ast_eid *eid, const char *s);
708
709 /*!
710  * \brief Compare two EIDs
711  *
712  * \return 0 if the two are the same, non-zero otherwise
713  */
714 int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2);
715
716 #endif /* _ASTERISK_UTILS_H */