CHANGES: Change md file extension to txt.
[asterisk/asterisk.git] / channels / iax2 / parser.c
index ee4a6c3..8683938 100644 (file)
@@ -20,7 +20,7 @@
  *
  * \brief Implementation of Inter-Asterisk eXchange Protocol, v 2
  *
- * \author Mark Spencer <markster@digium.com> 
+ * \author Mark Spencer <markster@digium.com>
  */
 
 /*** MODULEINFO
@@ -29,8 +29,6 @@
 
 #include "asterisk.h"
 
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -42,16 +40,23 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/lock.h"
 #include "asterisk/threadstorage.h"
 #include "asterisk/netsock2.h"
+#include "asterisk/format_cache.h"
+#include "asterisk/format_compatibility.h"
 
 #include "include/iax2.h"
 #include "include/parser.h"
 #include "include/provision.h"
+#include "include/codec_pref.h"
 
 static int frames = 0;
 static int iframes = 0;
 static int oframes = 0;
 
-#if !defined(LOW_MEMORY)
+#if (defined(LOW_MEMORY) || defined(MALLOC_DEBUG)) && !defined(NO_FRAME_CACHE)
+#define NO_FRAME_CACHE
+#endif
+
+#if !defined(NO_FRAME_CACHE)
 static void frame_cache_cleanup(void *data);
 
 /*! \brief A per-thread cache of iax_frame structures */
@@ -108,7 +113,7 @@ static void dump_string_hex(char *output, int maxlen, void *value, int len)
        int i = 0;
 
        while (len-- && (i + 1) * 4 < maxlen) {
-               sprintf(output + (4 * i), "\\x%2.2x", *((unsigned char *)value + i));
+               sprintf(output + (4 * i), "\\x%02hhx", *((unsigned char *)value + i));
                i++;
        }
 }
@@ -124,7 +129,7 @@ static void dump_string(char *output, int maxlen, void *value, int len)
 
 static void dump_prefs(char *output, int maxlen, void *value, int len)
 {
-       struct ast_codec_pref pref;
+       struct iax2_codec_pref pref;
        int total_len = 0;
 
        maxlen--;
@@ -135,10 +140,10 @@ static void dump_prefs(char *output, int maxlen, void *value, int len)
 
        strncpy(output, value, maxlen);
        output[maxlen] = '\0';
-       
-       ast_codec_pref_convert(&pref, output, total_len, 0);
+
+       iax2_codec_pref_convert(&pref, output, total_len, 0);
        memset(output,0,total_len);
-       ast_codec_pref_string(&pref, output, total_len);
+       iax2_codec_pref_string(&pref, output, total_len);
 }
 
 static void dump_int(char *output, int maxlen, void *value, int len)
@@ -146,7 +151,7 @@ static void dump_int(char *output, int maxlen, void *value, int len)
        if (len == (int)sizeof(unsigned int))
                snprintf(output, maxlen, "%lu", (unsigned long)ntohl(get_unaligned_uint32(value)));
        else
-               ast_copy_string(output, "Invalid INT", maxlen); 
+               ast_copy_string(output, "Invalid INT", maxlen);
 }
 
 static void dump_short(char *output, int maxlen, void *value, int len)
@@ -176,7 +181,7 @@ static void dump_datetime(char *output, int maxlen, void *value, int len)
                tm.tm_mday = (val >> 16) & 0x1f;
                tm.tm_mon  = ((val >> 21) & 0x0f) - 1;
                tm.tm_year = ((val >> 25) & 0x7f) + 100;
-               ast_strftime(output, maxlen, "%Y-%m-%d  %T", &tm); 
+               ast_strftime(output, maxlen, "%Y-%m-%d  %T", &tm);
        } else
                ast_copy_string(output, "Invalid DATETIME format!", maxlen);
 }
