Mon Oct 8 12:39:23 2012

Asterisk developer's documentation


iax2-parser.c File Reference

Implementation of Inter-Asterisk eXchange Protocol, v 2. More...

#include "asterisk.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "asterisk/frame.h"
#include "asterisk/utils.h"
#include "asterisk/unaligned.h"
#include "asterisk/config.h"
#include "asterisk/lock.h"
#include "asterisk/threadstorage.h"
#include "iax2.h"
#include "iax2-parser.h"
#include "iax2-provision.h"

Go to the source code of this file.

Data Structures

struct  iax2_ie
struct  iax_frame_list
 This is just so iax_frames, a list head struct for holding a list of iax_frame structures, is defined. More...
struct  iax_frames

Defines

#define FRAME_CACHE_MAX_SIZE   20

Functions

static void __init_frame_cache (void)
 A per-thread cache of iax_frame structures.
static void dump_addr (char *output, int maxlen, void *value, int len)
static void dump_byte (char *output, int maxlen, void *value, int len)
static void dump_datetime (char *output, int maxlen, void *value, int len)
static void dump_ies (unsigned char *iedata, int len)
static void dump_int (char *output, int maxlen, void *value, int len)
static void dump_ipaddr (char *output, int maxlen, void *value, int len)
static void dump_prefs (char *output, int maxlen, void *value, int len)
static void dump_prov (char *output, int maxlen, void *value, int len)
static void dump_prov_flags (char *output, int maxlen, void *value, int len)
static void dump_prov_ies (char *output, int maxlen, unsigned char *iedata, int len)
static void dump_samprate (char *output, int maxlen, void *value, int len)
static void dump_short (char *output, int maxlen, void *value, int len)
static void dump_string (char *output, int maxlen, void *value, int len)
static void dump_string_hex (char *output, int maxlen, void *value, int len)
static void dump_versioned_codec (char *output, int maxlen, void *value, int len)
static void frame_cache_cleanup (void *data)
void iax_frame_free (struct iax_frame *fr)
iax_frameiax_frame_new (int direction, int datalen, unsigned int cacheable)
void iax_frame_subclass2str (enum iax_frame_subclass subclass, char *str, size_t len)
void iax_frame_wrap (struct iax_frame *fr, struct ast_frame *f)
int iax_get_frames (void)
int iax_get_iframes (void)
int iax_get_oframes (void)
const char * iax_ie2str (int ie)
int iax_ie_append (struct iax_ie_data *ied, unsigned char ie)
int iax_ie_append_addr (struct iax_ie_data *ied, unsigned char ie, const struct sockaddr_in *sin)
int iax_ie_append_byte (struct iax_ie_data *ied, unsigned char ie, unsigned char dat)
int iax_ie_append_int (struct iax_ie_data *ied, unsigned char ie, unsigned int value)
int iax_ie_append_raw (struct iax_ie_data *ied, unsigned char ie, const void *data, int datalen)
int iax_ie_append_short (struct iax_ie_data *ied, unsigned char ie, unsigned short value)
int iax_ie_append_str (struct iax_ie_data *ied, unsigned char ie, const char *str)
int iax_ie_append_versioned_uint64 (struct iax_ie_data *ied, unsigned char ie, unsigned char version, uint64_t value)
int iax_parse_ies (struct iax_ies *ies, unsigned char *data, int datalen)
void iax_set_error (void(*func)(const char *))
void iax_set_output (void(*func)(const char *))
void iax_showframe (struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
static void internalerror (const char *str)
static void internaloutput (const char *str)

Variables

static void(*) errorf (const char *str) = internalerror
static struct ast_threadstorage frame_cache = { .once = PTHREAD_ONCE_INIT , .key_init = __init_frame_cache , .custom_init = NULL , }
static int frames = 0
static int iframes = 0
static struct iax2_ie infoelts []
static int oframes = 0
static void(*) outputf (const char *str) = internaloutput
static struct iax2_ie prov_ies []


Detailed Description

Implementation of Inter-Asterisk eXchange Protocol, v 2.

Author:
Mark Spencer <markster@digium.com>

Definition in file iax2-parser.c.


Define Documentation

#define FRAME_CACHE_MAX_SIZE   20

Definition at line 68 of file iax2-parser.c.

Referenced by __frame_free(), iax_frame_free(), and iax_frame_new().


Function Documentation

static void __init_frame_cache ( void   )  [static]

A per-thread cache of iax_frame structures.

Definition at line 57 of file iax2-parser.c.

00063 {

static void dump_addr ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 84 of file iax2-parser.c.

References ast_copy_string(), and ast_inet_ntoa().

00085 {
00086    struct sockaddr_in sin;
00087    if (len == (int)sizeof(sin)) {
00088       memcpy(&sin, value, len);
00089       snprintf(output, maxlen, "IPV4 %s:%d", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
00090    } else {
00091       ast_copy_string(output, "Invalid Address", maxlen);
00092    }
00093 }

static void dump_byte ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 149 of file iax2-parser.c.

References ast_copy_string().

00150 {
00151    if (len == (int)sizeof(unsigned char))
00152       snprintf(output, maxlen, "%d", *((unsigned char *)value));
00153    else
00154       ast_copy_string(output, "Invalid BYTE", maxlen);
00155 }

static void dump_datetime ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 157 of file iax2-parser.c.

References ast_copy_string(), ast_strftime(), get_unaligned_uint32(), ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, and ast_tm::tm_year.

00158 {
00159    struct ast_tm tm;
00160    unsigned long val = (unsigned long) ntohl(get_unaligned_uint32(value));
00161    if (len == (int)sizeof(unsigned int)) {
00162       tm.tm_sec  = (val & 0x1f) << 1;
00163       tm.tm_min  = (val >> 5) & 0x3f;
00164       tm.tm_hour = (val >> 11) & 0x1f;
00165       tm.tm_mday = (val >> 16) & 0x1f;
00166       tm.tm_mon  = ((val >> 21) & 0x0f) - 1;
00167       tm.tm_year = ((val >> 25) & 0x7f) + 100;
00168       ast_strftime(output, maxlen, "%Y-%m-%d  %T", &tm); 
00169    } else
00170       ast_copy_string(output, "Invalid DATETIME format!", maxlen);
00171 }

static void dump_ies ( unsigned char *  iedata,
int  len 
) [static]

Definition at line 387 of file iax2-parser.c.

References ARRAY_LEN, iax2_ie::dump, iax2_ie::ie, infoelts, name, and outputf.

Referenced by dundi_showframe(), and iax_showframe().

00388 {
00389    int ielen;
00390    int ie;
00391    int x;
00392    int found;
00393    char interp[1024];
00394    char tmp[1024];
00395    if (len < 2)
00396       return;
00397    while(len > 2) {
00398       ie = iedata[0];
00399       ielen = iedata[1];
00400       if (ielen + 2> len) {
00401          snprintf(tmp, (int)sizeof(tmp), "Total IE length of %d bytes exceeds remaining frame length of %d bytes\n", ielen + 2, len);
00402          outputf(tmp);
00403          return;
00404       }
00405       found = 0;
00406       for (x = 0; x < ARRAY_LEN(infoelts); x++) {
00407          if (infoelts[x].ie == ie) {
00408             if (infoelts[x].dump) {
00409                infoelts[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen);
00410                snprintf(tmp, (int)sizeof(tmp), "   %-15.15s : %s\n", infoelts[x].name, interp);
00411                outputf(tmp);
00412             } else {
00413                if (ielen)
00414                   snprintf(interp, (int)sizeof(interp), "%d bytes", ielen);
00415                else
00416                   strcpy(interp, "Present");
00417                snprintf(tmp, (int)sizeof(tmp), "   %-15.15s : %s\n", infoelts[x].name, interp);
00418                outputf(tmp);
00419             }
00420             found++;
00421          }
00422       }
00423       if (!found) {
00424          snprintf(tmp, (int)sizeof(tmp), "   Unknown IE %03d  : Present\n", ie);
00425          outputf(tmp);
00426       }
00427       iedata += (2 + ielen);
00428       len -= (2 + ielen);
00429    }
00430    outputf("\n");
00431 }

static void dump_int ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 133 of file iax2-parser.c.

References ast_copy_string(), and get_unaligned_uint32().

00134 {
00135    if (len == (int)sizeof(unsigned int))
00136       snprintf(output, maxlen, "%lu", (unsigned long)ntohl(get_unaligned_uint32(value)));
00137    else
00138       ast_copy_string(output, "Invalid INT", maxlen); 
00139 }

static void dump_ipaddr ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 173 of file iax2-parser.c.

References ast_copy_string(), and ast_inet_ntoa().

00174 {
00175    struct sockaddr_in sin;
00176    if (len == (int)sizeof(unsigned int)) {
00177       memcpy(&sin.sin_addr, value, len);
00178       snprintf(output, maxlen, "%s", ast_inet_ntoa(sin.sin_addr));
00179    } else
00180       ast_copy_string(output, "Invalid IPADDR", maxlen);
00181 }

static void dump_prefs ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 114 of file iax2-parser.c.

References ast_codec_pref_convert(), and ast_codec_pref_string().

00115 {
00116    struct ast_codec_pref pref;
00117    int total_len = 0;
00118 
00119    maxlen--;
00120    total_len = maxlen;
00121 
00122    if (maxlen > len)
00123       maxlen = len;
00124 
00125    strncpy(output, value, maxlen);
00126    output[maxlen] = '\0';
00127    
00128    ast_codec_pref_convert(&pref, output, total_len, 0);
00129    memset(output,0,total_len);
00130    ast_codec_pref_string(&pref, output, total_len);
00131 }

static void dump_prov ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 237 of file iax2-parser.c.

References dump_prov_ies().

00238 {
00239    dump_prov_ies(output, maxlen, value, len);
00240 }

static void dump_prov_flags ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 184 of file iax2-parser.c.

References ast_copy_string(), get_unaligned_uint32(), and iax_provflags2str().

00185 {
00186    char buf[256] = "";
00187    if (len == (int)sizeof(unsigned int))
00188       snprintf(output, maxlen, "%lu (%s)", (unsigned long)ntohl(get_unaligned_uint32(value)),
00189          iax_provflags2str(buf, sizeof(buf), ntohl(get_unaligned_uint32(value))));
00190    else
00191       ast_copy_string(output, "Invalid INT", maxlen);
00192 }

static void dump_prov_ies ( char *  output,
int  maxlen,
unsigned char *  iedata,
int  len 
) [static]

Definition at line 335 of file iax2-parser.c.

References ast_copy_string(), iax2_ie::dump, iax2_ie::ie, name, and prov_ies.

Referenced by dump_prov().

00336 {
00337    int ielen;
00338    int ie;
00339    int x;
00340    int found;
00341    char interp[80];
00342    char tmp[256];
00343    if (len < 2)
00344       return;
00345    strcpy(output, "\n"); 
00346    maxlen -= strlen(output); output += strlen(output);
00347    while(len > 2) {
00348       ie = iedata[0];
00349       ielen = iedata[1];
00350       if (ielen + 2> len) {
00351          snprintf(tmp, (int)sizeof(tmp), "Total Prov IE length of %d bytes exceeds remaining prov frame length of %d bytes\n", ielen + 2, len);
00352          ast_copy_string(output, tmp, maxlen);
00353          maxlen -= strlen(output);
00354          output += strlen(output);
00355          return;
00356       }
00357       found = 0;
00358       for (x=0;x<(int)sizeof(prov_ies) / (int)sizeof(prov_ies[0]); x++) {
00359          if (prov_ies[x].ie == ie) {
00360             if (prov_ies[x].dump) {
00361                prov_ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen);
00362                snprintf(tmp, (int)sizeof(tmp), "       %-15.15s : %s\n", prov_ies[x].name, interp);
00363                ast_copy_string(output, tmp, maxlen);
00364                maxlen -= strlen(output); output += strlen(output);
00365             } else {
00366                if (ielen)
00367                   snprintf(interp, (int)sizeof(interp), "%d bytes", ielen);
00368                else
00369                   strcpy(interp, "Present");
00370                snprintf(tmp, (int)sizeof(tmp), "       %-15.15s : %s\n", prov_ies[x].name, interp);
00371                ast_copy_string(output, tmp, maxlen);
00372                maxlen -= strlen(output); output += strlen(output);
00373             }
00374             found++;
00375          }
00376       }
00377       if (!found) {
00378          snprintf(tmp, (int)sizeof(tmp), "       Unknown Prov IE %03d  : Present\n", ie);
00379          ast_copy_string(output, tmp, maxlen);
00380          maxlen -= strlen(output); output += strlen(output);
00381       }
00382       iedata += (2 + ielen);
00383       len -= (2 + ielen);
00384    }
00385 }

static void dump_samprate ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 194 of file iax2-parser.c.

References ast_copy_string(), IAX_RATE_11KHZ, IAX_RATE_16KHZ, IAX_RATE_22KHZ, IAX_RATE_44KHZ, IAX_RATE_48KHZ, and IAX_RATE_8KHZ.

00195 {
00196    char tmp[256]="";
00197    int sr;
00198    if (len == (int)sizeof(unsigned short)) {
00199       sr = ntohs(*((unsigned short *)value));
00200       if (sr & IAX_RATE_8KHZ)
00201          strcat(tmp, ",8khz");
00202       if (sr & IAX_RATE_11KHZ)
00203          strcat(tmp, ",11.025khz");
00204       if (sr & IAX_RATE_16KHZ)
00205          strcat(tmp, ",16khz");
00206       if (sr & IAX_RATE_22KHZ)
00207          strcat(tmp, ",22.05khz");
00208       if (sr & IAX_RATE_44KHZ)
00209          strcat(tmp, ",44.1khz");
00210       if (sr & IAX_RATE_48KHZ)
00211          strcat(tmp, ",48khz");
00212       if (strlen(tmp))
00213          ast_copy_string(output, &tmp[1], maxlen);
00214       else
00215          ast_copy_string(output, "None Specified!\n", maxlen);
00216    } else
00217       ast_copy_string(output, "Invalid SHORT", maxlen);
00218 
00219 }

static void dump_short ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 141 of file iax2-parser.c.

References ast_copy_string(), and get_unaligned_uint16().

00142 {
00143    if (len == (int)sizeof(unsigned short))
00144       snprintf(output, maxlen, "%d", ntohs(get_unaligned_uint16(value)));
00145    else
00146       ast_copy_string(output, "Invalid SHORT", maxlen);
00147 }

static void dump_string ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 105 of file iax2-parser.c.

00106 {
00107    maxlen--;
00108    if (maxlen > len)
00109       maxlen = len;
00110    strncpy(output, value, maxlen);
00111    output[maxlen] = '\0';
00112 }

static void dump_string_hex ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 95 of file iax2-parser.c.

00096 {
00097    int i = 0;
00098 
00099    while (len-- && (i + 1) * 4 < maxlen) {
00100       sprintf(output + (4 * i), "\\x%2.2x", *((unsigned char *)value + i));
00101       i++;
00102    }
00103 }

static void dump_versioned_codec ( char *  output,
int  maxlen,
void *  value,
int  len 
) [static]

Definition at line 221 of file iax2-parser.c.

References ast_copy_string(), ast_getformatname(), get_unaligned_uint64(), ntohll(), and version.

00222 {
00223    char *version = (char *) value;
00224    if (version[0] == 0) {
00225       if (len == (int) (sizeof(format_t) + sizeof(char))) {
00226          format_t codec = ntohll(get_unaligned_uint64(value + 1));
00227          ast_copy_string(output, ast_getformatname(codec), maxlen);
00228       } else {
00229          ast_copy_string(output, "Invalid length!", maxlen);
00230       }
00231    } else {
00232       ast_copy_string(output, "Unknown version!", maxlen);
00233    }
00234 }

static void frame_cache_cleanup ( void *  data  )  [static]

Definition at line 1271 of file iax2-parser.c.

References ast_free, AST_LIST_REMOVE_HEAD, iax_frame::list, and iax_frames::list.

01272 {
01273    struct iax_frames *framelist = data;
01274    struct iax_frame *current;
01275 
01276    while ((current = AST_LIST_REMOVE_HEAD(&framelist->list, list)))
01277       ast_free(current);
01278 
01279    ast_free(framelist);
01280 }

void iax_frame_free ( struct iax_frame fr  ) 

Definition at line 1231 of file iax2-parser.c.

References iax_frame::afdatalen, ast_atomic_fetchadd_int(), ast_free, AST_LIST_FIRST, AST_LIST_INSERT_HEAD, AST_LIST_INSERT_TAIL, ast_threadstorage_get(), iax_frame::cacheable, iax_frame::direction, DIRECTION_INGRESS, DIRECTION_OUTGRESS, errorf, frame_cache, FRAME_CACHE_MAX_SIZE, and iax_frames::list.

Referenced by iax2_frame_free(), and transmit_frame().

01232 {
01233 #if !defined(LOW_MEMORY)
01234    struct iax_frames *iax_frames = NULL;
01235 #endif
01236 
01237    /* Note: does not remove from scheduler! */
01238    if (fr->direction == DIRECTION_INGRESS)
01239       ast_atomic_fetchadd_int(&iframes, -1);
01240    else if (fr->direction == DIRECTION_OUTGRESS)
01241       ast_atomic_fetchadd_int(&oframes, -1);
01242    else {
01243       errorf("Attempt to double free frame detected\n");
01244       return;
01245    }
01246    ast_atomic_fetchadd_int(&frames, -1);
01247 
01248 #if !defined(LOW_MEMORY)
01249    if (!fr->cacheable || !(iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
01250       ast_free(fr);
01251       return;
01252    }
01253 
01254    if (iax_frames->size < FRAME_CACHE_MAX_SIZE) {
01255       fr->direction = 0;
01256       /* Pseudo-sort: keep smaller frames at the top of the list. This should
01257        * increase the chance that we pick the smallest applicable frame for use. */
01258       if (AST_LIST_FIRST(&iax_frames->list) && AST_LIST_FIRST(&iax_frames->list)->afdatalen < fr->afdatalen) {
01259          AST_LIST_INSERT_TAIL(&iax_frames->list, fr, list);
01260       } else {
01261          AST_LIST_INSERT_HEAD(&iax_frames->list, fr, list);
01262       }
01263       iax_frames->size++;
01264       return;
01265    }
01266 #endif
01267    ast_free(fr);
01268 }

struct iax_frame* iax_frame_new ( int  direction,
int  datalen,
unsigned int  cacheable 
)

Definition at line 1173 of file iax2-parser.c.

References iax_frame::afdatalen, ast_atomic_fetchadd_int(), ast_calloc, ast_calloc_cache, AST_LIST_FIRST, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_realloc, ast_threadstorage_get(), DIRECTION_INGRESS, frame_cache, FRAME_CACHE_MAX_SIZE, and iax_frame::list.

Referenced by iax2_send(), and iaxfrdup2().

01174 {
01175    struct iax_frame *fr = NULL;
01176 
01177 #if !defined(LOW_MEMORY)
01178    struct iax_frames *iax_frames = NULL;
01179    struct iax_frame *smallest = NULL;
01180 
01181    /* Attempt to get a frame from this thread's cache */
01182    if ((iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
01183       smallest = AST_LIST_FIRST(&iax_frames->list);
01184       AST_LIST_TRAVERSE_SAFE_BEGIN(&iax_frames->list, fr, list) {
01185          if (fr->afdatalen >= datalen) {
01186             size_t afdatalen = fr->afdatalen;
01187             AST_LIST_REMOVE_CURRENT(list);
01188             iax_frames->size--;
01189             memset(fr, 0, sizeof(*fr));
01190             fr->afdatalen = afdatalen;
01191             break;
01192          } else if (smallest->afdatalen > fr->afdatalen) {
01193             smallest = fr;
01194          }
01195       }
01196       AST_LIST_TRAVERSE_SAFE_END;
01197    }
01198    if (!fr) {
01199       if (iax_frames && iax_frames->size >= FRAME_CACHE_MAX_SIZE && smallest) {
01200          /* Make useless cache into something more useful */
01201          AST_LIST_REMOVE(&iax_frames->list, smallest, list);
01202          if (!(fr = ast_realloc(smallest, sizeof(*fr) + datalen))) {
01203             AST_LIST_INSERT_TAIL(&iax_frames->list, smallest, list);
01204             return NULL;
01205          }
01206       } else if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen)))
01207          return NULL;
01208       fr->afdatalen = datalen;
01209    }
01210 #else
01211    if (!(fr = ast_calloc(1, sizeof(*fr) + datalen)))
01212       return NULL;
01213    fr->afdatalen = datalen;
01214 #endif
01215 
01216 
01217    fr->direction = direction;
01218    fr->retrans = -1;
01219    fr->cacheable = cacheable;
01220    
01221    if (fr->direction == DIRECTION_INGRESS)
01222       ast_atomic_fetchadd_int(&iframes, 1);
01223    else
01224       ast_atomic_fetchadd_int(&oframes, 1);
01225    
01226    ast_atomic_fetchadd_int(&frames, 1);
01227 
01228    return fr;
01229 }

void iax_frame_subclass2str ( enum iax_frame_subclass  subclass,
char *  str,
size_t  len 
)

Definition at line 433 of file iax2-parser.c.

References ast_copy_string(), IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_CALLTOKEN, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_MWI, IAX_COMMAND_NEW, IAX_COMMAND_PAGE, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_PROVISION, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_RTKEY, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, and IAX_COMMAND_VNAK.

Referenced by ast_cli_netstats(), handle_cli_iax2_show_channels(), and iax_showframe().

00434 {
00435    const char *cmd = "Unknown";
00436 
00437    /* if an error occurs here during compile, that means a new iax frame subclass
00438     * has been added to the iax_frame_subclass enum.  Add the new subclass to the
00439     * switch case and make sure to update it with a new string representation. */
00440    switch (subclass) {
00441    case IAX_COMMAND_NEW:
00442       cmd = "NEW    ";
00443       break;
00444    case IAX_COMMAND_PING:
00445       cmd = "PING   ";
00446       break;
00447    case IAX_COMMAND_PONG:
00448       cmd = "PONG   ";
00449       break;
00450    case IAX_COMMAND_ACK:
00451       cmd = "ACK    ";
00452       break;
00453    case IAX_COMMAND_HANGUP:
00454       cmd = "HANGUP ";
00455       break;
00456    case IAX_COMMAND_REJECT:
00457       cmd = "REJECT ";
00458       break;
00459    case IAX_COMMAND_ACCEPT:
00460       cmd = "ACCEPT ";
00461       break;
00462    case IAX_COMMAND_AUTHREQ:
00463       cmd = "AUTHREQ";
00464       break;
00465    case IAX_COMMAND_AUTHREP:
00466       cmd = "AUTHREP";
00467       break;
00468    case IAX_COMMAND_INVAL:
00469       cmd = "INVAL  ";
00470       break;
00471    case IAX_COMMAND_LAGRQ:
00472       cmd = "LAGRQ  ";
00473       break;
00474    case IAX_COMMAND_LAGRP:
00475       cmd = "LAGRP  ";
00476       break;
00477    case IAX_COMMAND_REGREQ:
00478       cmd = "REGREQ ";
00479       break;
00480    case IAX_COMMAND_REGAUTH:
00481       cmd = "REGAUTH";
00482       break;
00483    case IAX_COMMAND_REGACK:
00484       cmd = "REGACK ";
00485       break;
00486    case IAX_COMMAND_REGREJ:
00487       cmd = "REGREJ ";
00488       break;
00489    case IAX_COMMAND_REGREL:
00490       cmd = "REGREL ";
00491       break;
00492    case IAX_COMMAND_VNAK:
00493       cmd = "VNAK   ";
00494       break;
00495    case IAX_COMMAND_DPREQ:
00496       cmd = "DPREQ  ";
00497       break;
00498    case IAX_COMMAND_DPREP:
00499       cmd = "DPREP  ";
00500       break;
00501    case IAX_COMMAND_DIAL:
00502       cmd = "DIAL   ";
00503       break;
00504    case IAX_COMMAND_TXREQ:
00505       cmd = "TXREQ  ";
00506       break;
00507    case IAX_COMMAND_TXCNT:
00508       cmd = "TXCNT  ";
00509       break;
00510    case IAX_COMMAND_TXACC:
00511       cmd = "TXACC  ";
00512       break;
00513    case IAX_COMMAND_TXREADY:
00514       cmd = "TXREADY";
00515       break;
00516    case IAX_COMMAND_TXREL:
00517       cmd = "TXREL  ";
00518       break;
00519    case IAX_COMMAND_TXREJ:
00520       cmd = "TXREJ  ";
00521       break;
00522    case IAX_COMMAND_QUELCH:
00523       cmd = "QUELCH ";
00524       break;
00525    case IAX_COMMAND_UNQUELCH:
00526       cmd = "UNQULCH";
00527       break;
00528    case IAX_COMMAND_POKE:
00529       cmd = "POKE   ";
00530       break;
00531    case IAX_COMMAND_PAGE:
00532       cmd = "PAGE   ";
00533       break;
00534    case IAX_COMMAND_MWI:
00535       cmd = "MWI    ";
00536       break;
00537    case IAX_COMMAND_UNSUPPORT:
00538       cmd = "UNSPRTD";
00539       break;
00540    case IAX_COMMAND_TRANSFER:
00541       cmd = "TRANSFR";
00542       break;
00543    case IAX_COMMAND_PROVISION:
00544       cmd = "PROVISN";
00545       break;
00546    case IAX_COMMAND_FWDOWNL:
00547       cmd = "FWDWNLD";
00548       break;
00549    case IAX_COMMAND_FWDATA:
00550       cmd = "FWDATA ";
00551       break;
00552    case IAX_COMMAND_TXMEDIA:
00553       cmd = "TXMEDIA";
00554       break;
00555    case IAX_COMMAND_RTKEY:
00556       cmd = "RTKEY  ";
00557       break;
00558    case IAX_COMMAND_CALLTOKEN:
00559       cmd = "CTOKEN ";
00560       break;
00561    }
00562    ast_copy_string(str, cmd, len);
00563 }

void iax_frame_wrap ( struct iax_frame fr,
struct ast_frame f 
)

Definition at line 1142 of file iax2-parser.c.

References iax_frame::af, iax_frame::afdata, iax_frame::afdatalen, AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_swapcopy_samples(), ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, ast_frame::delivery, f, ast_frame::frametype, ast_frame::len, LOG_ERROR, ast_frame::mallocd, ast_frame::offset, ast_frame::ptr, ast_frame::samples, ast_frame::src, and ast_frame::subclass.

Referenced by iax2_send(), iaxfrdup2(), socket_process(), and socket_process_meta().

01143 {
01144    fr->af.frametype = f->frametype;
01145    fr->af.subclass.codec = f->subclass.codec;
01146    fr->af.mallocd = 0;           /* Our frame is static relative to the container */
01147    fr->af.datalen = f->datalen;
01148    fr->af.samples = f->samples;
01149    fr->af.offset = AST_FRIENDLY_OFFSET;
01150    fr->af.src = f->src;
01151    fr->af.delivery.tv_sec = 0;
01152    fr->af.delivery.tv_usec = 0;
01153    fr->af.data.ptr = fr->afdata;
01154    fr->af.len = f->len;
01155    if (fr->af.datalen) {
01156       size_t copy_len = fr->af.datalen;
01157       if (copy_len > fr->afdatalen) {
01158          ast_log(LOG_ERROR, "Losing frame data because destination buffer size '%d' bytes not big enough for '%d' bytes in the frame\n",
01159             (int) fr->afdatalen, (int) fr->af.datalen);
01160          copy_len = fr->afdatalen;
01161       }
01162 #if __BYTE_ORDER == __LITTLE_ENDIAN
01163       /* We need to byte-swap slinear samples from network byte order */
01164       if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass.codec == AST_FORMAT_SLINEAR)) {
01165          /* 2 bytes / sample for SLINEAR */
01166          ast_swapcopy_samples(fr->af.data.ptr, f->data.ptr, copy_len / 2);
01167       } else
01168 #endif
01169          memcpy(fr->af.data.ptr, f->data.ptr, copy_len);
01170    }
01171 }

