Tue Nov 4 13:20:38 2008

Asterisk developer's documentation


iax2-parser.h File Reference

Implementation of the IAX2 protocol. More...

#include "asterisk/linkedlists.h"

Go to the source code of this file.

Data Structures

struct  iax_frame
struct  iax_ie_data
struct  iax_ies

Defines

#define DIRECTION_INGRESS   1
#define DIRECTION_OUTGRESS   2

Functions

void iax_frame_free (struct iax_frame *fr)
iax_frameiax_frame_new (int direction, int datalen, unsigned int cacheable)
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(*output)(const char *data))
void iax_set_output (void(*output)(const char *data))
void iax_showframe (struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)


Detailed Description

Implementation of the IAX2 protocol.

Definition in file iax2-parser.h.


Define Documentation

#define DIRECTION_INGRESS   1

Definition at line 78 of file iax2-parser.h.

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

#define DIRECTION_OUTGRESS   2

Definition at line 79 of file iax2-parser.h.

Referenced by iax2_send(), iax_frame_free(), and send_trunk().


Function Documentation

void iax_frame_free ( struct iax_frame fr  ) 

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

References AST_LIST_INSERT_HEAD, iax_frame::cacheable, iax_frame::direction, DIRECTION_INGRESS, DIRECTION_OUTGRESS, errorf, and free.

Referenced by iax2_frame_free(), and network_thread().

00998 {
00999 #if !defined(LOW_MEMORY)
01000    struct iax_frames *iax_frames;
01001 #endif
01002 
01003    /* Note: does not remove from scheduler! */
01004    if (fr->direction == DIRECTION_INGRESS)
01005       ast_atomic_fetchadd_int(&iframes, -1);
01006    else if (fr->direction == DIRECTION_OUTGRESS)
01007       ast_atomic_fetchadd_int(&oframes, -1);
01008    else {
01009       errorf("Attempt to double free frame detected\n");
01010       return;
01011    }
01012    ast_atomic_fetchadd_int(&frames, -1);
01013 
01014 #if !defined(LOW_MEMORY)
01015    if (!fr->cacheable || !(iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
01016       free(fr);
01017       return;
01018    }
01019 
01020    fr->direction = 0;
01021    AST_LIST_INSERT_HEAD(iax_frames, fr, list);
01022 #else
01023    free(fr);
01024 #endif
01025 }

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

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

References iax_frame::afdatalen, ast_calloc, ast_calloc_cache, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, and DIRECTION_INGRESS.

Referenced by iax2_send(), and iaxfrdup2().

00952 {
00953    struct iax_frame *fr = NULL;
00954 
00955 #if !defined(LOW_MEMORY)
00956    struct iax_frames *iax_frames;
00957 
00958    /* Attempt to get a frame from this thread's cache */
00959    if ((iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
00960       AST_LIST_TRAVERSE_SAFE_BEGIN(iax_frames, fr, list) {
00961          if (fr->afdatalen >= datalen) {
00962             size_t afdatalen = fr->afdatalen;
00963             AST_LIST_REMOVE_CURRENT(iax_frames, list);
00964             memset(fr, 0, sizeof(*fr));
00965             fr->afdatalen = afdatalen;
00966             break;
00967          }
00968       }
00969       AST_LIST_TRAVERSE_SAFE_END
00970    }
00971    if (!fr) {
00972       if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen)))
00973          return NULL;
00974       fr->afdatalen = datalen;
00975    }
00976 #else
00977    if (!(fr = ast_calloc(1, sizeof(*fr) + datalen)))
00978       return NULL;
00979    fr->afdatalen = datalen;
00980 #endif
00981 
00982 
00983    fr->direction = direction;
00984    fr->retrans = -1;
00985    fr->cacheable = cacheable;
00986    
00987    if (fr->direction == DIRECTION_INGRESS)
00988       ast_atomic_fetchadd_int(&iframes, 1);
00989    else
00990       ast_atomic_fetchadd_int(&oframes, 1);
00991    
00992    ast_atomic_fetchadd_int(&frames, 1);
00993 
00994    return fr;
00995 }

void iax_frame_wrap ( struct iax_frame fr,
struct ast_frame f 
)

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

