Wed Oct 28 11:52:42 2009

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"

Include dependency graph for iax2-parser.c:

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 frame_cache_cleanup (void *data)
void iax_frame_free (struct iax_frame *fr)
struct 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_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 64 of file iax2-parser.c.


Function Documentation

static void __init_frame_cache ( void   )  [static]

A per-thread cache of iax_frame structures.

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

00059 {

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

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

References ast_copy_string(), and ast_inet_ntoa().

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

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

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

References ast_copy_string().

00146 {
00147    if (len == (int)sizeof(unsigned char))
00148       snprintf(output, maxlen, "%d", *((unsigned char *)value));
00149    else
00150       ast_copy_string(output, "Invalid BYTE", maxlen);
00151 }

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

Definition at line 153 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.

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

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

Definition at line 365 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().

00366 {
00367    int ielen;
00368    int ie;
00369    int x;
00370    int found;
00371    char interp[1024];
00372    char tmp[1024];
00373    if (len < 2)
00374       return;
00375    while(len > 2) {
00376       ie = iedata[0];
00377       ielen = iedata[1];
00378       if (ielen + 2> len) {
00379          snprintf(tmp, (int)sizeof(tmp), "Total IE length of %d bytes exceeds remaining frame length of %d bytes\n", ielen + 2, len);
00380          outputf(tmp);
00381          return;
00382       }
00383       found = 0;
00384       for (x = 0; x < ARRAY_LEN(infoelts); x++) {
00385          if (infoelts[x].ie == ie) {
00386             if (infoelts[x].dump) {
00387                infoelts[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen);
00388                snprintf(tmp, (int)sizeof(tmp), "   %-15.15s : %s\n", infoelts[x].name, interp);
00389                outputf(tmp);
00390             } else {
00391                if (ielen)
00392                   snprintf(interp, (int)sizeof(interp), "%d bytes", ielen);
00393                else
00394                   strcpy(interp, "Present");
00395                snprintf(tmp, (int)sizeof(tmp), "   %-15.15s : %s\n", infoelts[x].name, interp);
00396                outputf(tmp);
00397             }
00398             found++;
00399          }
00400       }
00401       if (!found) {
00402          snprintf(tmp, (int)sizeof(tmp), "   Unknown IE %03d  : Present\n", ie);
00403          outputf(tmp);
00404       }
00405       iedata += (2 + ielen);
00406       len -= (2 + ielen);
00407    }
00408    outputf("\n");
00409 }

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

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

References ast_copy_string(), and get_unaligned_uint32().

00130 {
00131    if (len == (int)sizeof(unsigned int))
00132       snprintf(output, maxlen, "%lu", (unsigned long)ntohl(get_unaligned_uint32(value)));
00133    else
00134       ast_copy_string(output, "Invalid INT", maxlen); 
00135 }

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

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

References ast_copy_string(), and ast_inet_ntoa().

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

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

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

References ast_codec_pref_convert(), and ast_codec_pref_string().

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

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

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

References dump_prov_ies().

00219 {
00220    dump_prov_ies(output, maxlen, value, len);
00221 }

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

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

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

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

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

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

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

Referenced by dump_prov().

00314 {
00315    int ielen;
00316    int ie;
00317    int x;
00318    int found;
00319    char interp[80];
00320    char tmp[256];
00321    if (len < 2)
00322       return;
00323    strcpy(output, "\n"); 
00324    maxlen -= strlen(output); output += strlen(output);
00325    while(len > 2) {
00326       ie = iedata[0];
00327       ielen = iedata[1];
00328       if (ielen + 2> len) {
00329          snprintf(tmp, (int)sizeof(tmp), "Total Prov IE length of %d bytes exceeds remaining prov frame length of %d bytes\n", ielen + 2, len);
00330          ast_copy_string(output, tmp, maxlen);
00331          maxlen -= strlen(output);
00332          output += strlen(output);
00333          return;
00334       }
00335       found = 0;
00336       for (x=0;x<(int)sizeof(prov_ies) / (int)sizeof(prov_ies[0]); x++) {
00337          if (prov_ies[x].ie == ie) {
00338             if (prov_ies[x].dump) {
00339                prov_ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen);
00340                snprintf(tmp, (int)sizeof(tmp), "       %-15.15s : %s\n", prov_ies[x].name, interp);
00341                ast_copy_string(output, tmp, maxlen);
00342                maxlen -= strlen(output); output += strlen(output);
00343             } else {
00344                if (ielen)
00345                   snprintf(interp, (int)sizeof(interp), "%d bytes", ielen);
00346                else
00347                   strcpy(interp, "Present");
00348                snprintf(tmp, (int)sizeof(tmp), "       %-15.15s : %s\n", prov_ies[x].name, interp);
00349                ast_copy_string(output, tmp, maxlen);
00350                maxlen -= strlen(output); output += strlen(output);
00351             }
00352             found++;
00353          }
00354       }
00355       if (!found) {
00356          snprintf(tmp, (int)sizeof(tmp), "       Unknown Prov IE %03d  : Present\n", ie);
00357          ast_copy_string(output, tmp, maxlen);
00358          maxlen -= strlen(output); output += strlen(output);
00359       }
00360       iedata += (2 + ielen);
00361       len -= (2 + ielen);
00362    }
00363 }

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

