Thu Jul 9 13:41:21 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"

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 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_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 struct iax2_ie ies []
static int iframes = 0
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 135 of file iax2-parser.c.

References ast_copy_string().

00136 {
00137    if (len == (int)sizeof(unsigned char))
00138       snprintf(output, maxlen, "%d", *((unsigned char *)value));
00139    else
00140       ast_copy_string(output, "Invalid BYTE", maxlen);
00141 }

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

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

00144 {
00145    struct ast_tm tm;
00146    unsigned long val = (unsigned long) ntohl(get_unaligned_uint32(value));
00147    if (len == (int)sizeof(unsigned int)) {
00148       tm.tm_sec  = (val & 0x1f) << 1;
00149       tm.tm_min  = (val >> 5) & 0x3f;
00150       tm.tm_hour = (val >> 11) & 0x1f;
00151       tm.tm_mday = (val >> 16) & 0x1f;
00152       tm.tm_mon  = ((val >> 21) & 0x0f) - 1;
00153       tm.tm_year = ((val >> 25) & 0x7f) + 100;
00154       ast_strftime(output, maxlen, "%Y-%m-%d  %T", &tm); 
00155    } else
00156       ast_copy_string(output, "Invalid DATETIME format!", maxlen);
00157 }

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

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

References iax2_ie::dump, iax2_ie::ie, ies, name, and outputf.

Referenced by dundi_showframe(), and iax_showframe().

00356 {
00357    int ielen;
00358    int ie;
00359    int x;
00360    int found;
00361    char interp[1024];
00362    char tmp[1024];
00363    if (len < 2)
00364       return;
00365    while(len > 2) {
00366       ie = iedata[0];
00367       ielen = iedata[1];
00368       if (ielen + 2> len) {
00369          snprintf(tmp, (int)sizeof(tmp), "Total IE length of %d bytes exceeds remaining frame length of %d bytes\n", ielen + 2, len);
00370          outputf(tmp);
00371          return;
00372       }
00373       found = 0;
00374       for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
00375          if (ies[x].ie == ie) {
00376             if (ies[x].dump) {
00377                ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen);
00378                snprintf(tmp, (int)sizeof(tmp), "   %-15.15s : %s\n", ies[x].name, interp);
00379                outputf(tmp);
00380             } else {
00381                if (ielen)
00382                   snprintf(interp, (int)sizeof(interp), "%d bytes", ielen);
00383                else
00384                   strcpy(interp, "Present");
00385                snprintf(tmp, (int)sizeof(tmp), "   %-15.15s : %s\n", ies[x].name, interp);
00386                outputf(tmp);
00387             }
00388             found++;
00389          }
00390       }
00391       if (!found) {
00392          snprintf(tmp, (int)sizeof(tmp), "   Unknown IE %03d  : Present\n", ie);
00393          outputf(tmp);
00394       }
00395       iedata += (2 + ielen);
00396       len -= (2 + ielen);
00397    }
00398    outputf("\n");
00399 }

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

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

References ast_copy_string(), and get_unaligned_uint32().

00120 {
00121    if (len == (int)sizeof(unsigned int))
00122       snprintf(output, maxlen, "%lu", (unsigned long)ntohl(get_unaligned_uint32(value)));
00123    else
00124       ast_copy_string(output, "Invalid INT", maxlen); 
00125 }

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

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

References ast_copy_string(), and ast_inet_ntoa().

00160 {
00161    struct sockaddr_in sin;
00162    if (len == (int)sizeof(unsigned int)) {
00163       memcpy(&sin.sin_addr, value, len);
00164       snprintf(output, maxlen, "%s", ast_inet_ntoa(sin.sin_addr));
00165    } else
00166       ast_copy_string(output, "Invalid IPADDR", maxlen);
00167 }

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

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

References ast_codec_pref_convert(), and ast_codec_pref_string().