00921 {
00922    fr->af.frametype = f->frametype;
00923    fr->af.subclass = f->subclass;
00924    fr->af.mallocd = 0;           /* Our frame is static relative to the container */
00925    fr->af.datalen = f->datalen;
00926    fr->af.samples = f->samples;
00927    fr->af.offset = AST_FRIENDLY_OFFSET;
00928    fr->af.src = f->src;
00929    fr->af.delivery.tv_sec = 0;
00930    fr->af.delivery.tv_usec = 0;
00931    fr->af.data = fr->afdata;
00932    fr->af.len = f->len;
00933    if (fr->af.datalen) {
00934       size_t copy_len = fr->af.datalen;
00935       if (copy_len > fr->afdatalen) {
00936          ast_log(LOG_ERROR, "Losing frame data because destination buffer size '%d' bytes not big enough for '%d' bytes in the frame\n",
00937             (int) fr->afdatalen, (int) fr->af.datalen);
00938          copy_len = fr->afdatalen;
00939       }
00940 #if __BYTE_ORDER == __LITTLE_ENDIAN
00941       /* We need to byte-swap slinear samples from network byte order */
00942       if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass == AST_FORMAT_SLINEAR)) {
00943          /* 2 bytes / sample for SLINEAR */
00944          ast_swapcopy_samples(fr->af.data, f->data, copy_len / 2);
00945       } else
00946 #endif
00947          memcpy(fr->af.data, f->data, copy_len);
00948    }
00949 }

int iax_get_frames ( void   ) 

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

Referenced by iax2_show_stats().

01040 { return frames; }

int iax_get_iframes ( void   ) 

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

Referenced by iax2_show_stats().

01041 { return iframes; }

int iax_get_oframes ( void   ) 

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

Referenced by iax2_show_stats().

01042 { return oframes; }

const char* iax_ie2str ( int  ie  ) 

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

References ies, and name.

Referenced by iax_ie_append_raw(), and iax_parse_ies().

00288 {
00289    int x;
00290    for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
00291       if (ies[x].ie == ie)
00292          return ies[x].name;
00293    }
00294    return "Unknown IE";
00295 }

int iax_ie_append ( struct iax_ie_data ied,
unsigned char  ie 
)

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

References iax_ie_append_raw().

Referenced by iax2_call(), and iax_firmware_append().

00598 {
00599    return iax_ie_append_raw(ied, ie, NULL, 0);
00600 }

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

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

References iax_ie_append_raw().

Referenced by iax2_start_transfer(), and update_registry().

00569 {
00570    return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in));
00571 }

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

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

00593 {
00594    return iax_ie_append_raw(ied, ie, &dat, 1);
00595 }

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

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

00574 {
00575    unsigned int newval;
00576    newval = htonl(value);
00577    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00578 }

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

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

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

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

00554 {
00555    char tmp[256];
00556    if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
00557       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);
00558       errorf(tmp);
00559       return -1;
00560    }
00561    ied->buf[ied->pos++] = ie;
00562    ied->buf[ied->pos++] = datalen;
00563    memcpy(ied->buf + ied->pos, data, datalen);
00564    ied->pos += datalen;
00565    return 0;
00566 }

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

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

00581 {
00582    unsigned short newval;
00583    newval = htons(value);
00584    return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
00585 }

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

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

00588 {
00589    return iax_ie_append_raw(ied, ie, str, strlen(str));
00590 }

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

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

References errorf, 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_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_VERSION, IAX_RATE_8KHZ, ies, len, and outputf.

Referenced by socket_process().