int iax_get_frames ( void   ) 

Definition at line 1283 of file iax2-parser.c.

Referenced by handle_cli_iax2_show_stats().

01283 { return frames; }

int iax_get_iframes ( void   ) 

Definition at line 1284 of file iax2-parser.c.

Referenced by handle_cli_iax2_show_stats().

01284 { return iframes; }

int iax_get_oframes ( void   ) 

Definition at line 1285 of file iax2-parser.c.

Referenced by handle_cli_iax2_show_stats().

01285 { return oframes; }

const char* iax_ie2str ( int  ie  ) 

Definition at line 324 of file iax2-parser.c.

References ARRAY_LEN, infoelts, and iax2_ie::name.

Referenced by iax_ie_append_raw(), and iax_parse_ies().

00325 {
00326    int x;
00327    for (x = 0; x < ARRAY_LEN(infoelts); x++) {
00328       if (infoelts[x].ie == ie)
00329          return infoelts[x].name;
00330    }
00331    return "Unknown IE";
00332 }

int iax_ie_append ( struct iax_ie_data ied,
unsigned char  ie 
)

Definition at line 737 of file iax2-parser.c.

References iax_ie_append_raw().

Referenced by iax2_call(), and iax_firmware_append().

00738 {
00739    return iax_ie_append_raw(ied, ie, NULL, 0);
00740 }