00101 {
00102    struct ast_codec_pref pref;
00103    int total_len = 0;
00104 
00105    maxlen--;
00106    total_len = maxlen;
00107 
00108    if (maxlen > len)
00109       maxlen = len;
00110 
00111    strncpy(output, value, maxlen);
00112    output[maxlen] = '\0';
00113    
00114    ast_codec_pref_convert(&pref, output, total_len, 0);
00115    memset(output,0,total_len);
00116    ast_codec_pref_string(&pref, output, total_len);
00117 }

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

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

References dump_prov_ies().

00209 {
00210    dump_prov_ies(output, maxlen, value, len);
00211 }

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

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

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

00171 {
00172    char buf[256] = "";
00173    if (len == (int)sizeof(unsigned int))
00174       snprintf(output, maxlen, "%lu (%s)", (unsigned long)ntohl(get_unaligned_uint32(value)),
00175          iax_provflags2str(buf, sizeof(buf), ntohl(get_unaligned_uint32(value))));
00176    else
00177       ast_copy_string(output, "Invalid INT", maxlen);
00178 }

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

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

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

Referenced by dump_prov().

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

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

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

00181 {
00182    char tmp[256]="";
00183    int sr;
00184    if (len == (int)sizeof(unsigned short)) {
00185       sr = ntohs(*((unsigned short *)value));
00186       if (sr & IAX_RATE_8KHZ)
00187          strcat(tmp, ",8khz");
00188       if (sr & IAX_RATE_11KHZ)
00189          strcat(tmp, ",11.025khz");
00190       if (sr & IAX_RATE_16KHZ)
00191          strcat(tmp, ",16khz");
00192       if (sr & IAX_RATE_22KHZ)
00193          strcat(tmp, ",22.05khz");
00194       if (sr & IAX_RATE_44KHZ)
00195          strcat(tmp, ",44.1khz");
00196       if (sr & IAX_RATE_48KHZ)
00197          strcat(tmp, ",48khz");
00198       if (strlen(tmp))
00199          ast_copy_string(output, &tmp[1], maxlen);
00200       else
00201          ast_copy_string(output, "None Specified!\n", maxlen);
00202    } else
00203       ast_copy_string(output, "Invalid SHORT", maxlen);
00204 
00205 }

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

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

References ast_copy_string(), and get_unaligned_uint16().

00128 {
00129    if (len == (int)sizeof(unsigned short))
00130       snprintf(output, maxlen, "%d", ntohs(get_unaligned_uint16(value)));
00131    else
00132       ast_copy_string(output, "Invalid SHORT", maxlen);
00133 }

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

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

00092 {
00093    maxlen--;
00094    if (maxlen > len)
00095       maxlen = len;
00096    strncpy(output, value, maxlen);
00097    output[maxlen] = '\0';
00098 }

static void frame_cache_cleanup ( void *  data  )  [static]

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

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

01160 {
01161    struct iax_frames *frames = data;
01162    struct iax_frame *cur;
01163 
01164    while ((cur = AST_LIST_REMOVE_HEAD(&frames->list, list)))
01165       ast_free(cur);
01166 
01167    ast_free(frames);
01168 }

void iax_frame_free ( struct iax_frame fr  ) 

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

References ast_atomic_fetchadd_int(), ast_free, AST_LIST_INSERT_HEAD, 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 network_thread().