@@ -365,7 +370,7 @@ static void dump_prov_ies(char *output, int maxlen, unsigned char *iedata, int l
        char tmp[256];
        if (len < 2)
                return;
-       strcpy(output, "\n"); 
+       strcpy(output, "\n");
        maxlen -= strlen(output); output += strlen(output);
        while(len > 2) {
                ie = iedata[0];
@@ -414,7 +419,7 @@ static void dump_ies(unsigned char *iedata, int len)
        int x;
        int found;
        char interp[1024];
-       char tmp[1024];
+       char tmp[1046];
 
        if (len < 2)
                return;
@@ -747,14 +752,14 @@ int iax_ie_append_versioned_uint64(struct iax_ie_data *ied, unsigned char ie, un
        return iax_ie_append_raw(ied, ie, &newval, (int) sizeof(newval));
 }
 
-int iax_ie_append_int(struct iax_ie_data *ied, unsigned char ie, unsigned int value) 
+int iax_ie_append_int(struct iax_ie_data *ied, unsigned char ie, unsigned int value)
 {
        unsigned int newval;
        newval = htonl(value);
        return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
 }
 
-int iax_ie_append_short(struct iax_ie_data *ied, unsigned char ie, unsigned short value) 
+int iax_ie_append_short(struct iax_ie_data *ied, unsigned char ie, unsigned short value)
 {
        unsigned short newval;
        newval = htons(value);
@@ -771,7 +776,7 @@ int iax_ie_append_byte(struct iax_ie_data *ied, unsigned char ie, unsigned char
        return iax_ie_append_raw(ied, ie, &dat, 1);
 }
 
-int iax_ie_append(struct iax_ie_data *ied, unsigned char ie) 
+int iax_ie_append(struct iax_ie_data *ied, unsigned char ie)
 {
        return iax_ie_append_raw(ied, ie, NULL, 0);
 }
@@ -977,7 +982,7 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
                                snprintf(tmp, (int)sizeof(tmp), "Expecting msgcount to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
                                errorf(tmp);
                        } else
-                               ies->msgcount = ntohs(get_unaligned_uint16(data + 2));  
+                               ies->msgcount = ntohs(get_unaligned_uint16(data + 2));
                        break;
                case IAX_IE_AUTOANSWER:
                        ies->autoanswer = 1;
@@ -1004,7 +1009,7 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
                                snprintf(tmp, (int)sizeof(tmp), "Expecting firmwarever to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
                                errorf(tmp);
                        } else
-                               ies->firmwarever = ntohs(get_unaligned_uint16(data + 2));       
+                               ies->firmwarever = ntohs(get_unaligned_uint16(data + 2));
                        break;
                case IAX_IE_DEVICETYPE:
                        ies->devicetype = (char *)data + 2;
@@ -1057,7 +1062,7 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
                                snprintf(tmp, (int)sizeof(tmp), "Expecting callingtns to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
                                errorf(tmp);
                        } else
-                               ies->calling_tns = ntohs(get_unaligned_uint16(data + 2));       
+                               ies->calling_tns = ntohs(get_unaligned_uint16(data + 2));
                        break;
                case IAX_IE_RR_JITTER:
                        if (len != (int)sizeof(unsigned int)) {
@@ -1149,7 +1154,7 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
                                ies->osptokenblock[count] = (char *)data + 2 + 1;
                                ies->ospblocklength[count] = len - 1;
                        } else {
-                               snprintf(tmp, (int)sizeof(tmp), "Expected OSP token block index to be 0~%d but was %d\n", IAX_MAX_OSPBLOCK_NUM - 1, count);
+                               snprintf(tmp, (int)sizeof(tmp), "Expected OSP token block index to be 0~%d but was %u\n", IAX_MAX_OSPBLOCK_NUM - 1, count);
                                errorf(tmp);
                        }
                        break;
@@ -1180,7 +1185,8 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
 void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
 {
        fr->af.frametype = f->frametype;
-       ast_format_copy(&fr->af.subclass.format, &f->subclass.format);
+       fr->af.subclass.format = f->subclass.format;
+       fr->af.subclass.integer = f->subclass.integer;
        fr->af.mallocd = 0;                             /* Our frame is static relative to the container */
        fr->af.datalen = f->datalen;
        fr->af.samples = f->samples;
@@ -1199,7 +1205,8 @@ void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
                }
 #if __BYTE_ORDER == __LITTLE_ENDIAN
                /* We need to byte-swap slinear samples from network byte order */
-               if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass.format.id == AST_FORMAT_SLINEAR)) {
+               if ((fr->af.frametype == AST_FRAME_VOICE) &&
+                       (ast_format_cmp(fr->af.subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL)) {
                        /* 2 bytes / sample for SLINEAR */
                        ast_swapcopy_samples(fr->af.data.ptr, f->data.ptr, copy_len / 2);
                } else
@@ -1212,7 +1219,7 @@ struct iax_frame *iax_frame_new(int direction, int datalen, unsigned int cacheab
 {
        struct iax_frame *fr;
 
-#if !defined(LOW_MEMORY)
+#if !defined(NO_FRAME_CACHE)
        if (cacheable) {
                struct iax_frames *iax_frames;
                struct iax_frame *smallest;
@@ -1240,13 +1247,13 @@ struct iax_frame *iax_frame_new(int direction, int datalen, unsigned int cacheab
                                        iax_frames->size--;
                                        ast_free(smallest);
                                }
-                               if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen))) {
+                               if (!(fr = ast_calloc(1, sizeof(*fr) + datalen))) {
                                        return NULL;
                                }
                                fr->afdatalen = datalen;
                        }
                } else {
-                       if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen))) {
+                       if (!(fr = ast_calloc(1, sizeof(*fr) + datalen))) {
                                return NULL;
                        }
                        fr->afdatalen = datalen;
@@ -1264,12 +1271,12 @@ struct iax_frame *iax_frame_new(int direction, int datalen, unsigned int cacheab
 
        fr->direction = direction;
        fr->retrans = -1;
-       
+
        if (fr->direction == DIRECTION_INGRESS)
                ast_atomic_fetchadd_int(&iframes, 1);
        else
                ast_atomic_fetchadd_int(&oframes, 1);
-       
+
        ast_atomic_fetchadd_int(&frames, 1);
 
        return fr;
@@ -1277,7 +1284,7 @@ struct iax_frame *iax_frame_new(int direction, int datalen, unsigned int cacheab
 
 void iax_frame_free(struct iax_frame *fr)
 {
-#if !defined(LOW_MEMORY)
+#if !defined(NO_FRAME_CACHE)
        struct iax_frames *iax_frames = NULL;
 #endif
 
@@ -1292,8 +1299,10 @@ void iax_frame_free(struct iax_frame *fr)
        }
        ast_atomic_fetchadd_int(&frames, -1);
 
-#if !defined(LOW_MEMORY)
-       if (!fr->cacheable || !(iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
+#if !defined(NO_FRAME_CACHE)
+       if (!fr->cacheable
+               || !ast_opt_cache_media_frames
+               || !(iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
                ast_free(fr);
                return;
        }
@@ -1314,7 +1323,7 @@ void iax_frame_free(struct iax_frame *fr)
        ast_free(fr);
 }
 
-#if !defined(LOW_MEMORY)
+#if !defined(NO_FRAME_CACHE)
 static void frame_cache_cleanup(void *data)
 {
        struct iax_frames *framelist = data;