int iax_ie_append_addr ( struct iax_ie_data ied,
unsigned char  ie,
const struct sockaddr_in *  sin 
)

Definition at line 698 of file iax2-parser.c.

References iax_ie_append_raw().

Referenced by iax2_start_transfer(), and update_registry().

00699 {
00700    return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in));
00701 }

int iax_ie_append_byte ( struct iax_ie_data ied,
unsigned char  ie,
unsigned char  dat 
)

Definition at line 732 of file iax2-parser.c.

References iax_ie_append_raw().

Referenced by __auth_reject(), __auto_hangup(), authenticate_request(), iax2_call(), iax2_hangup(), iax_provision_build(), and socket_process().

00733 {
00734    return iax_ie_append_raw(ied, ie, &dat, 1);
00735 }

int iax_ie_append_int ( struct iax_ie_data ied,
unsigned char  ie,
unsigned int  value 
)

Definition at line 713 of file iax2-parser.c.

References iax_ie_append_raw().

Referenced by cache_get_callno_locked(), construct_rr(), iax2_call(), iax2_start_transfer(), iax_firmware_append(), iax_provision_build(), socket_process(), try_transfer(), and update_registry().

00714 {
00715    unsigned int newval;
00716    newval = htonl(value);
00717    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00718 }

int iax_ie_append_raw ( struct iax_ie_data ied,
unsigned char  ie,
const void *  data,
int  datalen 
)