01126 {
01127 #if !defined(LOW_MEMORY)
01128    struct iax_frames *iax_frames = NULL;
01129 #endif
01130 
01131    /* Note: does not remove from scheduler! */
01132    if (fr->direction == DIRECTION_INGRESS)
01133       ast_atomic_fetchadd_int(&iframes, -1);
01134    else if (fr->direction == DIRECTION_OUTGRESS)
01135       ast_atomic_fetchadd_int(&oframes, -1);
01136    else {
01137       errorf("Attempt to double free frame detected\n");
01138       return;
01139    }
01140    ast_atomic_fetchadd_int(&frames, -1);
01141 
01142 #if !defined(LOW_MEMORY)
01143    if (!fr->cacheable || !(iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
01144       ast_free(fr);
01145       return;
01146    }
01147 
01148    if (iax_frames->size < FRAME_CACHE_MAX_SIZE) {
01149       fr->direction = 0;
01150       AST_LIST_INSERT_HEAD(&iax_frames->list, fr, list);
01151       iax_frames->size++;
01152       return;
01153    }
01154 #endif
01155    ast_free(fr);
01156 }

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

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

References iax_frame::afdatalen, ast_atomic_fetchadd_int(), ast_calloc, ast_calloc_cache, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_threadstorage_get(), DIRECTION_INGRESS, frame_cache, and iax_frames::list.

Referenced by iax2_send(), and iaxfrdup2().

01079 {
01080    struct iax_frame *fr = NULL;
01081 
01082 #if !defined(LOW_MEMORY)
01083    struct iax_frames *iax_frames = NULL;
01084 
01085    /* Attempt to get a frame from this thread's cache */
01086    if ((iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
01087       AST_LIST_TRAVERSE_SAFE_BEGIN(&iax_frames->list, fr, list) {
01088          if (fr->afdatalen >= datalen) {
01089             size_t afdatalen = fr->afdatalen;
01090             AST_LIST_REMOVE_CURRENT(list);
01091             iax_frames->size--;
01092             memset(fr, 0, sizeof(*fr));
01093             fr->afdatalen = afdatalen;
01094             break;
01095          }
01096       }
01097       AST_LIST_TRAVERSE_SAFE_END;
01098    }
01099    if (!fr) {
01100       if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen)))
01101          return NULL;
01102       fr->afdatalen = datalen;
01103    }
01104 #else
01105    if (!(fr = ast_calloc(1, sizeof(*fr) + datalen)))
01106       return NULL;
01107    fr->afdatalen = datalen;
01108 #endif
01109 
01110 
01111    fr->direction = direction;
01112    fr->retrans = -1;
01113    fr->cacheable = cacheable;
01114    
01115    if (fr->direction == DIRECTION_INGRESS)
01116       ast_atomic_fetchadd_int(&iframes, 1);
01117    else
01118       ast_atomic_fetchadd_int(&oframes, 1);
01119    
01120    ast_atomic_fetchadd_int(&frames, 1);
01121 
01122    return fr;
01123 }

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

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

References ast_copy_string(), IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, 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_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().

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

void iax_frame_wrap ( struct iax_frame fr,
struct ast_frame f 
)

Definition at line 1047 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, f, ast_frame::frametype, ast_frame::len, LOG_ERROR, ast_frame::mallocd, ast_frame::offset, ast_frame::samples, ast_frame::src, and ast_frame::subclass.

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

01048 {
01049    fr->af.frametype = f->frametype;
01050    fr->af.subclass = f->subclass;
01051    fr->af.mallocd = 0;           /* Our frame is static relative to the container */
01052    fr->af.datalen = f->datalen;
01053    fr->af.samples = f->samples;
01054    fr->af.offset = AST_FRIENDLY_OFFSET;
01055    fr->af.src = f->src;
01056    fr->af.delivery.tv_sec = 0;
01057    fr->af.delivery.tv_usec = 0;
01058    fr->af.data = fr->afdata;
01059    fr->af.len = f->len;
01060    if (fr->af.datalen) {
01061       size_t copy_len = fr->af.datalen;
01062       if (copy_len > fr->afdatalen) {
01063          ast_log(LOG_ERROR, "Losing frame data because destination buffer size '%d' bytes not big enough for '%d' bytes in the frame\n",
01064             (int) fr->afdatalen, (int) fr->af.datalen);
01065          copy_len = fr->afdatalen;
01066       }
01067 #if __BYTE_ORDER == __LITTLE_ENDIAN
01068       /* We need to byte-swap slinear samples from network byte order */
01069       if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass == AST_FORMAT_SLINEAR)) {
01070          /* 2 bytes / sample for SLINEAR */
01071          ast_swapcopy_samples(fr->af.data, f->data, copy_len / 2);
01072       } else
01073 #endif
01074          memcpy(fr->af.data, f->data, copy_len);
01075    }
01076 }