Definition at line 190 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.

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

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

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

References ast_copy_string(), and get_unaligned_uint16().

00138 {
00139    if (len == (int)sizeof(unsigned short))
00140       snprintf(output, maxlen, "%d", ntohs(get_unaligned_uint16(value)));
00141    else
00142       ast_copy_string(output, "Invalid SHORT", maxlen);
00143 }

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

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

00102 {
00103    maxlen--;
00104    if (maxlen > len)
00105       maxlen = len;
00106    strncpy(output, value, maxlen);
00107    output[maxlen] = '\0';
00108 }

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

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

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

static void frame_cache_cleanup ( void *  data  )  [static]

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

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

01206 {
01207    struct iax_frames *framelist = data;
01208    struct iax_frame *current;
01209 
01210    while ((current = AST_LIST_REMOVE_HEAD(&framelist->list, list)))
01211       ast_free(current);
01212 
01213    ast_free(framelist);
01214 }

void iax_frame_free ( struct iax_frame fr  ) 

Definition at line 1165 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, iax_frames::list, and iax_frames::size.

Referenced by iax2_frame_free(), and network_thread().

01166 {
01167 #if !defined(LOW_MEMORY)
01168    struct iax_frames *iax_frames = NULL;
01169 #endif
01170 
01171    /* Note: does not remove from scheduler! */
01172    if (fr->direction == DIRECTION_INGRESS)
01173       ast_atomic_fetchadd_int(&iframes, -1);
01174    else if (fr->direction == DIRECTION_OUTGRESS)
01175       ast_atomic_fetchadd_int(&oframes, -1);
01176    else {
01177       errorf("Attempt to double free frame detected\n");
01178       return;
01179    }
01180    ast_atomic_fetchadd_int(&frames, -1);
01181 
01182 #if !defined(LOW_MEMORY)
01183    if (!fr->cacheable || !(iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
01184       ast_free(fr);
01185       return;
01186    }
01187 
01188    if (iax_frames->size < FRAME_CACHE_MAX_SIZE) {
01189       fr->direction = 0;
01190       /* Pseudo-sort: keep smaller frames at the top of the list. This should
01191        * increase the chance that we pick the smallest applicable frame for use. */
01192       if (AST_LIST_FIRST(&iax_frames->list) && AST_LIST_FIRST(&iax_frames->list)->afdatalen < fr->afdatalen) {
01193          AST_LIST_INSERT_TAIL(&iax_frames->list, fr, list);
01194       } else {
01195          AST_LIST_INSERT_HEAD(&iax_frames->list, fr, list);
01196       }
01197       iax_frames->size++;
01198       return;
01199    }
01200 #endif
01201    ast_free(fr);
01202 }

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

Definition at line 1107 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(), iax_frame::cacheable, iax_frame::direction, DIRECTION_INGRESS, frame_cache, FRAME_CACHE_MAX_SIZE, iax_frame::list, iax_frames::list, iax_frame::retrans, and iax_frames::size.

Referenced by iax2_send(), and iaxfrdup2().

01108 {
01109    struct iax_frame *fr = NULL;
01110 
01111 #if !defined(LOW_MEMORY)
01112    struct iax_frames *iax_frames = NULL;
01113    struct iax_frame *smallest = NULL;
01114 
01115    /* Attempt to get a frame from this thread's cache */
01116    if ((iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
01117       smallest = AST_LIST_FIRST(&iax_frames->list);
01118       AST_LIST_TRAVERSE_SAFE_BEGIN(&iax_frames->list, fr, list) {
01119          if (fr->afdatalen >= datalen) {
01120             size_t afdatalen = fr->afdatalen;
01121             AST_LIST_REMOVE_CURRENT(list);
01122             iax_frames->size--;
01123             memset(fr, 0, sizeof(*fr));
01124             fr->afdatalen = afdatalen;
01125             break;
01126          } else if (smallest->afdatalen > fr->afdatalen) {
01127             smallest = fr;
01128          }
01129       }
01130       AST_LIST_TRAVERSE_SAFE_END;
01131    }
01132    if (!fr) {
01133       if (iax_frames->size >= FRAME_CACHE_MAX_SIZE && smallest) {
01134          /* Make useless cache into something more useful */
01135          AST_LIST_REMOVE(&iax_frames->list, smallest, list);
01136          if (!(fr = ast_realloc(smallest, sizeof(*fr) + datalen))) {
01137             AST_LIST_INSERT_TAIL(&iax_frames->list, smallest, list);
01138             return NULL;
01139          }
01140       } else if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen)))
01141          return NULL;
01142       fr->afdatalen = datalen;
01143    }
01144 #else
01145    if (!(fr = ast_calloc(1, sizeof(*fr) + datalen)))
01146       return NULL;
01147    fr->afdatalen = datalen;
01148 #endif
01149 
01150 
01151    fr->direction = direction;
01152    fr->retrans = -1;
01153    fr->cacheable = cacheable;
01154    
01155    if (fr->direction == DIRECTION_INGRESS)
01156       ast_atomic_fetchadd_int(&iframes, 1);
01157    else
01158       ast_atomic_fetchadd_int(&oframes, 1);
01159    
01160    ast_atomic_fetchadd_int(&frames, 1);
01161 
01162    return fr;
01163 }

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