Definition at line 683 of file iax2-parser.c.

References iax_ie_data::buf, errorf, iax_ie2str(), and iax_ie_data::pos.

Referenced by iax2_call(), iax2_key_rotate(), iax2_provision(), iax_firmware_append(), iax_ie_append(), iax_ie_append_addr(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), and iax_ie_append_versioned_uint64().

00684 {
00685    char tmp[256];
00686    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00687       snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", iax_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
00688       errorf(tmp);
00689       return -1;
00690    }
00691    ied->buf[ied->pos++] = ie;
00692    ied->buf[ied->pos++] = datalen;
00693    memcpy(ied->buf + ied->pos, data, datalen);
00694    ied->pos += datalen;
00695    return 0;
00696 }

int iax_ie_append_short ( struct iax_ie_data ied,
unsigned char  ie,
unsigned short  value 
)

Definition at line 720 of file iax2-parser.c.

References iax_ie_append_raw().

Referenced by authenticate_request(), cache_get_callno_locked(), construct_rr(), dp_lookup(), iax2_call(), iax2_do_register(), iax2_start_transfer(), iax_provision_build(), registry_authrequest(), registry_rerequest(), socket_process(), and update_registry().

00721 {
00722    unsigned short newval;
00723    newval = htons(value);
00724    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00725 }

