Wed Oct 28 11:46:11 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 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 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, and name.

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 1168 of file iax2-parser.c.

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

01169 {
01170    struct iax_frames *frames = data;
01171    struct iax_frame *cur;
01172 
01173    while ((cur = AST_LIST_REMOVE_HEAD(&frames->list, list)))
01174       ast_free(cur);
01175 
01176    ast_free(frames);
01177 }

void iax_frame_free ( struct iax_frame fr  ) 

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

Referenced by iax2_frame_free(), and network_thread().

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

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

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

Referenced by iax2_send(), and iaxfrdup2().

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

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_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_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    case IAX_COMMAND_CALLTOKEN:
00524       cmd = "CTOKEN ";
00525       break;
00526    }
00527    ast_copy_string(str, cmd, len);
00528 }

void iax_frame_wrap ( struct iax_frame fr,
struct ast_frame f 
)

Definition at line 1056 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::samples, ast_frame::src, and ast_frame::subclass.

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

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

int iax_get_frames ( void   ) 

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

Referenced by handle_cli_iax2_show_stats().

01180 { return frames; }

int iax_get_iframes ( void   ) 

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

Referenced by handle_cli_iax2_show_stats().

01181 { return iframes; }

int iax_get_oframes ( void   ) 

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

Referenced by handle_cli_iax2_show_stats().

01182 { return oframes; }

const char* iax_ie2str ( int  ie  ) 

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

References ies, and iax2_ie::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 686 of file iax2-parser.c.

References iax_ie_append_raw().

Referenced by iax2_call(), and iax_firmware_append().

00687 {
00688    return iax_ie_append_raw(ied, ie, NULL, 0);
00689 }

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

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

References iax_ie_append_raw().

Referenced by iax2_start_transfer(), and update_registry().

00658 {
00659    return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in));
00660 }

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

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

00682 {
00683    return iax_ie_append_raw(ied, ie, &dat, 1);
00684 }

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

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

00663 {
00664    unsigned int newval;
00665    newval = htonl(value);
00666    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00667 }

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

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

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

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

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

00670 {
00671    unsigned short newval;
00672    newval = htons(value);
00673    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00674 }

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 701 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().

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

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

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

References errorf.

Referenced by load_module().

00697 {
00698    errorf = func;
00699 }

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

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

References outputf.

Referenced by load_module().

00692 {
00693    outputf = func;
00694 }

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

Definition at line 530 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, 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 iax2_send(), raw_hangup(), send_packet(), and socket_process().

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

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]

struct iax2_ie ies[] [static]

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

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]

struct iax2_ie prov_ies[] [static]

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


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