Definition at line 411 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().

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

void iax_frame_wrap ( struct iax_frame fr,
struct ast_frame f 
)

Definition at line 1076 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::data, ast_frame::datalen, ast_frame::delivery, 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().

01077 {
01078    fr->af.frametype = f->frametype;
01079    fr->af.subclass = f->subclass;
01080    fr->af.mallocd = 0;           /* Our frame is static relative to the container */
01081    fr->af.datalen = f->datalen;
01082    fr->af.samples = f->samples;
01083    fr->af.offset = AST_FRIENDLY_OFFSET;
01084    fr->af.src = f->src;
01085    fr->af.delivery.tv_sec = 0;
01086    fr->af.delivery.tv_usec = 0;
01087    fr->af.data.ptr = fr->afdata;
01088    fr->af.len = f->len;
01089    if (fr->af.datalen) {
01090       size_t copy_len = fr->af.datalen;
01091       if (copy_len > fr->afdatalen) {
01092          ast_log(LOG_ERROR, "Losing frame data because destination buffer size '%d' bytes not big enough for '%d' bytes in the frame\n",
01093             (int) fr->afdatalen, (int) fr->af.datalen);
01094          copy_len = fr->afdatalen;
01095       }
01096 #if __BYTE_ORDER == __LITTLE_ENDIAN
01097       /* We need to byte-swap slinear samples from network byte order */
01098       if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass == AST_FORMAT_SLINEAR)) {
01099          /* 2 bytes / sample for SLINEAR */
01100          ast_swapcopy_samples(fr->af.data.ptr, f->data.ptr, copy_len / 2);
01101       } else
01102 #endif
01103          memcpy(fr->af.data.ptr, f->data.ptr, copy_len);
01104    }
01105 }