int iax_ie_append_str ( struct iax_ie_data ied,
unsigned char  ie,
const char *  str 
)

Definition at line 727 of file iax2-parser.c.

References iax_ie_append_raw().

Referenced by __auth_reject(), __auto_hangup(), authenticate(), authenticate_request(), cache_get_callno_locked(), dp_lookup(), handle_call_token(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_transfer(), iax_provision_build(), registry_authrequest(), registry_rerequest(), resend_with_token(), socket_process(), and update_registry().

00728 {
00729    return iax_ie_append_raw(ied, ie, str, strlen(str));
00730 }

int iax_ie_append_versioned_uint64 ( struct iax_ie_data ied,
unsigned char  ie,
unsigned char  version,
uint64_t  value 
)

Definition at line 703 of file iax2-parser.c.

References htonll(), iax_ie_append_raw(), and put_unaligned_uint64().

Referenced by iax2_call(), and socket_process().

00704 {
00705    struct _local {
00706       unsigned char version;
00707       uint64_t value;
00708    } __attribute__((packed)) newval = { version, };
00709    put_unaligned_uint64(&newval.value, htonll(value));
00710    return iax_ie_append_raw(ied, ie, &newval, (int) sizeof(newval));
00711 }

int iax_parse_ies ( struct iax_ies ies,
unsigned char *  data,
int  datalen 
)

Definition at line 752 of file iax2-parser.c.

References iax_ies::adsicpe, iax_ies::apparent_addr, ast_copy_string(), ast_free, ast_str_buffer(), ast_str_create(), ast_str_set(), ast_variable_new(), iax_ies::authmethods, iax_ies::autoanswer, iax_ies::called_context, iax_ies::called_number, iax_ies::calling_ani, iax_ies::calling_name, iax_ies::calling_number, iax_ies::calling_pres, iax_ies::calling_tns, iax_ies::calling_ton, iax_ies::callno, iax_ies::calltoken, iax_ies::calltokendata, iax_ies::capability, iax_ies::cause, iax_ies::causecode, iax_ies::challenge, iax_ies::codec_prefs, iax_ies::datetime, iax_ies::devicetype, iax_ies::dnid, iax_ies::dpstatus, iax_ies::enckey, iax_ies::enckeylen, iax_ies::encmethods, errorf, ast_variable::file, iax_ies::firmwarever, iax_ies::format, iax_ies::fwdata, iax_ies::fwdatalen, iax_ies::fwdesc, get_unaligned_uint16(), get_unaligned_uint32(), get_unaligned_uint64(), iax_ie2str(), IAX_IE_ADSICPE, IAX_IE_APPARENT_ADDR, IAX_IE_AUTHMETHODS, IAX_IE_AUTOANSWER, IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CALLING_ANI, IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_CALLINGPRES, IAX_IE_CALLINGTNS, IAX_IE_CALLINGTON, IAX_IE_CALLNO, IAX_IE_CALLTOKEN, IAX_IE_CAPABILITY, IAX_IE_CAPABILITY2, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_CHALLENGE, IAX_IE_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DEVICETYPE, IAX_IE_DNID, IAX_IE_DPSTATUS, IAX_IE_ENCKEY, IAX_IE_ENCRYPTION, IAX_IE_FIRMWAREVER, IAX_IE_FORMAT, IAX_IE_FORMAT2, IAX_IE_FWBLOCKDATA, IAX_IE_FWBLOCKDESC, IAX_IE_IAX_UNKNOWN, IAX_IE_LANGUAGE, IAX_IE_MD5_RESULT, IAX_IE_MSGCOUNT, IAX_IE_MUSICONHOLD, IAX_IE_OSPTOKEN, IAX_IE_PASSWORD, IAX_IE_PROVVER, IAX_IE_RDNIS, IAX_IE_REFRESH, IAX_IE_RR_DELAY, IAX_IE_RR_DROPPED, IAX_IE_RR_JITTER, IAX_IE_RR_LOSS, IAX_IE_RR_OOO, IAX_IE_RR_PKTS, IAX_IE_RSA_RESULT, IAX_IE_SAMPLINGRATE, IAX_IE_SERVICEIDENT, IAX_IE_TRANSFERID, IAX_IE_USERNAME, IAX_IE_VARIABLE, IAX_IE_VERSION, IAX_MAX_OSPBLOCK_NUM, IAX_RATE_8KHZ, iax_ies::iax_unknown, iax_ies::language, len(), iax_ies::md5_result, iax_ies::msgcount, iax_ies::musiconhold, ast_variable::name, ast_variable::next, ntohll(), iax_ies::ospblocklength, iax_ies::osptokenblock, outputf, iax_ies::password, iax_ies::provver, iax_ies::provverpres, iax_ies::rdnis, iax_ies::refresh, iax_ies::rr_delay, iax_ies::rr_dropped, iax_ies::rr_jitter, iax_ies::rr_loss, iax_ies::rr_ooo, iax_ies::rr_pkts, iax_ies::rsa_result, iax_ies::samprate, iax_ies::serviceident, str, iax_ies::transferid, iax_ies::username, ast_variable::value, var, iax_ies::vars, version, and iax_ies::version.

Referenced by socket_process().

00753 {
00754    /* Parse data into information elements */
00755    int len;
00756    int ie;
00757    char tmp[256], *tmp2;
00758    struct ast_variable *var, *var2, *prev;
00759    unsigned int count;
00760    memset(ies, 0, (int)sizeof(struct iax_ies));
00761    ies->msgcount = -1;
00762    ies->firmwarever = -1;
00763    ies->calling_ton = -1;
00764    ies->calling_tns = -1;
00765    ies->calling_pres = -1;
00766    ies->samprate = IAX_RATE_8KHZ;
00767    while(datalen >= 2) {
00768       ie = data[0];
00769       len = data[1];
00770       if (len > datalen - 2) {
00771          errorf("Information element length exceeds message size\n");
00772          return -1;
00773       }
00774       switch(ie) {
00775       case IAX_IE_CALLED_NUMBER:
00776          ies->called_number = (char *)data + 2;
00777          break;
00778       case IAX_IE_CALLING_NUMBER:
00779          ies->calling_number = (char *)data + 2;
00780          break;
00781       case IAX_IE_CALLING_ANI:
00782          ies->calling_ani = (char *)data + 2;
00783          break;
00784       case IAX_IE_CALLING_NAME:
00785          ies->calling_name = (char *)data + 2;
00786          break;
00787       case IAX_IE_CALLED_CONTEXT:
00788          ies->called_context = (char *)data + 2;
00789          break;
00790       case IAX_IE_USERNAME:
00791          ies->username = (char *)data + 2;
00792          break;
00793       case IAX_IE_PASSWORD:
00794          ies->password = (char *)data + 2;
00795          break;
00796       case IAX_IE_CODEC_PREFS:
00797          ies->codec_prefs = (char *)data + 2;
00798          break;
00799       case IAX_IE_CAPABILITY:
00800          if (len != (int)sizeof(unsigned int)) {
00801             snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00802             errorf(tmp);
00803          } else if (ies->capability == 0) { /* Don't overwrite capability2, if specified */
00804             ies->capability = ntohl(get_unaligned_uint32(data + 2));
00805          }
00806          break;
00807       case IAX_IE_CAPABILITY2:
00808          {
00809             int version = data[2];
00810             if (version == 0) {
00811                if (len != (int)sizeof(char) + sizeof(format_t)) {
00812                   snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int) (sizeof(format_t) + sizeof(char)), len);
00813                   errorf(tmp);
00814                } else {
00815                   ies->capability = (format_t) ntohll(get_unaligned_uint64(data + 3));
00816                }
00817             } /* else unknown version */
00818          }
00819          break;
00820       case IAX_IE_FORMAT:
00821          if (len != (int)sizeof(unsigned int)) {
00822             snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00823             errorf(tmp);
00824          } else if (ies->format == 0) { /* Don't overwrite format2, if specified */
00825             ies->format = ntohl(get_unaligned_uint32(data + 2));
00826          }
00827          break;
00828       case IAX_IE_FORMAT2:
00829          {
00830             int version = data[2];
00831             if (version == 0) {
00832                if (len != (int)sizeof(char) + sizeof(format_t)) {
00833                   snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int) (sizeof(format_t) + sizeof(char)), len);
00834                   errorf(tmp);
00835                } else {
00836                   ies->format = (format_t) ntohll(get_unaligned_uint64(data + 3));
00837                }
00838             } /* else unknown version */
00839          }
00840          break;
00841       case IAX_IE_LANGUAGE:
00842          ies->language = (char *)data + 2;
00843          break;
00844       case IAX_IE_VERSION:
00845          if (len != (int)sizeof(unsigned short)) {
00846             snprintf(tmp, (int)sizeof(tmp),  "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00847             errorf(tmp);
00848          } else
00849             ies->version = ntohs(get_unaligned_uint16(data + 2));
00850          break;
00851       case IAX_IE_ADSICPE:
00852          if (len != (int)sizeof(unsigned short)) {
00853             snprintf(tmp, (int)sizeof(tmp), "Expecting adsicpe to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00854             errorf(tmp);
00855          } else
00856             ies->adsicpe = ntohs(get_unaligned_uint16(data + 2));
00857          break;
00858       case IAX_IE_SAMPLINGRATE:
00859          if (len != (int)sizeof(unsigned short)) {
00860             snprintf(tmp, (int)sizeof(tmp), "Expecting samplingrate to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00861             errorf(tmp);
00862          } else
00863             ies->samprate = ntohs(get_unaligned_uint16(data + 2));
00864          break;
00865       case IAX_IE_DNID:
00866          ies->dnid = (char *)data + 2;
00867          break;
00868       case IAX_IE_RDNIS:
00869          ies->rdnis = (char *)data + 2;
00870          break;
00871       case IAX_IE_AUTHMETHODS:
00872          if (len != (int)sizeof(unsigned short))  {
00873             snprintf(tmp, (int)sizeof(tmp), "Expecting authmethods to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00874             errorf(tmp);
00875          } else
00876             ies->authmethods = ntohs(get_unaligned_uint16(data + 2));
00877          break;
00878       case IAX_IE_ENCRYPTION:
00879          if (len != (int)sizeof(unsigned short))  {
00880             snprintf(tmp, (int)sizeof(tmp), "Expecting encryption to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00881             errorf(tmp);
00882          } else
00883             ies->encmethods = ntohs(get_unaligned_uint16(data + 2));
00884          break;
00885       case IAX_IE_CHALLENGE:
00886          ies->challenge = (char *)data + 2;
00887          break;
00888       case IAX_IE_MD5_RESULT:
00889          ies->md5_result = (char *)data + 2;
00890          break;
00891       case IAX_IE_RSA_RESULT:
00892          ies->rsa_result = (char *)data + 2;
00893          break;
00894       case IAX_IE_APPARENT_ADDR:
00895          ies->apparent_addr = ((struct sockaddr_in *)(data + 2));
00896          break;
00897       case IAX_IE_REFRESH:
00898          if (len != (int)sizeof(unsigned short)) {
00899             snprintf(tmp, (int)sizeof(tmp),  "Expecting refresh to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00900             errorf(tmp);
00901          } else
00902             ies->refresh = ntohs(get_unaligned_uint16(data + 2));
00903          break;
00904       case IAX_IE_DPSTATUS:
00905          if (len != (int)sizeof(unsigned short)) {
00906             snprintf(tmp, (int)sizeof(tmp),  "Expecting dpstatus to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00907             errorf(tmp);
00908          } else
00909             ies->dpstatus = ntohs(get_unaligned_uint16(data + 2));
00910          break;
00911       case IAX_IE_CALLNO:
00912          if (len != (int)sizeof(unsigned short)) {
00913             snprintf(tmp, (int)sizeof(tmp),  "Expecting callno to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00914             errorf(tmp);
00915          } else
00916             ies->callno = ntohs(get_unaligned_uint16(data + 2));
00917          break;
00918       case IAX_IE_CAUSE:
00919          ies->cause = (char *)data + 2;
00920          break;
00921       case IAX_IE_CAUSECODE:
00922          if (len != 1) {
00923             snprintf(tmp, (int)sizeof(tmp), "Expecting causecode to be single byte but was %d\n", len);
00924             errorf(tmp);
00925          } else {
00926             ies->causecode = data[2];
00927          }
00928          break;
00929       case IAX_IE_IAX_UNKNOWN:
00930          if (len == 1)
00931             ies->iax_unknown = data[2];
00932          else {
00933             snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len);
00934             errorf(tmp);
00935          }
00936          break;
00937       case IAX_IE_MSGCOUNT:
00938          if (len != (int)sizeof(unsigned short)) {
00939             snprintf(tmp, (int)sizeof(tmp), "Expecting msgcount to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00940             errorf(tmp);
00941          } else
00942             ies->msgcount = ntohs(get_unaligned_uint16(data + 2));   
00943          break;
00944       case IAX_IE_AUTOANSWER:
00945          ies->autoanswer = 1;
00946          break;
00947       case IAX_IE_MUSICONHOLD:
00948          ies->musiconhold = 1;
00949          break;
00950       case IAX_IE_TRANSFERID:
00951          if (len != (int)sizeof(unsigned int)) {
00952             snprintf(tmp, (int)sizeof(tmp), "Expecting transferid to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00953             errorf(tmp);
00954          } else
00955             ies->transferid = ntohl(get_unaligned_uint32(data + 2));
00956          break;
00957       case IAX_IE_DATETIME:
00958          if (len != (int)sizeof(unsigned int)) {
00959             snprintf(tmp, (int)sizeof(tmp), "Expecting date/time to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00960             errorf(tmp);
00961          } else
00962             ies->datetime = ntohl(get_unaligned_uint32(data + 2));
00963          break;
00964       case IAX_IE_FIRMWAREVER:
00965          if (len != (int)sizeof(unsigned short)) {
00966             snprintf(tmp, (int)sizeof(tmp), "Expecting firmwarever to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00967             errorf(tmp);
00968          } else
00969             ies->firmwarever = ntohs(get_unaligned_uint16(data + 2));   
00970          break;
00971       case IAX_IE_DEVICETYPE:
00972          ies->devicetype = (char *)data + 2;
00973          break;
00974       case IAX_IE_SERVICEIDENT:
00975          ies->serviceident = (char *)data + 2;
00976          break;
00977       case IAX_IE_FWBLOCKDESC:
00978          if (len != (int)sizeof(unsigned int)) {
00979             snprintf(tmp, (int)sizeof(tmp), "Expected block desc to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00980             errorf(tmp);
00981          } else
00982             ies->fwdesc = ntohl(get_unaligned_uint32(data + 2));
00983          break;
00984       case IAX_IE_FWBLOCKDATA:
00985          ies->fwdata = data + 2;
00986          ies->fwdatalen = len;
00987          break;
00988       case IAX_IE_ENCKEY:
00989          ies->enckey = data + 2;
00990          ies->enckeylen = len;
00991          break;
00992       case IAX_IE_PROVVER:
00993          if (len != (int)sizeof(unsigned int)) {
00994             snprintf(tmp, (int)sizeof(tmp), "Expected provisioning version to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00995             errorf(tmp);
00996          } else {
00997             ies->provverpres = 1;
00998             ies->provver = ntohl(get_unaligned_uint32(data + 2));
00999          }
01000          break;
01001       case IAX_IE_CALLINGPRES:
01002          if (len == 1)
01003             ies->calling_pres = data[2];
01004          else {
01005             snprintf(tmp, (int)sizeof(tmp), "Expected single byte callingpres, but was %d long\n", len);
01006             errorf(tmp);
01007          }
01008          break;
01009       case IAX_IE_CALLINGTON:
01010          if (len == 1)
01011             ies->calling_ton = data[2];
01012          else {
01013             snprintf(tmp, (int)sizeof(tmp), "Expected single byte callington, but was %d long\n", len);
01014             errorf(tmp);
01015          }
01016          break;
01017       case IAX_IE_CALLINGTNS:
01018          if (len != (int)sizeof(unsigned short)) {
01019             snprintf(tmp, (int)sizeof(tmp), "Expecting callingtns to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
01020             errorf(tmp);
01021          } else
01022             ies->calling_tns = ntohs(get_unaligned_uint16(data + 2));   
01023          break;
01024                case IAX_IE_RR_JITTER:
01025                        if (len != (int)sizeof(unsigned int)) {
01026                                snprintf(tmp, (int)sizeof(tmp), "Expected jitter rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
01027                                errorf(tmp);
01028                        } else {
01029                                ies->rr_jitter = ntohl(get_unaligned_uint32(data + 2));
01030                        }
01031                        break;
01032                case IAX_IE_RR_LOSS:
01033                        if (len != (int)sizeof(unsigned int)) {
01034                                snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
01035                                errorf(tmp);
01036                        } else {
01037                                ies->rr_loss = ntohl(get_unaligned_uint32(data + 2));
01038                        }
01039                        break;
01040                case IAX_IE_RR_PKTS:
01041                        if (len != (int)sizeof(unsigned int)) {
01042                                snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
01043                                errorf(tmp);
01044                        } else {
01045                                ies->rr_pkts = ntohl(get_unaligned_uint32(data + 2));
01046                        }
01047                        break;
01048                case IAX_IE_RR_DELAY:
01049                        if (len != (int)sizeof(unsigned short)) {
01050                                snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
01051                         errorf(tmp);
01052                        } else {
01053                                ies->rr_delay = ntohs(get_unaligned_uint16(data + 2));
01054                        }
01055                        break;
01056       case IAX_IE_RR_DROPPED:
01057          if (len != (int)sizeof(unsigned int)) {
01058             snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
01059             errorf(tmp);
01060          } else {
01061             ies->rr_dropped = ntohl(get_unaligned_uint32(data + 2));
01062          }
01063          break;
01064       case IAX_IE_RR_OOO:
01065          if (len != (int)sizeof(unsigned int)) {
01066             snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
01067             errorf(tmp);
01068          } else {
01069             ies->rr_ooo = ntohl(get_unaligned_uint32(data + 2));
01070          }
01071          break;
01072       case IAX_IE_VARIABLE:
01073          ast_copy_string(tmp, (char *)data + 2, len + 1);
01074          tmp2 = strchr(tmp, '=');
01075          if (tmp2)
01076             *tmp2++ = '\0';
01077          else
01078             tmp2 = "";
01079          {
01080             struct ast_str *str = ast_str_create(16);
01081             /* Existing variable or new variable? */
01082             for (var2 = ies->vars, prev = NULL; var2; prev = var2, var2 = var2->next) {
01083                if (strcmp(tmp, var2->name) == 0) {
01084                   ast_str_set(&str, 0, "%s%s", var2->value, tmp2);
01085                   var = ast_variable_new(tmp, ast_str_buffer(str), var2->file);
01086                   var->next = var2->next;
01087                   if (prev) {
01088                      prev->next = var;
01089                   } else {
01090                      ies->vars = var;
01091                   }
01092                   snprintf(tmp, sizeof(tmp), "Assigned (%p)%s to (%p)%s\n", var->name, var->name, var->value, var->value);
01093                   outputf(tmp);
01094                   ast_free(var2);
01095                   break;
01096                }
01097             }
01098             ast_free(str);
01099          }
01100 
01101          if (!var2) {
01102             var = ast_variable_new(tmp, tmp2, "");
01103             snprintf(tmp, sizeof(tmp), "Assigned (%p)%s to (%p)%s\n", var->name, var->name, var->value, var->value);
01104             outputf(tmp);
01105             var->next = ies->vars;
01106             ies->vars = var;
01107          }
01108          break;
01109       case IAX_IE_OSPTOKEN:
01110          if ((count = data[2]) < IAX_MAX_OSPBLOCK_NUM) {
01111             ies->osptokenblock[count] = (char *)data + 2 + 1;
01112             ies->ospblocklength[count] = len - 1;
01113          } else {
01114             snprintf(tmp, (int)sizeof(tmp), "Expected OSP token block index to be 0~%d but was %d\n", IAX_MAX_OSPBLOCK_NUM - 1, count);
01115             errorf(tmp);
01116          }
01117          break;
01118       case IAX_IE_CALLTOKEN:
01119          if (len) {
01120             ies->calltokendata = (unsigned char *) data + 2;
01121          }
01122          ies->calltoken = 1;
01123          break;
01124       default:
01125          snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len);
01126          outputf(tmp);
01127       }
01128       /* Overwrite information element with 0, to null terminate previous portion */
01129       data[0] = 0;
01130       datalen -= (len + 2);
01131       data += (len + 2);
01132    }
01133    /* Null-terminate last field */
01134    *data = '\0';
01135    if (datalen) {
01136       errorf("Invalid information element contents, strange boundary\n");
01137       return -1;
01138    }
01139    return 0;
01140 }

void iax_set_error ( void(*)(const char *)  func  ) 

Definition at line 747 of file iax2-parser.c.

References errorf.

Referenced by load_module().

00748 {
00749    errorf = func;
00750 }

void iax_set_output ( void(*)(const char *)  func  ) 

Definition at line 742 of file iax2-parser.c.

References outputf.

Referenced by load_module().

00743 {
00744    outputf = func;
00745 }

void iax_showframe ( struct iax_frame f,
struct ast_iax2_full_hdr fhi,
int  rx,
struct sockaddr_in *  sin,
int  datalen 
)

Definition at line 565 of file iax2-parser.c.

References ARRAY_LEN, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_IAX, ast_inet_ntoa(), ast_iax2_full_hdr::csub, ast_iax2_full_hdr::dcallno, dump_ies(), f, IAX_FLAG_FULL, IAX_FLAG_RETRANS, iax_frame_subclass2str(), ast_iax2_full_hdr::iedata, ast_iax2_full_hdr::iseqno, ast_iax2_full_hdr::oseqno, outputf, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::ts, and ast_iax2_full_hdr::type.

Referenced by iax_outputframe(), and send_packet().

00566 {
00567    const char *framelist[] = {
00568       "(0?)",
00569       "DTMF_E ",
00570       "VOICE  ",
00571       "VIDEO  ",
00572       "CONTROL",
00573       "NULL   ",
00574       "IAX    ",
00575       "TEXT   ",
00576       "IMAGE  ",
00577       "HTML   ",
00578       "CNG    ",
00579       "MODEM  ",
00580       "DTMF_B ",
00581    };
00582    const char *cmds[] = {
00583       "(0?)",
00584       "HANGUP ",
00585       "RING   ",
00586       "RINGING",
00587       "ANSWER ",
00588       "BUSY   ",
00589       "TKOFFHK",
00590       "OFFHOOK",
00591       "CONGSTN",
00592       "FLASH  ",
00593       "WINK   ",
00594       "OPTION ",
00595       "RDKEY  ",
00596       "RDUNKEY",
00597       "PROGRES",
00598       "PROCDNG",
00599       "HOLD   ",
00600       "UNHOLD ",
00601       "VIDUPDT",
00602       "T38    ",
00603       "SRCUPDT",
00604       "TXFER  ",
00605       "CNLINE ",
00606       "REDIR  ",
00607    };
00608    struct ast_iax2_full_hdr *fh;
00609    char retries[20];
00610    char class2[20];
00611    char subclass2[20];
00612    const char *class;
00613    const char *subclass;
00614    char *dir;
00615    char tmp[512];
00616 
00617    switch(rx) {
00618    case 0:
00619       dir = "Tx";
00620       break;
00621    case 2:
00622       dir = "TE";
00623       break;
00624    case 3:
00625       dir = "RD";
00626       break;
00627    default:
00628       dir = "Rx";
00629       break;
00630    }
00631    if (f) {
00632       fh = f->data;
00633       snprintf(retries, sizeof(retries), "%03d", f->retries);
00634    } else {
00635       fh = fhi;
00636       if (ntohs(fh->dcallno) & IAX_FLAG_RETRANS)
00637          strcpy(retries, "Yes");
00638       else
00639          strcpy(retries, " No");
00640    }
00641    if (!(ntohs(fh->scallno) & IAX_FLAG_FULL)) {
00642       /* Don't mess with mini-frames */
00643       return;
00644    }
00645    if (fh->type >= ARRAY_LEN(framelist)) {
00646       snprintf(class2, sizeof(class2), "(%d?)", fh->type);
00647       class = class2;
00648    } else {
00649       class = framelist[(int)fh->type];
00650    }
00651    if (fh->type == AST_FRAME_DTMF_BEGIN || fh->type == AST_FRAME_DTMF_END) {
00652       sprintf(subclass2, "%c", fh->csub);
00653       subclass = subclass2;
00654    } else if (fh->type == AST_FRAME_IAX) {
00655          iax_frame_subclass2str((int)fh->csub, subclass2, sizeof(subclass2));
00656          subclass = subclass2;
00657    } else if (fh->type == AST_FRAME_CONTROL) {
00658       if (fh->csub >= ARRAY_LEN(cmds)) {
00659          snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub);
00660          subclass = subclass2;
00661       } else {
00662          subclass = cmds[(int)fh->csub];
00663       }
00664    } else {
00665       snprintf(subclass2, sizeof(subclass2), "%d", fh->csub);
00666       subclass = subclass2;
00667    }
00668    snprintf(tmp, sizeof(tmp), 
00669        "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s Subclass: %s\n",
00670        dir,
00671        retries, fh->oseqno, fh->iseqno, class, subclass);
00672    outputf(tmp);
00673    snprintf(tmp, sizeof(tmp), 
00674        "   Timestamp: %05lums  SCall: %5.5d  DCall: %5.5d [%s:%d]\n",
00675        (unsigned long)ntohl(fh->ts),
00676        ntohs(fh->scallno) & ~IAX_FLAG_FULL, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS,
00677        ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
00678    outputf(tmp);
00679    if (fh->type == AST_FRAME_IAX)
00680       dump_ies(fh->iedata, datalen);
00681 }

static void internalerror ( const char *  str  )  [static]

Definition at line 76 of file iax2-parser.c.

00077 {
00078    fprintf(stderr, "WARNING: %s", str);
00079 }

static void internaloutput ( const char *  str  )  [static]

Definition at line 71 of file iax2-parser.c.

00072 {
00073    fputs(str, stdout);
00074 }


Variable Documentation

void(*) errorf(const char *str) = internalerror [static]

Definition at line 82 of file iax2-parser.c.

Referenced by dundi_ie_append_answer(), dundi_ie_append_cause(), dundi_ie_append_encdata(), dundi_ie_append_hint(), dundi_ie_append_raw(), dundi_parse_ies(), dundi_set_error(), iax_frame_free(), iax_ie_append_raw(), iax_parse_ies(), and iax_set_error().

struct ast_threadstorage frame_cache = { .once = PTHREAD_ONCE_INIT , .key_init = __init_frame_cache , .custom_init = NULL , } [static]

Definition at line 57 of file iax2-parser.c.

Referenced by __frame_free(), ast_frame_header_new(), ast_frdup(), iax_frame_free(), and iax_frame_new().

int frames = 0 [static]

Definition at line 49 of file iax2-parser.c.

Referenced by __ast_answer(), __ast_queue_frame(), __frame_free(), ast_frame_header_new(), ast_frdup(), ast_rtp_read(), fixed_jb_get(), frame_cache_cleanup(), process_dtmf_rfc2833(), and queue_put().

int iframes = 0 [static]

Definition at line 50 of file iax2-parser.c.

struct iax2_ie infoelts[] [static]

Referenced by dump_ies(), dundi_ie2str(), and iax_ie2str().

int oframes = 0 [static]

Definition at line 51 of file iax2-parser.c.

void(*) outputf(const char *str) = internaloutput [static]

Definition at line 81 of file iax2-parser.c.

Referenced by dump_ies(), dundi_parse_ies(), dundi_set_output(), dundi_showframe(), iax_parse_ies(), iax_set_output(), and iax_showframe().

struct iax2_ie prov_ies[] [static]

Definition at line 304 of file iax2-parser.c.

Referenced by dump_prov_ies().


Generated on Mon Oct 8 12:39:23 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7