Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:34 2007

Asterisk developer's documentation :: Codename Pineapple


iax2-parser.h File Reference


Detailed Description

Implementation of the IAX2 protocol.

Definition in file iax2-parser.h.

#include "asterisk/linkedlists.h"

Include dependency graph for iax2-parser.h:

This graph shows which files directly or indirectly include this file:

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)


Define Documentation

#define DIRECTION_INGRESS   1
 

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

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

#define DIRECTION_OUTGRESS   2
 

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

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

Referenced by iax2_frame_free(), and network_thread().

01021 {
01022 #if !defined(LOW_MEMORY)
01023    struct iax_frames *iax_frames;
01024 #endif
01025 
01026    /* Note: does not remove from scheduler! */
01027    if (fr->direction == DIRECTION_INGRESS)
01028       ast_atomic_fetchadd_int(&iframes, -1);
01029    else if (fr->direction == DIRECTION_OUTGRESS)
01030       ast_atomic_fetchadd_int(&oframes, -1);
01031    else {
01032       errorf("Attempt to double free frame detected\n");
01033       return;
01034    }
01035    ast_atomic_fetchadd_int(&frames, -1);
01036 
01037 #if !defined(LOW_MEMORY)
01038    if (!fr->cacheable || !(iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
01039       free(fr);
01040       return;
01041    }
01042 
01043    fr->direction = 0;
01044    AST_LIST_INSERT_HEAD(iax_frames, fr, list);
01045 #else
01046    free(fr);
01047 #endif
01048 }

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

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

References ast_calloc, ast_calloc_cache, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, DIRECTION_INGRESS, frames, iframes, iax_frame::mallocd_datalen, and oframes.

Referenced by iax2_send(), and iaxfrdup2().

00975 {
00976    struct iax_frame *fr = NULL;
00977 
00978 #if !defined(LOW_MEMORY)
00979    struct iax_frames *iax_frames;
00980 
00981    /* Attempt to get a frame from this thread's cache */
00982    if ((iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
00983       AST_LIST_TRAVERSE_SAFE_BEGIN(iax_frames, fr, list) {
00984          if (fr->mallocd_datalen >= datalen) {
00985             size_t mallocd_datalen = fr->mallocd_datalen;
00986             AST_LIST_REMOVE_CURRENT(iax_frames, list);
00987             memset(fr, 0, sizeof(*fr));
00988             fr->mallocd_datalen = mallocd_datalen;
00989             break;
00990          }
00991       }
00992       AST_LIST_TRAVERSE_SAFE_END
00993    }
00994    if (!fr) {
00995       if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen)))
00996          return NULL;
00997       fr->mallocd_datalen = datalen;
00998    }
00999 #else
01000    if (!(fr = ast_calloc(1, sizeof(*fr) + datalen)))
01001       return NULL;
01002    fr->mallocd_datalen = datalen;
01003 #endif
01004 
01005 
01006    fr->direction = direction;
01007    fr->retrans = -1;
01008    fr->cacheable = cacheable;
01009    
01010    if (fr->direction == DIRECTION_INGRESS)
01011       ast_atomic_fetchadd_int(&iframes, 1);
01012    else
01013       ast_atomic_fetchadd_int(&oframes, 1);
01014    
01015    ast_atomic_fetchadd_int(&frames, 1);
01016 
01017    return fr;
01018 }

void iax_frame_wrap struct iax_frame fr,
struct ast_frame f
 

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

References iax_frame::af, iax_frame::afdata, AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_swapcopy_samples(), ast_frame::data, ast_frame::datalen, ast_frame::delivery, ast_frame::frametype, 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().

00952 {
00953    fr->af.frametype = f->frametype;
00954    fr->af.subclass = f->subclass;
00955    fr->af.mallocd = 0;           /* Our frame is static relative to the container */
00956    fr->af.datalen = f->datalen;
00957    fr->af.samples = f->samples;
00958    fr->af.offset = AST_FRIENDLY_OFFSET;
00959    fr->af.src = f->src;
00960    fr->af.delivery.tv_sec = 0;
00961    fr->af.delivery.tv_usec = 0;
00962    fr->af.data = fr->afdata;
00963    if (fr->af.datalen) {
00964 #if __BYTE_ORDER == __LITTLE_ENDIAN
00965       /* We need to byte-swap slinear samples from network byte order */
00966       if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass == AST_FORMAT_SLINEAR)) {
00967          ast_swapcopy_samples(fr->af.data, f->data, fr->af.samples);
00968       } else
00969 #endif
00970       memcpy(fr->af.data, f->data, fr->af.datalen);
00971    }
00972 }

int iax_get_frames void   ) 
 

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

References frames.

Referenced by iax2_show_stats().

01063 { return frames; }

int iax_get_iframes void   ) 
 

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

References iframes.

Referenced by iax2_show_stats().

01064 { return iframes; }

int iax_get_oframes void   ) 
 

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

References oframes.

Referenced by iax2_show_stats().

01065 { return oframes; }

const char* iax_ie2str int  ie  ) 
 

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

References ies, and name.

Referenced by iax_ie_append_raw(), and iax_parse_ies().

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

int iax_ie_append struct iax_ie_data ied,
unsigned char  ie
 

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

References iax_ie_append_raw().

Referenced by iax2_call(), and iax_firmware_append().

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

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

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

References iax_ie_append_raw().

Referenced by iax2_start_transfer(), and update_registry().

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

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

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

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

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

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

References iax_ie_append_raw().

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

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

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

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

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

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

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

References iax_ie_append_raw().

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

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

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

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

References iax_ie_append_raw().

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

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

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

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

References ast_variable_new(), errorf, free, 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_VARIABLE, IAX_IE_VERSION, IAX_RATE_8KHZ, ies, len, ast_variable::name, ast_variable::next, outputf, ast_variable::value, and var.

Referenced by socket_process().

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

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 398 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, dump_ies(), frames, IAX_FLAG_FULL, IAX_FLAG_RETRANS, iaxs, 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().

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


Asterisk is a trademark for Digium, inc.. | Edvina.net | Asterisk.org | This documentation was generated with Doxygen