int iax_get_frames ( void   ) 

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

Referenced by handle_cli_iax2_show_stats().

01217 { return frames; }

int iax_get_iframes ( void   ) 

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

Referenced by handle_cli_iax2_show_stats().

01218 { return iframes; }

int iax_get_oframes ( void   ) 

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

Referenced by handle_cli_iax2_show_stats().

01219 { return oframes; }

const char* iax_ie2str ( int  ie  ) 

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

References ARRAY_LEN, infoelts, and iax2_ie::name.

Referenced by iax_ie_append_raw(), and iax_parse_ies().

00303 {
00304    int x;
00305    for (x = 0; x < ARRAY_LEN(infoelts); x++) {
00306       if (infoelts[x].ie == ie)
00307          return infoelts[x].name;
00308    }
00309    return "Unknown IE";
00310 }

int iax_ie_append ( struct iax_ie_data ied,
unsigned char  ie 
)

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

References iax_ie_append_raw().

Referenced by iax2_call(), and iax_firmware_append().

00700 {
00701    return iax_ie_append_raw(ied, ie, NULL, 0);
00702 }

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

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

References iax_ie_append_raw().

Referenced by iax2_start_transfer(), and update_registry().

00671 {
00672    return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in));
00673 }

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

Definition at line 694 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().

00695 {
00696    return iax_ie_append_raw(ied, ie, &dat, 1);
00697 }

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

Definition at line 675 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().

00676 {
00677    unsigned int newval;
00678    newval = htonl(value);
00679    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00680 }

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

Definition at line 655 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(), and iax_ie_append_str().

00656 {
00657    char tmp[256];
00658    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00659       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);
00660       errorf(tmp);
00661       return -1;
00662    }
00663    ied->buf[ied->pos++] = ie;
00664    ied->buf[ied->pos++] = datalen;
00665    memcpy(ied->buf + ied->pos, data, datalen);
00666    ied->pos += datalen;
00667    return 0;
00668 }

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

Definition at line 682 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().

00683 {
00684    unsigned short newval;
00685    newval = htons(value);
00686    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00687 }

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

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

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

References iax_ies::adsicpe, iax_ies::apparent_addr, ast_copy_string(), ast_free, 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(), 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_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_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, 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, ast_str::str, str, iax_ies::transferid, iax_ies::username, ast_variable::value, var, iax_ies::vars, and iax_ies::version.

Referenced by socket_process().

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

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

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

References errorf.

Referenced by load_module().

00710 {
00711    errorf = func;
00712 }

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

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

References outputf.

Referenced by load_module().

00705 {
00706    outputf = func;
00707 }

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

Definition at line 543 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, iax_frame::data, ast_iax2_full_hdr::dcallno, dir, dump_ies(), 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, iax_frame::retries, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::ts, and ast_iax2_full_hdr::type.

Referenced by iax_outputframe(), and send_packet().

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

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

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

00073 {
00074    fprintf(stderr, "WARNING: %s", str);
00075 }

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

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

00068 {
00069    fputs(str, stdout);
00070 }


Variable Documentation

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]

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

int frames = 0 [static]

int iframes = 0 [static]

Definition at line 46 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 47 of file iax2-parser.c.

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

struct iax2_ie prov_ies[] [static]

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


Generated on Wed Oct 28 11:52:42 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6