Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:47:56 2009

## Asterisk developer's documentation

# utils.h

Go to the documentation of this file.

    00001 /*
    00002  * Asterisk -- An open source telephony toolkit.
    00003  *
    00004  * Copyright (C) 1999 - 2005, Digium, Inc.
    00005  *
    00006  * Mark Spencer <markster@digium.com>
    00007  *
    00008  * See http://www.asterisk.org for more information about
    00009  * the Asterisk project. Please do not directly contact
    00010  * any of the maintainers of this project for assistance;
    00011  * the project provides a web site, mailing lists and IRC
    00012  * channels for your use.
    00013  *
    00014  * This program is free software, distributed under the terms of
    00015  * the GNU General Public License Version 2. See the LICENSE file
    00016  * at the top of the source tree.
    00017  */
    00018
    00019 /*! \file
    00020  * \brief Utility functions
    00021  */
    00022
    00023 #ifndef _ASTERISK_UTILS_H
    00024 #define _ASTERISK_UTILS_H
    00025
    00026 #include "asterisk/compat.h"
    00027
    00028 #include <netinet/in.h>
    00029 #include <arpa/inet.h>  /* we want to override inet_ntoa */
    00030 #include <netdb.h>
    00031 #include <limits.h>
    00032
    00033 #include "asterisk/lock.h"
    00034 #include "asterisk/time.h"
    00035 #include "asterisk/strings.h"
    00036
    00037 /*! \note
    00038  \verbatim
    00039    Note:
    00040    It is very important to use only unsigned variables to hold
    00041    bit flags, as otherwise you can fall prey to the compiler's
    00042    sign-extension antics if you try to use the top two bits in
    00043    your variable.
    00044
    00045    The flag macros below use a set of compiler tricks to verify
    00046    that the caller is using an "unsigned int" variable to hold
    00047    the flags, and nothing else. If the caller uses any other
    00048    type of variable, a warning message similar to this:
    00049
    00050    warning: comparison of distinct pointer types lacks cast
    00051    will be generated.
    00052
    00053    The "dummy" variable below is used to make these comparisons.
    00054
    00055    Also note that at -O2 or above, this type-safety checking
    00056    does _not_ produce any additional object code at all.
    00057  \endverbatim
    00058 */
    00059
    00060 extern unsigned int __unsigned_int_flags_dummy;
    00061
    00062 #define ast_test_flag(p,flag)       ({ \
    00063                typeof ((p)->flags) __p = (p)->flags; \
    00064                typeof (__unsigned_int_flags_dummy) __x = 0; \
    00065                (void) (&__p == &__x); \
    00066                ((p)->flags & (flag)); \
    00067                })
    00068
    00069 #define ast_set_flag(p,flag)     do { \
    00070                typeof ((p)->flags) __p = (p)->flags; \
    00071                typeof (__unsigned_int_flags_dummy) __x = 0; \
    00072                (void) (&__p == &__x); \
    00073                ((p)->flags |= (flag)); \
    00074                } while(0)
    00075
    00076 #define ast_clear_flag(p,flag)      do { \
    00077                typeof ((p)->flags) __p = (p)->flags; \
    00078                typeof (__unsigned_int_flags_dummy) __x = 0; \
    00079                (void) (&__p == &__x); \
    00080                ((p)->flags &= ~(flag)); \
    00081                } while(0)
    00082
    00083 #define ast_copy_flags(dest,src,flagz) do { \
    00084                typeof ((dest)->flags) __d = (dest)->flags; \
    00085                typeof ((src)->flags) __s = (src)->flags; \
    00086                typeof (__unsigned_int_flags_dummy) __x = 0; \
    00087                (void) (&__d == &__x); \
    00088                (void) (&__s == &__x); \
    00089                (dest)->flags &= ~(flagz); \
    00090                (dest)->flags |= ((src)->flags & (flagz)); \
    00091                } while (0)
    00092
    00093 #define ast_set2_flag(p,value,flag) do { \
    00094                typeof ((p)->flags) __p = (p)->flags; \
    00095                typeof (__unsigned_int_flags_dummy) __x = 0; \
    00096                (void) (&__p == &__x); \
    00097                if (value) \
    00098                   (p)->flags |= (flag); \
    00099                else \
    00100                   (p)->flags &= ~(flag); \
    00101                } while (0)
    00102
    00103 /* Non-type checking variations for non-unsigned int flags.  You
    00104    should only use non-unsigned int flags where required by
    00105    protocol etc and if you know what you're doing :)  */
    00106 #define ast_test_flag_nonstd(p,flag)      ({ \
    00107                ((p)->flags & (flag)); \
    00108                })
    00109
    00110 #define ast_set_flag_nonstd(p,flag)       do { \
    00111                ((p)->flags |= (flag)); \
    00112                } while(0)
    00113
    00114 #define ast_clear_flag_nonstd(p,flag)     do { \
    00115                ((p)->flags &= ~(flag)); \
    00116                } while(0)
    00117
    00118 #define ast_copy_flags_nonstd(dest,src,flagz)   do { \
    00119                (dest)->flags &= ~(flagz); \
    00120                (dest)->flags |= ((src)->flags & (flagz)); \
    00121                } while (0)
    00122
    00123 #define ast_set2_flag_nonstd(p,value,flag)   do { \
    00124                if (value) \
    00125                   (p)->flags |= (flag); \
    00126                else \
    00127                   (p)->flags &= ~(flag); \
    00128                } while (0)
    00129
    00130 #define AST_FLAGS_ALL UINT_MAX
    00131
    00132 struct ast_flags {
    00133    unsigned int flags;
    00134 };
    00135
    00136 struct ast_hostent {
    00137    struct hostent hp;
    00138    char buf[1024];
    00139 };
    00140
    00141 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp);
    00142
    00143 /* ast_md5_hash
    00144    \brief Produces MD5 hash based on input string */
    00145 void ast_md5_hash(char *output, char *input);
    00146
    00147 /* ast_sha1_hash
    00148    \brief Produces SHA1 hash based on input string */
    00149 void ast_sha1_hash(char *output, char *input);
    00150
    00151 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max);
    00152 int ast_base64decode(unsigned char *dst, const char *src, int max);
    00153
    00154 /*! ast_uri_encode
    00155    \brief Turn text string to URI-encoded %XX version
    00156    At this point, we're converting from ISO-8859-x (8-bit), not UTF8
    00157    as in the SIP protocol spec
    00158    If doreserved == 1 we will convert reserved characters also.
    00159    RFC 2396, section 2.4
    00160    outbuf needs to have more memory allocated than the instring
    00161    to have room for the expansion. Every char that is converted
    00162    is replaced by three ASCII characters.
    00163    \param string  String to be converted
    00164    \param outbuf  Resulting encoded string
    00165    \param buflen  Size of output buffer
    00166    \param doreserved Convert reserved characters
    00167 */
    00168
    00169 char *ast_uri_encode(char *string, char *outbuf, int buflen, int doreserved);
    00170
    00171 /*!   \brief Decode URI, URN, URL (overwrite string)
    00172    \param s String to be decoded
    00173  */
    00174 void ast_uri_decode(char *s);
    00175
    00176 static force_inline void ast_slinear_saturated_add(short *input, short *value)
    00177 {
    00178    int res;
    00179
    00180    res = (int) *input + *value;
    00181    if (res > 32767)
    00182       *input = 32767;
    00183    else if (res < -32767)
    00184       *input = -32767;
    00185    else
    00186       *input = (short) res;
    00187 }
    00188
    00189 static force_inline void ast_slinear_saturated_multiply(short *input, short *value)
    00190 {
    00191    int res;
    00192
    00193    res = (int) *input * *value;
    00194    if (res > 32767)
    00195       *input = 32767;
    00196    else if (res < -32767)
    00197       *input = -32767;
    00198    else
    00199       *input = (short) res;
    00200 }
    00201
    00202 static force_inline void ast_slinear_saturated_divide(short *input, short *value)
    00203 {
    00204    *input /= *value;
    00205 }
    00206
    00207 int test_for_thread_safety(void);
    00208
    00209 const char *ast_inet_ntoa(char *buf, int bufsiz, struct in_addr ia);
    00210
    00211 #ifdef inet_ntoa
    00212 #undef inet_ntoa
    00213 #endif
    00214 #define inet_ntoa __dont__use__inet_ntoa__use__ast_inet_ntoa__instead__
    00215
    00216 int ast_utils_init(void);
    00217 int ast_wait_for_input(int fd, int ms);
    00218
    00219 /*! Compares the source address and port of two sockaddr_in */
    00220 static force_inline int inaddrcmp(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2)
    00221 {
    00222    return ((sin1->sin_addr.s_addr != sin2->sin_addr.s_addr)
    00223       || (sin1->sin_port != sin2->sin_port));
    00224 }
    00225
    00226 #define AST_STACKSIZE 256 * 1024
    00227 #define ast_pthread_create(a,b,c,d) ast_pthread_create_stack(a,b,c,d,0)
    00228 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize);
    00229
    00230 /*!
    00231    \brief Process a string to find and replace characters
    00232    \param start The string to analyze
    00233    \param find The character to find
    00234    \param replace_with The character that will replace the one we are looking for
    00235 */
    00236 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
    00237
    00238 #ifndef HAVE_GETLOADAVG
    00239 int getloadavg(double *list, int nelem);
    00240 #endif
    00241
    00242 /*!
    00243   \brief Disable PMTU discovery on a socket
    00244   \param sock The socket to manipulate
    00245   \return Nothing
    00246
    00247   On Linux, UDP sockets default to sending packets with the Dont Fragment (DF)
    00248   bit set. This is supposedly done to allow the application to do PMTU
    00249   discovery, but Asterisk does not do this.
    00250
    00251   Because of this, UDP packets sent by Asterisk that are larger than the MTU
    00252   of any hop in the path will be lost. This function can be called on a socket
    00253   to ensure that the DF bit will not be set.
    00254  */
    00255 void ast_enable_packet_fragmentation(int sock);
    00256
    00257 #endif /* _ASTERISK_UTILS_H */