int iax_get_frames ( void   ) 

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

Referenced by handle_cli_iax2_show_stats().

01171 { return frames; }

int iax_get_iframes ( void   ) 

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

Referenced by handle_cli_iax2_show_stats().

01172 { return iframes; }

int iax_get_oframes ( void   ) 

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

Referenced by handle_cli_iax2_show_stats().

01173 { return oframes; }

const char* iax_ie2str ( int  ie  ) 

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

References ies, and name.

Referenced by iax_ie_append_raw(), and iax_parse_ies().

00293 {
00294    int x;
00295    for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
00296       if (ies[x].ie == ie)
00297          return ies[x].name;
00298    }
00299    return "Unknown IE";
00300 }

int iax_ie_append ( struct iax_ie_data ied,
unsigned char  ie 
)

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

References iax_ie_append_raw().

Referenced by iax2_call(), and iax_firmware_append().

00684 {
00685    return iax_ie_append_raw(ied, ie, NULL, 0);
00686 }

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

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

References iax_ie_append_raw().

Referenced by iax2_start_transfer(), and update_registry().

00655 {
00656    return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in));
00657 }

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

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

00679 {
00680    return iax_ie_append_raw(ied, ie, &dat, 1);
00681 }

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

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

00660 {
00661    unsigned int newval;
00662    newval = htonl(value);
00663    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00664 }

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

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

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

Referenced by iax2_call(), 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().

00640 {
00641    char tmp[256];
00642    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00643       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);
00644       errorf(tmp);
00645       return -1;
00646    }
00647    ied->buf[ied->pos++] = ie;
00648    ied->buf[ied->pos++] = datalen;
00649    memcpy(ied->buf + ied->pos, data, datalen);
00650    ied->pos += datalen;
00651    return 0;
00652 }

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

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

00667 {
00668    unsigned short newval;
00669    newval = htons(value);
00670    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00671 }

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

Definition at line 673 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(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_transfer(), iax_provision_build(), registry_authrequest(), registry_rerequest(), socket_process(), and update_registry().

00674 {
00675    return iax_ie_append_raw(ied, ie, str, strlen(str));
00676 }

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

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

References ast_copy_string(), ast_free, ast_str_create(), ast_str_set(), ast_variable_new(), errorf, ast_variable::file, 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_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, ies, len(), ast_variable::name, ast_variable::next, outputf, str, ast_variable::value, and var.

Referenced by socket_process().

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

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

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

References errorf.

Referenced by load_module().

00694 {
00695    errorf = func;
00696 }

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

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

References outputf.

Referenced by load_module().

00689 {
00690    outputf = func;
00691 }

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

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

References 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, dir, 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 iax2_send(), raw_hangup(), send_packet(), and socket_process().

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

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]

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

int frames = 0 [static]

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

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

struct iax2_ie ies[] [static]

Referenced by authenticate_reply(), authenticate_verify(), check_access(), complete_dpreply(), complete_transfer(), dump_ies(), dundi_answer_entity(), dundi_answer_query(), dundi_ie2str(), dundi_parse_ies(), dundi_prop_precache(), handle_command_response(), iax2_ack_registry(), iax_ie2str(), iax_parse_ies(), register_verify(), registry_rerequest(), save_osptoken(), save_rr(), socket_process(), and try_transfer().

int iframes = 0 [static]

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

int oframes = 0 [static]

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

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

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

Referenced by dump_prov_ies().


Generated on Thu Jul 9 13:41:21 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7