00613 {
00614    /* Parse data into information elements */
00615    int len;
00616    int ie;
00617    char tmp[256];
00618    memset(ies, 0, (int)sizeof(struct iax_ies));
00619    ies->msgcount = -1;
00620    ies->firmwarever = -1;
00621    ies->calling_ton = -1;
00622    ies->calling_tns = -1;
00623    ies->calling_pres = -1;
00624    ies->samprate = IAX_RATE_8KHZ;
00625    while(datalen >= 2) {
00626       ie = data[0];
00627       len = data[1];
00628       if (len > datalen - 2) {
00629          errorf("Information element length exceeds message size\n");
00630          return -1;
00631       }
00632       switch(ie) {
00633       case IAX_IE_CALLED_NUMBER:
00634          ies->called_number = (char *)data + 2;
00635          break;
00636       case IAX_IE_CALLING_NUMBER:
00637          ies->calling_number = (char *)data + 2;
00638          break;
00639       case IAX_IE_CALLING_ANI:
00640          ies->calling_ani = (char *)data + 2;
00641          break;
00642       case IAX_IE_CALLING_NAME:
00643          ies->calling_name = (char *)data + 2;
00644          break;
00645       case IAX_IE_CALLED_CONTEXT:
00646          ies->called_context = (char *)data + 2;
00647          break;
00648       case IAX_IE_USERNAME:
00649          ies->username = (char *)data + 2;
00650          break;
00651       case IAX_IE_PASSWORD:
00652          ies->password = (char *)data + 2;
00653          break;
00654       case IAX_IE_CODEC_PREFS:
00655          ies->codec_prefs = (char *)data + 2;
00656          break;
00657       case IAX_IE_CAPABILITY:
00658          if (len != (int)sizeof(unsigned int)) {
00659             snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00660             errorf(tmp);
00661          } else
00662             ies->capability = ntohl(get_unaligned_uint32(data + 2));
00663          break;
00664       case IAX_IE_FORMAT:
00665          if (len != (int)sizeof(unsigned int)) {
00666             snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00667             errorf(tmp);
00668          } else
00669             ies->format = ntohl(get_unaligned_uint32(data + 2));
00670          break;
00671       case IAX_IE_LANGUAGE:
00672          ies->language = (char *)data + 2;
00673          break;
00674       case IAX_IE_VERSION:
00675          if (len != (int)sizeof(unsigned short)) {
00676             snprintf(tmp, (int)sizeof(tmp),  "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00677             errorf(tmp);
00678          } else
00679             ies->version = ntohs(get_unaligned_uint16(data + 2));
00680          break;
00681       case IAX_IE_ADSICPE:
00682          if (len != (int)sizeof(unsigned short)) {
00683             snprintf(tmp, (int)sizeof(tmp), "Expecting adsicpe to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00684             errorf(tmp);
00685          } else
00686             ies->adsicpe = ntohs(get_unaligned_uint16(data + 2));
00687          break;
00688       case IAX_IE_SAMPLINGRATE:
00689          if (len != (int)sizeof(unsigned short)) {
00690             snprintf(tmp, (int)sizeof(tmp), "Expecting samplingrate to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00691             errorf(tmp);
00692          } else
00693             ies->samprate = ntohs(get_unaligned_uint16(data + 2));
00694          break;
00695       case IAX_IE_DNID:
00696          ies->dnid = (char *)data + 2;
00697          break;
00698       case IAX_IE_RDNIS:
00699          ies->rdnis = (char *)data + 2;
00700          break;
00701       case IAX_IE_AUTHMETHODS:
00702          if (len != (int)sizeof(unsigned short))  {
00703             snprintf(tmp, (int)sizeof(tmp), "Expecting authmethods to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00704             errorf(tmp);
00705          } else
00706             ies->authmethods = ntohs(get_unaligned_uint16(data + 2));
00707          break;
00708       case IAX_IE_ENCRYPTION:
00709          if (len != (int)sizeof(unsigned short))  {
00710             snprintf(tmp, (int)sizeof(tmp), "Expecting encryption to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00711             errorf(tmp);
00712          } else
00713             ies->encmethods = ntohs(get_unaligned_uint16(data + 2));
00714          break;
00715       case IAX_IE_CHALLENGE:
00716          ies->challenge = (char *)data + 2;
00717          break;
00718       case IAX_IE_MD5_RESULT:
00719          ies->md5_result = (char *)data + 2;
00720          break;
00721       case IAX_IE_RSA_RESULT:
00722          ies->rsa_result = (char *)data + 2;
00723          break;
00724       case IAX_IE_APPARENT_ADDR:
00725          ies->apparent_addr = ((struct sockaddr_in *)(data + 2));
00726          break;
00727       case IAX_IE_REFRESH:
00728          if (len != (int)sizeof(unsigned short)) {
00729             snprintf(tmp, (int)sizeof(tmp),  "Expecting refresh to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00730             errorf(tmp);
00731          } else
00732             ies->refresh = ntohs(get_unaligned_uint16(data + 2));
00733          break;
00734       case IAX_IE_DPSTATUS:
00735          if (len != (int)sizeof(unsigned short)) {
00736             snprintf(tmp, (int)sizeof(tmp),  "Expecting dpstatus to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00737             errorf(tmp);
00738          } else
00739             ies->dpstatus = ntohs(get_unaligned_uint16(data + 2));
00740          break;
00741       case IAX_IE_CALLNO:
00742          if (len != (int)sizeof(unsigned short)) {
00743             snprintf(tmp, (int)sizeof(tmp),  "Expecting callno to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00744             errorf(tmp);
00745          } else
00746             ies->callno = ntohs(get_unaligned_uint16(data + 2));
00747          break;
00748       case IAX_IE_CAUSE:
00749          ies->cause = (char *)data + 2;
00750          break;
00751       case IAX_IE_CAUSECODE:
00752          if (len != 1) {
00753             snprintf(tmp, (int)sizeof(tmp), "Expecting causecode to be single byte but was %d\n", len);
00754             errorf(tmp);
00755          } else {
00756             ies->causecode = data[2];
00757          }
00758          break;
00759       case IAX_IE_IAX_UNKNOWN:
00760          if (len == 1)
00761             ies->iax_unknown = data[2];
00762          else {
00763             snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len);
00764             errorf(tmp);
00765          }
00766          break;
00767       case IAX_IE_MSGCOUNT:
00768          if (len != (int)sizeof(unsigned short)) {
00769             snprintf(tmp, (int)sizeof(tmp), "Expecting msgcount to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00770             errorf(tmp);
00771          } else
00772             ies->msgcount = ntohs(get_unaligned_uint16(data + 2));   
00773          break;
00774       case IAX_IE_AUTOANSWER:
00775          ies->autoanswer = 1;
00776          break;
00777       case IAX_IE_MUSICONHOLD:
00778          ies->musiconhold = 1;
00779          break;
00780       case IAX_IE_TRANSFERID:
00781          if (len != (int)sizeof(unsigned int)) {
00782             snprintf(tmp, (int)sizeof(tmp), "Expecting transferid to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00783             errorf(tmp);
00784          } else
00785             ies->transferid = ntohl(get_unaligned_uint32(data + 2));
00786          break;
00787       case IAX_IE_DATETIME:
00788          if (len != (int)sizeof(unsigned int)) {
00789             snprintf(tmp, (int)sizeof(tmp), "Expecting date/time to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00790             errorf(tmp);
00791          } else
00792             ies->datetime = ntohl(get_unaligned_uint32(data + 2));
00793          break;
00794       case IAX_IE_FIRMWAREVER:
00795          if (len != (int)sizeof(unsigned short)) {
00796             snprintf(tmp, (int)sizeof(tmp), "Expecting firmwarever to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00797             errorf(tmp);
00798          } else
00799             ies->firmwarever = ntohs(get_unaligned_uint16(data + 2));   
00800          break;
00801       case IAX_IE_DEVICETYPE:
00802          ies->devicetype = (char *)data + 2;
00803          break;
00804       case IAX_IE_SERVICEIDENT:
00805          ies->serviceident = (char *)data + 2;
00806          break;
00807       case IAX_IE_FWBLOCKDESC:
00808          if (len != (int)sizeof(unsigned int)) {
00809             snprintf(tmp, (int)sizeof(tmp), "Expected block desc to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00810             errorf(tmp);
00811          } else
00812             ies->fwdesc = ntohl(get_unaligned_uint32(data + 2));
00813          break;
00814       case IAX_IE_FWBLOCKDATA:
00815          ies->fwdata = data + 2;
00816          ies->fwdatalen = len;
00817          break;
00818       case IAX_IE_ENCKEY:
00819          ies->enckey = data + 2;
00820          ies->enckeylen = len;
00821          break;
00822       case IAX_IE_PROVVER:
00823          if (len != (int)sizeof(unsigned int)) {
00824             snprintf(tmp, (int)sizeof(tmp), "Expected provisioning version to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00825             errorf(tmp);
00826          } else {
00827             ies->provverpres = 1;
00828             ies->provver = ntohl(get_unaligned_uint32(data + 2));
00829          }
00830          break;
00831       case IAX_IE_CALLINGPRES:
00832          if (len == 1)
00833             ies->calling_pres = data[2];
00834          else {
00835             snprintf(tmp, (int)sizeof(tmp), "Expected single byte callingpres, but was %d long\n", len);
00836             errorf(tmp);
00837          }
00838          break;
00839       case IAX_IE_CALLINGTON:
00840          if (len == 1)
00841             ies->calling_ton = data[2];
00842          else {
00843             snprintf(tmp, (int)sizeof(tmp), "Expected single byte callington, but was %d long\n", len);
00844             errorf(tmp);
00845          }
00846          break;
00847       case IAX_IE_CALLINGTNS:
00848          if (len != (int)sizeof(unsigned short)) {
00849             snprintf(tmp, (int)sizeof(tmp), "Expecting callingtns to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00850             errorf(tmp);
00851          } else
00852             ies->calling_tns = ntohs(get_unaligned_uint16(data + 2));   
00853          break;
00854                case IAX_IE_RR_JITTER:
00855                        if (len != (int)sizeof(unsigned int)) {
00856                                snprintf(tmp, (int)sizeof(tmp), "Expected jitter rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00857                                errorf(tmp);
00858                        } else {
00859                                ies->rr_jitter = ntohl(get_unaligned_uint32(data + 2));
00860                        }
00861                        break;
00862                case IAX_IE_RR_LOSS:
00863                        if (len != (int)sizeof(unsigned int)) {
00864                                snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00865                                errorf(tmp);
00866                        } else {
00867                                ies->rr_loss = ntohl(get_unaligned_uint32(data + 2));
00868                        }
00869                        break;
00870                case IAX_IE_RR_PKTS:
00871                        if (len != (int)sizeof(unsigned int)) {
00872                                snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00873                                errorf(tmp);
00874                        } else {
00875                                ies->rr_pkts = ntohl(get_unaligned_uint32(data + 2));
00876                        }
00877                        break;
00878                case IAX_IE_RR_DELAY:
00879                        if (len != (int)sizeof(unsigned short)) {
00880                                snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
00881                         errorf(tmp);
00882                        } else {
00883                                ies->rr_delay = ntohs(get_unaligned_uint16(data + 2));
00884                        }
00885                        break;
00886       case IAX_IE_RR_DROPPED:
00887          if (len != (int)sizeof(unsigned int)) {
00888             snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00889             errorf(tmp);
00890          } else {
00891             ies->rr_dropped = ntohl(get_unaligned_uint32(data + 2));
00892          }
00893          break;
00894       case IAX_IE_RR_OOO:
00895          if (len != (int)sizeof(unsigned int)) {
00896             snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
00897             errorf(tmp);
00898          } else {
00899             ies->rr_ooo = ntohl(get_unaligned_uint32(data + 2));
00900          }
00901          break;
00902       default:
00903          snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len);
00904          outputf(tmp);
00905       }
00906       /* Overwrite information element with 0, to null terminate previous portion */
00907       data[0] = 0;
00908       datalen -= (len + 2);
00909       data += (len + 2);
00910    }
00911    /* Null-terminate last field */
00912    *data = '\0';
00913    if (datalen) {
00914       errorf("Invalid information element contents, strange boundary\n");
00915       return -1;
00916    }
00917    return 0;
00918 }

void iax_set_error ( void(*)(const char *data)  output  ) 

void iax_set_output ( void(*)(const char *data)  output  ) 

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

Definition at line 396 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, dump_ies(), f, IAX_FLAG_FULL, IAX_FLAG_RETRANS, iaxs, 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().

00397 {
00398    const char *frames[] = {
00399       "(0?)",
00400       "DTMF_E ",
00401       "VOICE  ",
00402       "VIDEO  ",
00403       "CONTROL",
00404       "NULL   ",
00405       "IAX    ",
00406       "TEXT   ",
00407       "IMAGE  ",
00408       "HTML   ",
00409       "CNG    ",
00410       "MODEM  ",
00411       "DTMF_B ",
00412    };
00413    const char *iaxs[] = {
00414       "(0?)",
00415       "NEW    ",
00416       "PING   ",
00417       "PONG   ",
00418       "ACK    ",
00419       "HANGUP ",
00420       "REJECT ",
00421       "ACCEPT ",
00422       "AUTHREQ",
00423       "AUTHREP",
00424       "INVAL  ",
00425       "LAGRQ  ",
00426       "LAGRP  ",
00427       "REGREQ ",
00428       "REGAUTH",
00429       "REGACK ",
00430       "REGREJ ",
00431       "REGREL ",
00432       "VNAK   ",
00433       "DPREQ  ",
00434       "DPREP  ",
00435       "DIAL   ",
00436       "TXREQ  ",
00437       "TXCNT  ",
00438       "TXACC  ",
00439       "TXREADY",
00440       "TXREL  ",
00441       "TXREJ  ",
00442       "QUELCH ",
00443       "UNQULCH",
00444       "POKE   ",
00445       "PAGE   ",
00446       "MWI    ",
00447       "UNSPRTD",
00448       "TRANSFR",
00449       "PROVISN",
00450       "FWDWNLD",
00451       "FWDATA ",
00452       "TXMEDIA"
00453    };
00454    const char *cmds[] = {
00455       "(0?)",
00456       "HANGUP ",
00457       "RING   ",
00458       "RINGING",
00459       "ANSWER ",
00460       "BUSY   ",
00461       "TKOFFHK",
00462       "OFFHOOK",
00463       "CONGSTN",
00464       "FLASH  ",
00465       "WINK   ",
00466       "OPTION ",
00467       "RDKEY  ",
00468       "RDUNKEY",
00469       "PROGRES",
00470       "PROCDNG",
00471       "HOLD   ",
00472       "UNHOLD ",
00473       "VIDUPDT", };
00474    struct ast_iax2_full_hdr *fh;
00475    char retries[20];
00476    char class2[20];
00477    char subclass2[20];
00478    const char *class;
00479    const char *subclass;
00480    char *dir;
00481    char tmp[512];
00482 
00483    switch(rx) {
00484    case 0:
00485       dir = "Tx";
00486       break;
00487    case 2:
00488       dir = "TE";
00489       break;
00490    case 3:
00491       dir = "RD";
00492       break;
00493    default:
00494       dir = "Rx";
00495       break;
00496    }
00497    if (f) {
00498       fh = f->data;
00499       snprintf(retries, sizeof(retries), "%03d", f->retries);
00500    } else {
00501       fh = fhi;
00502       if (ntohs(fh->dcallno) & IAX_FLAG_RETRANS)
00503          strcpy(retries, "Yes");
00504       else
00505          strcpy(retries, " No");
00506    }
00507    if (!(ntohs(fh->scallno) & IAX_FLAG_FULL)) {
00508       /* Don't mess with mini-frames */
00509       return;
00510    }
00511    if (fh->type >= (int)sizeof(frames)/(int)sizeof(frames[0])) {
00512       snprintf(class2, sizeof(class2), "(%d?)", fh->type);
00513       class = class2;
00514    } else {
00515       class = frames[(int)fh->type];
00516    }
00517    if (fh->type == AST_FRAME_DTMF_BEGIN || fh->type == AST_FRAME_DTMF_END) {
00518       sprintf(subclass2, "%c", fh->csub);
00519       subclass = subclass2;
00520    } else if (fh->type == AST_FRAME_IAX) {
00521       if (fh->csub >= (int)sizeof(iaxs)/(int)sizeof(iaxs[0])) {
00522          snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub);
00523          subclass = subclass2;
00524       } else {
00525          subclass = iaxs[(int)fh->csub];
00526       }
00527    } else if (fh->type == AST_FRAME_CONTROL) {
00528       if (fh->csub >= (int)sizeof(cmds)/(int)sizeof(cmds[0])) {
00529          snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub);
00530          subclass = subclass2;
00531       } else {
00532          subclass = cmds[(int)fh->csub];
00533       }
00534    } else {
00535       snprintf(subclass2, sizeof(subclass2), "%d", fh->csub);
00536       subclass = subclass2;
00537    }
00538    snprintf(tmp, sizeof(tmp), 
00539        "%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s Subclass: %s\n",
00540        dir,
00541        retries, fh->oseqno, fh->iseqno, class, subclass);
00542    outputf(tmp);
00543    snprintf(tmp, sizeof(tmp), 
00544        "   Timestamp: %05lums  SCall: %5.5d  DCall: %5.5d [%s:%d]\n",
00545        (unsigned long)ntohl(fh->ts),
00546        ntohs(fh->scallno) & ~IAX_FLAG_FULL, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS,
00547        ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
00548    outputf(tmp);
00549    if (fh->type == AST_FRAME_IAX)
00550       dump_ies(fh->iedata, datalen);
00551 }


Generated on Tue Nov 4 13:20:38 2008 for Asterisk - the Open Source PBX by  doxygen 1.4.7