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 */

Generated on Wed Oct 28 15:47:56 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6